@@ -43,32 +43,64 @@ export class LuaTranspiler {
4343 return indent + this . transpileExpression ( < ts . Expression > tsEx . getChildren ( node ) [ 0 ] ) + "\n" ;
4444 case ts . SyntaxKind . ReturnStatement :
4545 return indent + this . transpileReturn ( < ts . ReturnStatement > node ) + "\n" ;
46+ case ts . SyntaxKind . IfStatement :
47+ return this . transpileIf ( < ts . IfStatement > node , indent ) ;
48+ case ts . SyntaxKind . WhileStatement :
49+ return this . transpileWhile ( < ts . WhileStatement > node , indent ) ;
4650 case ts . SyntaxKind . ForStatement :
4751 return this . transpileFor ( < ts . ForStatement > node , indent ) ;
4852 case ts . SyntaxKind . ForOfStatement :
4953 return this . transpileForOf ( < ts . ForOfStatement > node , indent ) ;
5054 case ts . SyntaxKind . ForInStatement :
5155 return this . transpileForIn ( < ts . ForInStatement > node , indent ) ;
56+ case ts . SyntaxKind . BreakStatement :
57+ return indent + "break\n" ;
58+ case ts . SyntaxKind . ContinueKeyword :
59+ // Disallow continue
60+ throw new TranspileError ( "Continue is not supported in Lua" , node ) ;
5261 case ts . SyntaxKind . EndOfFileToken :
5362 return "" ;
5463 default :
5564 throw new TranspileError ( "Unsupported node kind: " + tsEx . enumName ( node . kind , ts . SyntaxKind ) , node ) ;
5665 }
5766 }
5867
59- static transpileFor ( node : ts . ForStatement , indent : string ) : string {
68+ static transpileIf ( node : ts . IfStatement , indent : string ) : string {
69+ const condition = this . transpileExpression ( node . expression ) ;
70+
71+ let result = indent + `if ${ condition } then\n` ;
72+ result += this . transpileBlock ( node . thenStatement , indent + " " ) ;
73+
74+ if ( node . elseStatement ) {
75+ result += indent + "else\n" ;
76+ result += this . transpileBlock ( node . elseStatement , indent + " " ) ;
77+ }
6078
61- // Get identifier
62- const identifier = tsEx . getFirstChildOfType < ts . Identifier > ( tsEx . getChildren ( node . initializer ) [ 0 ] , ts . isIdentifier ) ;
79+ return result + indent + "end\n" ;
80+ }
6381
82+ static transpileWhile ( node : ts . WhileStatement , indent : string ) : string {
83+ const condition = this . transpileExpression ( node . expression ) ;
84+
85+ let result = indent + `while ${ condition } do\n` ;
86+ result += this . transpileBlock ( node . statement , indent + " " ) ;
87+ return result + indent + "end\n" ;
88+ }
89+
90+ static transpileFor ( node : ts . ForStatement , indent : string ) : string {
91+ // Goal: Populate three for components:
6492 let start = "0" ;
6593 let end = "0" ;
6694 let step = "1" ;
6795
96+ // Get variable
97+ const variable = ( < ts . VariableDeclarationList > node . initializer ) . declarations [ 0 ] ;
98+ const identifier = < ts . Identifier > variable . name ;
99+
68100 // Get initial value
69- const varDec = tsEx . getFirstChildOfType < ts . VariableDeclaration > ( node . initializer , ts . isVariableDeclaration ) ;
70- start = this . transpileExpression ( tsEx . getChildren ( varDec ) [ 1 ] ) ;
101+ start = this . transpileExpression ( variable . initializer ) ;
71102
103+ // Get ending value
72104 if ( ts . isBinaryExpression ( node . condition ) ) {
73105 if ( ts . isIdentifier ( node . condition . left ) ) {
74106 // Account for lua 1 indexing
@@ -153,7 +185,7 @@ export class LuaTranspiler {
153185
154186 static transpileForOf ( node : ts . ForOfStatement , indent : string ) : string {
155187 // Get variable identifier
156- const variable = < ts . VariableDeclaration > ( < ts . VariableDeclarationList > node . initializer ) . declarations [ 0 ] ;
188+ const variable = ( < ts . VariableDeclarationList > node . initializer ) . declarations [ 0 ] ;
157189 const identifier = < ts . Identifier > variable . name ;
158190
159191 // Transpile expression
@@ -197,6 +229,8 @@ export class LuaTranspiler {
197229 return this . transpileCallExpression ( < ts . CallExpression > node ) ;
198230 case ts . SyntaxKind . PropertyAccessExpression :
199231 return this . transpilePropertyAccessExpression ( < ts . PropertyAccessExpression > node ) ;
232+ case ts . SyntaxKind . ElementAccessExpression :
233+ return this . transpileElementAccessExpression ( < ts . ElementAccessExpression > node ) ;
200234 case ts . SyntaxKind . Identifier :
201235 // For identifiers simply return their name
202236 return ( < ts . Identifier > node ) . text ;
@@ -214,11 +248,11 @@ export class LuaTranspiler {
214248 case ts . SyntaxKind . PrefixUnaryExpression :
215249 return this . transpilePrefixUnaryExpression ( < ts . PrefixUnaryExpression > node ) ;
216250 case ts . SyntaxKind . ArrayLiteralExpression :
217- return this . transpileArrayLiteral ( node ) ;
251+ return this . transpileArrayLiteral ( < ts . ArrayLiteralExpression > node ) ;
218252 case ts . SyntaxKind . ObjectLiteralExpression :
219- return this . transpileObjectLiteral ( node ) ;
253+ return this . transpileObjectLiteral ( < ts . ObjectLiteralExpression > node ) ;
220254 case ts . SyntaxKind . FunctionExpression :
221- return this . transpileFunctionExpression ( node ) ;
255+ return this . transpileFunctionExpression ( < ts . FunctionExpression > node ) ;
222256 default :
223257 throw new TranspileError ( "Unsupported expression kind: " + tsEx . enumName ( node . kind , ts . SyntaxKind ) , node ) ;
224258 }
@@ -287,16 +321,14 @@ export class LuaTranspiler {
287321 }
288322
289323 static transpileCallExpression ( node : ts . CallExpression ) : string {
290- const children = tsEx . getChildren ( node ) ;
291-
292- let callPath = this . transpileExpression ( children [ 0 ] ) ;
324+ let callPath = this . transpileExpression ( node . expression ) ;
293325 // Remove last . with :
294326 if ( callPath . indexOf ( "." ) > - 1 ) {
295327 callPath = callPath . substr ( 0 , callPath . lastIndexOf ( "." ) ) + ":" + callPath . substr ( callPath . lastIndexOf ( "." ) + 1 ) ;
296328 }
297329
298330 const parameters = [ ] ;
299- children . slice ( 1 ) . forEach ( param => {
331+ node . arguments . forEach ( param => {
300332 parameters . push ( this . transpileExpression ( param ) ) ;
301333 } )
302334
@@ -326,12 +358,18 @@ export class LuaTranspiler {
326358 return parts . join ( "." ) ;
327359 }
328360
361+ static transpileElementAccessExpression ( node : ts . ElementAccessExpression ) : string {
362+ const element = this . transpileExpression ( node . expression ) ;
363+ const index = this . transpileExpression ( node . argumentExpression ) ;
364+
365+ return `${ element } [${ index } ]` ;
366+ }
367+
329368 // Transpile a variable statement
330369 static transpileVariableStatement ( node : ts . VariableStatement ) : string {
331370 let result = "" ;
332371
333- let list = tsEx . getFirstChildOfType < ts . VariableDeclarationList > ( node , ts . isVariableDeclarationList ) ;
334- list . declarations . forEach ( declaration => {
372+ node . declarationList . declarations . forEach ( declaration => {
335373 result += this . transpileVariableDeclaration ( < ts . VariableDeclaration > declaration ) ;
336374 } ) ;
337375
@@ -340,10 +378,8 @@ export class LuaTranspiler {
340378
341379 static transpileVariableDeclaration ( node : ts . VariableDeclaration ) : string {
342380 // Find variable identifier
343- const identifier = tsEx . getFirstChildOfType < ts . Identifier > ( node , ts . isIdentifier ) ;
344- const valueLiteral = tsEx . getChildren ( node ) [ 1 ] ;
345-
346- const value = this . transpileExpression ( valueLiteral ) ;
381+ const identifier = < ts . Identifier > node . name ;
382+ const value = this . transpileExpression ( node . initializer ) ;
347383
348384 return `local ${ identifier . escapedText } = ${ value } ` ;
349385 }
@@ -358,7 +394,7 @@ export class LuaTranspiler {
358394 // Build parameter string
359395 let paramNames = [ ] ;
360396 parameters . forEach ( param => {
361- paramNames . push ( tsEx . getFirstChildOfType < ts . Identifier > ( param , ts . isIdentifier ) . escapedText ) ;
397+ paramNames . push ( ( < ts . Identifier > param . name ) . escapedText ) ;
362398 } ) ;
363399
364400 // Build function header
@@ -374,12 +410,8 @@ export class LuaTranspiler {
374410
375411 // Transpile a class declaration
376412 static transpileClass ( node : ts . ClassDeclaration , indent : string ) : string {
377-
378- // Find first identifier
379- const identifierNode = tsEx . getFirstChildOfType < ts . Identifier > ( node , child => ts . isIdentifier ( child ) ) ;
380-
381413 // Write class declaration
382- const className = < string > identifierNode . escapedText ;
414+ const className = < string > node . name . escapedText ;
383415 let result = indent + `${ className } = ${ className } or {}\n` ;
384416
385417 // Get all properties
@@ -396,8 +428,8 @@ export class LuaTranspiler {
396428 // Find value assignment
397429 const assignments = tsEx . getChildrenOfType ( p , tsEx . isValueType ) ;
398430
399- // [0] is name literal, [1] is value, ignore fields with no assigned value
400- if ( assignments . length < 2 )
431+ // Ignore fields with no assigned value
432+ if ( ! p . initializer )
401433 continue ;
402434
403435 if ( isStatic ) {
@@ -449,38 +481,34 @@ export class LuaTranspiler {
449481 // Add in instance field declarations
450482 for ( const f of instanceFields ) {
451483 // Get identifier
452- const fieldIdentifier = tsEx . getFirstChildOfType < ts . Identifier > ( f , ts . isIdentifier ) ;
484+ const fieldIdentifier = < ts . Identifier > f . name ;
453485 const fieldName = fieldIdentifier . escapedText ;
454486
455- // Get value at index 1 (index 0 is field name)
456- const valueNode = tsEx . getChildrenOfType < ts . Node > ( f , tsEx . isValueType ) [ 1 ] ;
457- let value = this . transpileExpression ( valueNode ) ;
487+ let value = this . transpileExpression ( f . initializer ) ;
458488
459489 result += indent + ` self.${ fieldName } = ${ value } \n` ;
460490 }
461491
462492 // Transpile constructor body
463- tsEx . getChildrenOfType < ts . Block > ( node , ts . isBlock ) . forEach ( child => {
464- result += this . transpileBlock ( child , indent + " " ) ;
465- } ) ;
493+ result += this . transpileBlock ( node . body , indent + " " ) ;
466494
467495 return result + `${ indent } end\n` ;
468496 }
469497
470- static transpileArrayLiteral ( node : ts . Node ) : string {
498+ static transpileArrayLiteral ( node : ts . ArrayLiteralExpression ) : string {
471499 let values = [ ] ;
472500
473- node . forEachChild ( child => {
501+ node . elements . forEach ( child => {
474502 values . push ( this . transpileExpression ( child ) ) ;
475503 } ) ;
476504
477505 return "{" + values . join ( "," ) + "}" ;
478506 }
479507
480- static transpileObjectLiteral ( node : ts . Node ) : string {
508+ static transpileObjectLiteral ( node : ts . ObjectLiteralExpression ) : string {
481509 let properties = [ ] ;
482510 // Add all property assignments
483- tsEx . getChildrenOfType < ts . PropertyAssignment > ( node , ts . isPropertyAssignment ) . forEach ( assignment => {
511+ node . properties . forEach ( assignment => {
484512 const [ key , value ] = tsEx . getChildren ( assignment ) ;
485513 if ( ts . isIdentifier ( key ) ) {
486514 properties . push ( `["${ key . escapedText } "]=` + this . transpileExpression ( value ) ) ;
@@ -493,16 +521,13 @@ export class LuaTranspiler {
493521 return "{" + properties . join ( "," ) + "}" ;
494522 }
495523
496- static transpileFunctionExpression ( node : ts . Node ) : string {
497- let params = tsEx . getChildrenOfType < ts . ParameterDeclaration > ( node , ts . isParameter ) ;
524+ static transpileFunctionExpression ( node : ts . FunctionExpression ) : string {
498525 // Build parameter string
499526 let paramNames = [ ] ;
500- params . forEach ( param => {
527+ node . parameters . forEach ( param => {
501528 paramNames . push ( tsEx . getFirstChildOfType < ts . Identifier > ( param , ts . isIdentifier ) . escapedText ) ;
502529 } ) ;
503530
504- let block = tsEx . getFirstChildOfType < ts . Block > ( node , ts . isBlock ) ;
505-
506- return `function(${ paramNames . join ( "," ) } )\n` + this . transpileBlock ( block , " " ) + " end\n" ;
531+ return `function(${ paramNames . join ( "," ) } )\n` + this . transpileBlock ( node . body , " " ) + " end\n" ;
507532 }
508533}
0 commit comments