@@ -33,7 +33,7 @@ static void runtime_error(const char* format, ...)
3333 for (int i = vm .frame_count - 1 ; i >= 0 ; i -- )
3434 {
3535 CallFrame * frame = & vm .frames [i ];
36- ObjFunction * function = frame -> function ;
36+ ObjFunction * function = frame -> closure -> function ;
3737 size_t instruction = frame -> ip - function -> chunk .code - 1 ;
3838
3939 fprintf (stderr , "[line %d] in " , function -> chunk .lines [instruction ]);
@@ -89,12 +89,12 @@ static Value peek(int distance)
8989 return vm .stack_top [-1 - distance ];
9090}
9191
92- static bool call (ObjFunction * function , int arg_count )
92+ static bool call (ObjClosure * closure , int arg_count )
9393{
94- if (function -> arity != arg_count )
94+ if (arg_count != closure -> function -> arity )
9595 {
96- runtime_error ("Expected %d arguments but got %d." , function -> arity ,
97- arg_count );
96+ runtime_error ("Expected %d arguments but got %d." ,
97+ closure -> function -> arity , arg_count );
9898 }
9999 if (vm .frame_count == FRAMES_MAX )
100100 {
@@ -104,8 +104,8 @@ static bool call(ObjFunction* function, int arg_count)
104104 return false;
105105 }
106106 CallFrame * frame = & vm .frames [vm .frame_count ++ ];
107- frame -> function = function ;
108- frame -> ip = function -> chunk .code ;
107+ frame -> closure = closure ;
108+ frame -> ip = closure -> function -> chunk .code ;
109109 frame -> slots = vm .stack_top - arg_count - 1 ;
110110 return true;
111111}
@@ -116,10 +116,8 @@ static bool call_value(Value callee, int arg_count)
116116 {
117117 switch (OBJ_TYPE (callee ))
118118 {
119- case OBJ_FUNCTION :
120- {
121- return call (AS_FUNCTION (callee ), arg_count );
122- }
119+ case OBJ_CLOSURE :
120+ return call (AS_CLOSURE (callee ), arg_count );
123121 case OBJ_NATIVE :
124122 {
125123 NativeFn native = AS_NATIVE (callee );
@@ -164,7 +162,8 @@ static InterpretResult run()
164162
165163#define READ_BYTE () (*frame->ip++)
166164#define READ_SHORT () (frame->ip += 2, (u16)(frame->ip[-2] << 8) | frame->ip[-1])
167- #define READ_CONSTANT () (frame->function->chunk.constants.values[READ_BYTE()])
165+ #define READ_CONSTANT () \
166+ (frame->closure->function->chunk.constants.values[READ_BYTE()])
168167#define READ_STRING () AS_STRING(READ_CONSTANT())
169168#define BINARY_OP (value_type , op ) \
170169 do \
@@ -190,8 +189,9 @@ static InterpretResult run()
190189 printf (" ]" );
191190 }
192191 printf ("\n" );
193- disassemble_instruction (& frame -> function -> chunk ,
194- (int )(frame -> ip - frame -> function -> chunk .code ));
192+ disassemble_instruction (
193+ & frame -> closure -> function -> chunk ,
194+ (int )(frame -> ip - frame -> closure -> function -> chunk .code ));
195195#endif
196196 u8 instruction ;
197197 switch (instruction = READ_BYTE ())
@@ -342,6 +342,13 @@ static InterpretResult run()
342342 frame = & vm .frames [vm .frame_count - 1 ];
343343 break ;
344344 }
345+ case OP_CLOSURE :
346+ {
347+ ObjFunction * function = AS_FUNCTION (READ_CONSTANT ());
348+ ObjClosure * closure = new_closure (function );
349+ push (OBJ_VAL (closure ));
350+ break ;
351+ }
345352 case OP_RETURN :
346353 {
347354 Value result = pop ();
@@ -375,11 +382,10 @@ InterpretResult interpret(char* source)
375382 return INTERPRET_COMPILE_ERROR ;
376383
377384 push (OBJ_VAL (function ));
378- call_value (OBJ_VAL (function ), 0 );
379- CallFrame * frame = & vm .frames [vm .frame_count ++ ];
380- frame -> function = function ;
381- frame -> ip = function -> chunk .code ;
382- frame -> slots = vm .stack ;
385+ ObjClosure * closure = new_closure (function );
386+ pop ();
387+ push (OBJ_VAL (closure ));
388+ call_value (OBJ_VAL (closure ), 0 );
383389
384390 return run ();
385391}
0 commit comments