@@ -44,7 +44,7 @@ void freeVM(VM *pvm) {
4444}
4545
4646// Runtime Error Helper
47- static void runtimeError (VM * pvm , const char * format , ...) {
47+ void runtimeError (VM * pvm , const char * format , ...) {
4848 char message [1024 ];
4949 va_list args ;
5050 va_start (args , format );
@@ -108,145 +108,6 @@ static void concatenate(VM* pvm) {
108108}
109109
110110
111- void closeUpvalues (VM * vm , Value * last ) {
112- while (vm -> openUpvalues != NULL &&
113- vm -> openUpvalues -> location >= last ) {
114- ObjUpvalue * upvalue = vm -> openUpvalues ;
115- upvalue -> closed = * upvalue -> location ;
116- upvalue -> location = & upvalue -> closed ;
117- vm -> openUpvalues = upvalue -> next ;
118- }
119- }
120-
121- ObjUpvalue * captureUpvalue (Value * local , VM * vm ) {
122- ObjUpvalue * prevUpvalue = NULL ;
123- ObjUpvalue * upvalue = vm -> openUpvalues ;
124- while (upvalue != NULL && upvalue -> location > local ) {
125- prevUpvalue = upvalue ;
126- upvalue = upvalue -> next ;
127- }
128-
129- if (upvalue != NULL && upvalue -> location == local ) {
130- return upvalue ;
131- }
132-
133- ObjUpvalue * createdUpvalue = newUpvalue (local );
134- createdUpvalue -> next = upvalue ;
135-
136- if (prevUpvalue == NULL ) {
137- vm -> openUpvalues = createdUpvalue ;
138- } else {
139- prevUpvalue -> next = createdUpvalue ;
140- }
141-
142- return createdUpvalue ;
143- }
144-
145- void defineMethod (ObjString * name , VM * vm ) {
146- Value method = peek (vm , 0 );
147- ObjClass * klass = AS_CLASS (peek (vm , 1 ));
148- tableSet (& klass -> methods , name , method );
149- pop (vm );
150- }
151-
152- bool bindMethod (struct ObjClass * klass , ObjString * name , VM * vm ) {
153- Value method ;
154- if (!tableGet (& klass -> methods , name , & method )) {
155- runtimeError (vm , "Undefined property '%s'." , name -> chars );
156- return false;
157- }
158-
159- ObjBoundMethod * bound = newBoundMethod (peek (vm , 0 ), AS_CLOSURE (method ));
160- pop (vm );
161- push (vm , OBJ_VAL (bound ));
162- return true;
163- }
164-
165- bool call (ObjClosure * closure , int argCount , VM * vm ) {
166- if (argCount != closure -> function -> arity ) {
167- runtimeError (vm , "Expected %d arguments but got %d." ,
168- closure -> function -> arity , argCount );
169- return false;
170- }
171-
172- if (vm -> frameCount == 64 ) {
173- runtimeError (vm , "Stack overflow." );
174- return false;
175- }
176-
177- CallFrame * frame = & vm -> frames [vm -> frameCount ++ ];
178- frame -> closure = closure ;
179- frame -> ip = closure -> function -> chunk .code ;
180- frame -> slots = vm -> stackTop - argCount - 1 ;
181- return true;
182- }
183-
184- bool callValue (Value callee , int argCount , VM * vm ) {
185- if (IS_OBJ (callee )) {
186- switch (OBJ_TYPE (callee )) {
187- case OBJ_BOUND_METHOD : {
188- ObjBoundMethod * bound = AS_BOUND_METHOD (callee );
189- vm -> stackTop [- argCount - 1 ] = bound -> receiver ;
190- return call (bound -> method , argCount , vm );
191- }
192- case OBJ_CLASS : {
193- ObjClass * klass = AS_CLASS (callee );
194- vm -> stackTop [- argCount - 1 ] = OBJ_VAL (newInstance (klass ));
195- Value initializer ;
196- if (tableGet (& klass -> methods , copyString ("init" , 4 ), & initializer )) {
197- return call (AS_CLOSURE (initializer ), argCount , vm );
198- } else if (argCount != 0 ) {
199- runtimeError (vm , "Expected 0 arguments but got %d." , argCount );
200- return false;
201- }
202- return true;
203- }
204- case OBJ_CLOSURE :
205- return call (AS_CLOSURE (callee ), argCount , vm );
206- case OBJ_NATIVE : {
207- NativeFn native = AS_NATIVE (callee );
208- Value result = native (argCount , vm -> stackTop - argCount );
209- vm -> stackTop -= argCount + 1 ;
210- push (vm , result );
211- return true;
212- }
213- default :
214- break ; // Non-callable object type
215- }
216- }
217- runtimeError (vm , "Can only call functions and classes." );
218- return false;
219- }
220-
221- bool invokeFromClass (struct ObjClass * klass , ObjString * name ,
222- int argCount , VM * vm ) {
223- Value method ;
224- if (!tableGet (& klass -> methods , name , & method )) {
225- runtimeError (vm , "Undefined property '%s'." , name -> chars );
226- return false;
227- }
228- return call (AS_CLOSURE (method ), argCount , vm );
229- }
230-
231- bool invoke (ObjString * name , int argCount , VM * vm ) {
232- Value receiver = peek (vm , argCount );
233-
234- if (!IS_INSTANCE (receiver )) {
235- runtimeError (vm , "Only instances have methods." );
236- return false;
237- }
238-
239- struct ObjInstance * instance = AS_INSTANCE (receiver );
240-
241- Value value ;
242- if (tableGet (& instance -> fields , name , & value )) {
243- vm -> stackTop [- argCount - 1 ] = value ;
244- return callValue (value , argCount , vm );
245- }
246-
247- return invokeFromClass (instance -> klass , name , argCount , vm );
248- }
249-
250111static InterpretResult run (VM * vm ) {
251112
252113 CallFrame * frame = & vm -> frames [vm -> frameCount - 1 ];
0 commit comments