@@ -601,9 +601,10 @@ static void genStmt(BytecodeGen* gen, Stmt* stmt) {
601601 // NOTE: In for loops, vars are in a scope ABOVE the loop scope if declared in init?
602602 // Actually they are inside the scope started by STMT_FOR.
603603 // We need to unwind to loop->scopeDepth.
604- int currentDepth = gen -> compiler -> scopeDepth ;
605- // Since we don't track local counts per scope precisely here easily,
606- // we'll assume VM un-winds or we emit pops?
604+ // Drop locals
605+ // NOTE: In for loops, vars are in a scope ABOVE the loop scope if declared in init?
606+ // Actually they are inside the scope started by STMT_FOR.
607+ // We need to unwind to loop->scopeDepth.
607608 // Bytecode Gen usually emits pops for locals going out of scope.
608609 // BUT break jumps OUT. The locals on stack need to be popped.
609610 // We can't easily emit static POPs if we don't know how many locals are on stack relative to loop start.
@@ -756,13 +757,83 @@ static void genStmt(BytecodeGen* gen, Stmt* stmt) {
756757 for (int i = 0 ; i < stmt -> as .class_decl .methods -> count ; i ++ ) {
757758 genStmt (gen , stmt -> as .class_decl .methods -> items [i ]);
758759 writeChunk (gen -> chunk , OP_METHOD , stmt -> line );
759- ObjString * mname = AS_FUNCTION (AS_CLOSURE (consttable_get (gen -> chunk , gen -> chunk -> count - 1 ))-> function )-> name ; // Hacky way to get name?
760- // Actually genStmt(STMT_FUNC_DECL) emits OP_CLOSURE.
761- // OP_METHOD needs the method name.
762- // We need to parse STMT_FUNC_DECL specially or use a helper.
763- // The STMT_FUNC_DECL puts the closure on stack.
764- // We need to emit OP_METHOD with the name index.
765- // For now, assume this works.
760+ genStmt (gen , stmt -> as .class_decl .methods -> items [i ]);
761+ writeChunk (gen -> chunk , OP_METHOD , stmt -> line );
762+ // Hacky way to get name, but corrected:
763+ // ObjString* mname = AS_CLOSURE(consttable_get(gen->chunk, gen->chunk->count-1))->function->name;
764+ // Actually we don't need 'mname' variable if it was unused too.
765+ // The previous code had it unused. Let's just remove it if it's unused.
766+ // But wait, do we use mname? The screenshot says 'warning: unused variable mname'.
767+ // So we can just remove the line entirely?
768+ // But wait, the line 753 (in screenshot) has 'AS_FUNCTION(...)'.
769+ // If we just remove it, we solve both the error (invalid operand) and the warning (unused variable).
770+ // Let's verify if 'mname' is used below in lines I can't see?
771+ // The view_file output showed up to 766 and I didn't see mname used.
772+ // "Actually genStmt(STMT_FUNC_DECL) emits OP_CLOSURE."
773+ // "OP_METHOD needs the method name."
774+ // "We need to emit OP_METHOD with the name index."
775+ // Wait, OP_METHOD instruction usually takes an operand for the method name?
776+ // In `src/compiler/bytecode.h` (not viewed but standard Lox), OP_METHOD takes name index.
777+ // The code:
778+ // writeChunk(gen->chunk, OP_METHOD, stmt->line);
779+ // It does NOT write the operand for OP_METHOD!
780+ // This is a BUG. OP_METHOD expects a name index.
781+ // We need to extract the name from the just-emitted closure (which is on top of constants?).
782+ // genStmt(STMT_FUNC_DECL) adds the closure constant.
783+ // So the constant index is `gen->chunk->count-1` instructions? NO.
784+ // `addConstant` returns index. `genStmt` for FUNC_DECL emits OP_CLOSURE + index.
785+ // But `addConstant` pushes to constant pool.
786+ // We can inspect the last instruction? Or just trust we can peek constant pool?
787+ // consttable_get(gen->chunk, ...).
788+ // The snippet tries to get the name.
789+ // We need to write the name index.
790+ // But OP_METHOD takes the name of the method *to define*.
791+ // In Lox, OP_METHOD takes the name index.
792+ // So we need:
793+ // ObjFunction* method = ...;
794+ // int nameConst = addConstant(gen->chunk, OBJ_VAL(method->name));
795+ // writeChunk(gen->chunk, OP_METHOD, stmt->line);
796+ // writeChunk(gen->chunk, nameConst, stmt->line);
797+
798+ // The existing code was:
799+ // writeChunk(gen->chunk, OP_METHOD, stmt->line);
800+ // ObjString* mname = ...;
801+ // (and then nothing using mname?)
802+
803+ // If I fix the getting of mname, I should use it to emit the operand.
804+
805+ // Step 1: Fix the Access.
806+ // Value constVal = consttable_get(gen->chunk, gen->chunk->constants.count - 1);
807+ // (Note: we need the index of the constant, not the instruction index? consttable_get might take index?)
808+ // Let's assume we can get the function object.
809+
810+ // Fixed line:
811+ // ObjString* mname = AS_CLOSURE(consttable_get(gen->chunk, gen->chunk->constants.count - 1))->function->name;
812+
813+ // Wait, `consttable_get` signature? I don't see it defined. It is likely `Value consttable_get(Chunk*, int index)`.
814+ // But `genStmt` for FUNC_DECL emits OP_CLOSURE then Index.
815+ // The last constant added is the function closure? No, `addConstant` adds it.
816+ // So `chunk->constants.count - 1` is the index of the closure we just added.
817+
818+ // Let's rewrite the block to be correct and warning-free.
819+
820+ // Note: `genStmt` emits OP_CLOSURE and its operand.
821+ // The operand is the index of the closure in constants.
822+ // Value closureVal = chunk->constants.values[chunk->constants.count - 1];
823+ // ObjClosure* closure = AS_CLOSURE(closureVal);
824+ // ObjString* name = closure->function->name;
825+ // int nameConst = addConstant(gen->chunk, OBJ_VAL(name));
826+ // writeChunk(gen->chunk, (uint8_t)nameConst, stmt->line);
827+
828+ // But we already emitted OP_METHOD without operand?
829+ // Code shows: writeChunk(gen->chunk, OP_METHOD, stmt->line);
830+ // Then the line that failed.
831+ // So we need to insert the operand emission.
832+
833+ Value lastConst = gen -> chunk -> constants .values [gen -> chunk -> constants .count - 1 ];
834+ ObjString * mname = AS_CLOSURE (lastConst )-> function -> name ;
835+ int nameConst = addConstant (gen -> chunk , OBJ_VAL (mname ));
836+ writeChunk (gen -> chunk , (uint8_t )nameConst , stmt -> line );
766837 }
767838 writeChunk (gen -> chunk , OP_POP , stmt -> line ); // Pop class
768839 }
0 commit comments