@@ -135,7 +135,7 @@ export class Compiler {
135
135
private nextRegister : number ; // next free register
136
136
private numVars : number ; // number of active variables
137
137
private scopeStack : Scope [ ] ;
138
- private currentScope : Scope | null ;
138
+ private currentScope : Scope | undefined ;
139
139
140
140
/* Constructor */
141
141
constructor ( ast : ASTNode . Program ) {
@@ -144,7 +144,7 @@ export class Compiler {
144
144
this . nextRegister = - 1 ;
145
145
this . numVars = 0 ;
146
146
this . scopeStack = [ ] ;
147
- this . currentScope = null ;
147
+ this . currentScope = undefined ;
148
148
}
149
149
150
150
/* Stack Management */
@@ -206,7 +206,8 @@ export class Compiler {
206
206
}
207
207
208
208
this . scopeStack . pop ( ) ;
209
- this . currentScope = this . scopeStack [ this . scopeStack . length - 1 ] ?? null ;
209
+ this . currentScope =
210
+ this . scopeStack [ this . scopeStack . length - 1 ] ?? undefined ;
210
211
}
211
212
212
213
// Runs at the end of compilation to ensure that
@@ -286,6 +287,39 @@ export class Compiler {
286
287
) : void {
287
288
this . compileConstantNode ( node , targetRegister ) ;
288
289
}
290
+ private compileVariableNode (
291
+ node : ASTNode . VariableNode ,
292
+ targetRegister : number ,
293
+ ) : void {
294
+ const variableName = node . name ;
295
+
296
+ let currentScope = this . currentScope ;
297
+ while ( currentScope ) {
298
+ if ( currentScope . locals [ variableName ] !== undefined ) {
299
+ const variableRegister = currentScope . locals [ variableName ] ;
300
+ this . emit (
301
+ new IRInstruction ( Opcodes . MOVE , [
302
+ new IROperand ( "Register" , targetRegister ) ,
303
+ new IROperand ( "Register" , variableRegister ) ,
304
+ ] ) ,
305
+ ) ;
306
+ return ;
307
+ }
308
+
309
+ currentScope = this . scopeStack [ this . scopeStack . indexOf ( currentScope ) - 1 ] ;
310
+ }
311
+
312
+ // Variable not found in any scope, assume global
313
+ const constantIndex = this . emitConstant (
314
+ new LuaConstant ( LuaConstantType . LUA_TSTRING , variableName ) ,
315
+ ) ;
316
+ this . emit (
317
+ new IRInstruction ( Opcodes . GETGLOBAL , [
318
+ new IROperand ( "Register" , targetRegister ) ,
319
+ new IROperand ( "Constant" , constantIndex ) ,
320
+ ] ) ,
321
+ ) ;
322
+ }
289
323
290
324
/* Statement Compilation */
291
325
private compileDoStatement ( node : ASTNode . DoStatement ) : void {
@@ -333,6 +367,9 @@ export class Compiler {
333
367
targetRegister ,
334
368
) ;
335
369
break ;
370
+ case ASTNode . NodeType . VARIABLE :
371
+ this . compileVariableNode ( node as ASTNode . VariableNode , targetRegister ) ;
372
+ break ;
336
373
default :
337
374
throw new Error ( `Unsupported expression node type: ${ node . type } ` ) ;
338
375
}
0 commit comments