Skip to content

Commit 091d440

Browse files
committed
feat(compiler): add support for compiling variable nodes
1 parent a657ae9 commit 091d440

File tree

1 file changed

+40
-3
lines changed

1 file changed

+40
-3
lines changed

src/compiler/compiler.ts

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ export class Compiler {
135135
private nextRegister: number; // next free register
136136
private numVars: number; // number of active variables
137137
private scopeStack: Scope[];
138-
private currentScope: Scope | null;
138+
private currentScope: Scope | undefined;
139139

140140
/* Constructor */
141141
constructor(ast: ASTNode.Program) {
@@ -144,7 +144,7 @@ export class Compiler {
144144
this.nextRegister = -1;
145145
this.numVars = 0;
146146
this.scopeStack = [];
147-
this.currentScope = null;
147+
this.currentScope = undefined;
148148
}
149149

150150
/* Stack Management */
@@ -206,7 +206,8 @@ export class Compiler {
206206
}
207207

208208
this.scopeStack.pop();
209-
this.currentScope = this.scopeStack[this.scopeStack.length - 1] ?? null;
209+
this.currentScope =
210+
this.scopeStack[this.scopeStack.length - 1] ?? undefined;
210211
}
211212

212213
// Runs at the end of compilation to ensure that
@@ -286,6 +287,39 @@ export class Compiler {
286287
): void {
287288
this.compileConstantNode(node, targetRegister);
288289
}
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+
}
289323

290324
/* Statement Compilation */
291325
private compileDoStatement(node: ASTNode.DoStatement): void {
@@ -333,6 +367,9 @@ export class Compiler {
333367
targetRegister,
334368
);
335369
break;
370+
case ASTNode.NodeType.VARIABLE:
371+
this.compileVariableNode(node as ASTNode.VariableNode, targetRegister);
372+
break;
336373
default:
337374
throw new Error(`Unsupported expression node type: ${node.type}`);
338375
}

0 commit comments

Comments
 (0)