Skip to content

Commit 69379a2

Browse files
committed
feat: Implement initial bytecode generation for expressions, statements, and function declarations.
1 parent 6b948a0 commit 69379a2

1 file changed

Lines changed: 102 additions & 95 deletions

File tree

src/compiler/bytecode_gen.c

Lines changed: 102 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "../../include/common.h"
88
#include "../../include/value.h"
99
#include "../../include/object.h"
10+
#include <stddef.h>
1011

1112
// --- Compiler & Scope Types ---
1213

@@ -62,7 +63,7 @@ static void initCompiler(BytecodeGen* gen, Compiler* compiler, CompFunctionType
6263

6364
static ObjFunction* endCompiler(BytecodeGen* gen) {
6465
// Emit return
65-
writeChunk(gen->chunk, OP_NIL, 0); // TODO: Line info
66+
writeChunk(gen->chunk, OP_NIL, 0);
6667
writeChunk(gen->chunk, OP_RETURN, 0);
6768

6869
ObjFunction* function = gen->compiler->function;
@@ -112,22 +113,17 @@ static void addLocal(BytecodeGen* gen, const char* name) {
112113
local->depth = gen->compiler->scopeDepth; // Assuming initialized immediately
113114
}
114115

115-
// remove static declaration of addConstant, use header implementation implicitly linked
116-
117116
static void emitConstant(BytecodeGen* gen, Value value, int line) {
118117
int constant = addConstant(gen->chunk, value);
119118
if (constant > 255) {
120-
writeChunk(gen->chunk, OP_CONSTANT, line); // Handle appropriately if we had OP_CONSTANT_LONG
119+
writeChunk(gen->chunk, OP_CONSTANT, line);
121120
fprintf(stderr, "Too many constants.\n");
122121
} else {
123122
writeChunk(gen->chunk, OP_CONSTANT, line);
124123
writeChunk(gen->chunk, (uint8_t)constant, line);
125124
}
126125
}
127126

128-
// ... (Rest of BytecodeGen is fine until generateBytecode/STMT_FUNC_DECL) ...
129-
// NOTE: Must ensure STMT_FUNC_DECL uses COMP_FUNCTION
130-
131127
static void genExpr(BytecodeGen* gen, Expr* expr) {
132128
if (expr == NULL) return;
133129

@@ -227,7 +223,6 @@ static void genStmt(BytecodeGen* gen, Stmt* stmt) {
227223
if (stmt == NULL) return;
228224

229225
switch (stmt->type) {
230-
// ...
231226
case STMT_FUNC_DECL: {
232227
// New Compiler for Function
233228
Compiler funcCompiler;
@@ -272,91 +267,101 @@ static void genStmt(BytecodeGen* gen, Stmt* stmt) {
272267
}
273268
break;
274269
}
275-
// ... (Rest default)
276-
default:
277-
if(stmt->type == STMT_BLOCK) { // Handle other cases similarly if overridden
278-
beginScope(gen);
270+
case STMT_BLOCK: {
271+
beginScope(gen);
272+
if (stmt->as.block.statements) {
279273
for (int i=0; i < stmt->as.block.statements->count; i++) {
280274
genStmt(gen, stmt->as.block.statements->items[i]);
281275
}
282-
endScope(gen);
283-
} else if (stmt->type == STMT_VAR_DECL) {
284-
if (stmt->as.var_decl.initializer) {
285-
genExpr(gen, stmt->as.var_decl.initializer);
286-
} else {
287-
writeChunk(gen->chunk, OP_NIL, stmt->line);
288-
}
289-
290-
if (gen->compiler->scopeDepth > 0) {
291-
addLocal(gen, stmt->as.var_decl.name);
292-
} else {
293-
Value nameVal = OBJ_VAL(copyString(stmt->as.var_decl.name, strlen(stmt->as.var_decl.name)));
294-
int nameConst = addConstant(gen->chunk, nameVal);
295-
writeChunk(gen->chunk, OP_DEFINE_GLOBAL, stmt->line);
296-
writeChunk(gen->chunk, (uint8_t)nameConst, stmt->line);
297-
}
298-
} else if (stmt->type == STMT_EXPRESSION) {
299-
genExpr(gen, stmt->as.expression.expression);
300-
writeChunk(gen->chunk, OP_POP, stmt->line);
301-
} else if (stmt->type == STMT_PRINT) {
302-
genExpr(gen, stmt->as.print.expression);
303-
writeChunk(gen->chunk, OP_PRINT, stmt->line);
304-
} else if (stmt->type == STMT_RETURN) {
305-
if (stmt->as.return_stmt.value) {
306-
genExpr(gen, stmt->as.return_stmt.value);
307-
} else {
308-
writeChunk(gen->chunk, OP_NIL, stmt->line);
309-
}
310-
writeChunk(gen->chunk, OP_RETURN, stmt->line);
311-
} else if (stmt->type == STMT_IF) {
312-
genExpr(gen, stmt->as.if_stmt.condition);
313-
writeChunk(gen->chunk, OP_JUMP_IF_FALSE, stmt->line);
314-
writeChunk(gen->chunk, 0xff, 0); writeChunk(gen->chunk, 0xff, 0);
315-
int thenJump = gen->chunk->count - 2;
316-
writeChunk(gen->chunk, OP_POP, stmt->line);
317-
318-
genStmt(gen, stmt->as.if_stmt.then_branch);
319-
320-
writeChunk(gen->chunk, OP_JUMP, 0);
321-
writeChunk(gen->chunk, 0xff, 0); writeChunk(gen->chunk, 0xff, 0);
322-
int elseJump = gen->chunk->count - 2;
323-
324-
int patchThen = gen->chunk->count - thenJump - 2;
325-
gen->chunk->code[thenJump] = (patchThen >> 8) & 0xff;
326-
gen->chunk->code[thenJump+1] = patchThen & 0xff;
327-
328-
writeChunk(gen->chunk, OP_POP, stmt->line);
329-
if (stmt->as.if_stmt.else_branch) genStmt(gen, stmt->as.if_stmt.else_branch);
330-
331-
int patchElse = gen->chunk->count - elseJump - 2;
332-
gen->chunk->code[elseJump] = (patchElse >> 8) & 0xff;
333-
gen->chunk->code[elseJump+1] = patchElse & 0xff;
334-
} else if (stmt->type == STMT_WHILE) {
335-
int loopStart = gen->chunk->count;
336-
genExpr(gen, stmt->as.while_stmt.condition);
337-
338-
writeChunk(gen->chunk, OP_JUMP_IF_FALSE, stmt->line);
339-
writeChunk(gen->chunk, 0xff, 0); writeChunk(gen->chunk, 0xff, 0);
340-
int exitJump = gen->chunk->count - 2;
341-
writeChunk(gen->chunk, OP_POP, stmt->line);
342-
343-
genStmt(gen, stmt->as.while_stmt.body);
344-
345-
writeChunk(gen->chunk, OP_LOOP, stmt->line);
346-
int offset = gen->chunk->count - loopStart + 2;
347-
writeChunk(gen->chunk, (offset >> 8) & 0xff, 0);
348-
writeChunk(gen->chunk, offset & 0xff, 0);
349-
350-
int patchExit = gen->chunk->count - exitJump - 2;
351-
gen->chunk->code[exitJump] = (patchExit >> 8) & 0xff;
352-
gen->chunk->code[exitJump+1] = patchExit & 0xff;
353-
354-
writeChunk(gen->chunk, OP_POP, stmt->line);
355-
}
356-
else {
357-
// fall back for other types if any
358-
}
359-
break;
276+
}
277+
endScope(gen);
278+
break;
279+
}
280+
case STMT_VAR_DECL: {
281+
if (stmt->as.var_decl.initializer) {
282+
genExpr(gen, stmt->as.var_decl.initializer);
283+
} else {
284+
writeChunk(gen->chunk, OP_NIL, stmt->line);
285+
}
286+
287+
if (gen->compiler->scopeDepth > 0) {
288+
addLocal(gen, stmt->as.var_decl.name);
289+
} else {
290+
Value nameVal = OBJ_VAL(copyString(stmt->as.var_decl.name, strlen(stmt->as.var_decl.name)));
291+
int nameConst = addConstant(gen->chunk, nameVal);
292+
writeChunk(gen->chunk, OP_DEFINE_GLOBAL, stmt->line);
293+
writeChunk(gen->chunk, (uint8_t)nameConst, stmt->line);
294+
}
295+
break;
296+
}
297+
case STMT_EXPRESSION: {
298+
genExpr(gen, stmt->as.expression.expression);
299+
writeChunk(gen->chunk, OP_POP, stmt->line);
300+
break;
301+
}
302+
case STMT_PRINT: {
303+
genExpr(gen, stmt->as.print.expression);
304+
writeChunk(gen->chunk, OP_PRINT, stmt->line);
305+
break;
306+
}
307+
case STMT_RETURN: {
308+
if (stmt->as.return_stmt.value) {
309+
genExpr(gen, stmt->as.return_stmt.value);
310+
} else {
311+
writeChunk(gen->chunk, OP_NIL, stmt->line);
312+
}
313+
writeChunk(gen->chunk, OP_RETURN, stmt->line);
314+
break;
315+
}
316+
case STMT_IF: {
317+
genExpr(gen, stmt->as.if_stmt.condition);
318+
writeChunk(gen->chunk, OP_JUMP_IF_FALSE, stmt->line);
319+
writeChunk(gen->chunk, 0xff, 0); writeChunk(gen->chunk, 0xff, 0);
320+
int thenJump = gen->chunk->count - 2;
321+
writeChunk(gen->chunk, OP_POP, stmt->line);
322+
323+
genStmt(gen, stmt->as.if_stmt.then_branch);
324+
325+
writeChunk(gen->chunk, OP_JUMP, 0);
326+
writeChunk(gen->chunk, 0xff, 0); writeChunk(gen->chunk, 0xff, 0);
327+
int elseJump = gen->chunk->count - 2;
328+
329+
int patchThen = gen->chunk->count - thenJump - 2;
330+
gen->chunk->code[thenJump] = (patchThen >> 8) & 0xff;
331+
gen->chunk->code[thenJump+1] = patchThen & 0xff;
332+
333+
writeChunk(gen->chunk, OP_POP, stmt->line);
334+
if (stmt->as.if_stmt.else_branch) genStmt(gen, stmt->as.if_stmt.else_branch);
335+
336+
int patchElse = gen->chunk->count - elseJump - 2;
337+
gen->chunk->code[elseJump] = (patchElse >> 8) & 0xff;
338+
gen->chunk->code[elseJump+1] = patchElse & 0xff;
339+
break;
340+
}
341+
case STMT_WHILE: {
342+
int loopStart = gen->chunk->count;
343+
genExpr(gen, stmt->as.while_stmt.condition);
344+
345+
writeChunk(gen->chunk, OP_JUMP_IF_FALSE, stmt->line);
346+
writeChunk(gen->chunk, 0xff, 0); writeChunk(gen->chunk, 0xff, 0);
347+
int exitJump = gen->chunk->count - 2;
348+
writeChunk(gen->chunk, OP_POP, stmt->line);
349+
350+
genStmt(gen, stmt->as.while_stmt.body);
351+
352+
writeChunk(gen->chunk, OP_LOOP, stmt->line);
353+
int offset = gen->chunk->count - loopStart + 2;
354+
writeChunk(gen->chunk, (offset >> 8) & 0xff, 0);
355+
writeChunk(gen->chunk, offset & 0xff, 0);
356+
357+
int patchExit = gen->chunk->count - exitJump - 2;
358+
gen->chunk->code[exitJump] = (patchExit >> 8) & 0xff;
359+
gen->chunk->code[exitJump+1] = patchExit & 0xff;
360+
361+
writeChunk(gen->chunk, OP_POP, stmt->line);
362+
break;
363+
}
364+
default: break;
360365
}
361366
}
362367

@@ -371,17 +376,19 @@ void generateBytecode(StmtList* statements, Chunk* chunk) {
371376
compiler.function = newFunction();
372377
compiler.function->chunk = *chunk;
373378

374-
compiler.type = COMP_SCRIPT; // Use new enum value
379+
compiler.type = COMP_SCRIPT;
375380
compiler.localCount = 0;
376381
compiler.scopeDepth = 0;
377382

378383
compiler.locals[compiler.localCount++].depth = 0;
379384
compiler.locals[0].name = "";
380385

381-
for (int i = 0; i < statements->count; i++) {
382-
genStmt(&gen, statements->items[i]);
386+
if (statements) {
387+
for (int i = 0; i < statements->count; i++) {
388+
genStmt(&gen, statements->items[i]);
389+
}
383390
}
384391

385-
writeChunk(gen.chunk, OP_NIL, 0); // Fix: gen.chunk instead of gen->chunk
386-
writeChunk(gen.chunk, OP_RETURN, 0); // Fix: gen.chunk instead of gen->chunk
392+
writeChunk(gen.chunk, OP_NIL, 0);
393+
writeChunk(gen.chunk, OP_RETURN, 0);
387394
}

0 commit comments

Comments
 (0)