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
6364static 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-
117116static 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-
131127static 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