Skip to content

Commit 0265eb8

Browse files
committed
feat: Implement the core virtual machine for bytecode execution and runtime error handling.
1 parent 55eb5fd commit 0265eb8

1 file changed

Lines changed: 60 additions & 29 deletions

File tree

src/runtime/vm.c

Lines changed: 60 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -350,20 +350,33 @@ static InterpretResult run(VM *vm) {
350350
DISPATCH();
351351
}
352352
DO_OP_GET_PROPERTY: {
353-
if (!IS_INSTANCE(peek(vm, 0))) {
354-
runtimeError(vm, "Only instances have properties.");
355-
return INTERPRET_RUNTIME_ERROR;
356-
}
357-
struct ObjInstance* instance = AS_INSTANCE(peek(vm, 0));
353+
Value target = peek(vm, 0);
358354
ObjString* name = READ_STRING();
359-
Value value;
360-
if (tableGet(&instance->fields, name, &value)) {
361-
pop(vm); // Instance
362-
push(vm, value);
363-
DISPATCH();
364-
}
365-
if (!bindMethod(instance->klass, name, vm)) {
366-
return INTERPRET_RUNTIME_ERROR;
355+
356+
if (IS_INSTANCE(target)) {
357+
struct ObjInstance* instance = AS_INSTANCE(target);
358+
Value value;
359+
if (tableGet(&instance->fields, name, &value)) {
360+
pop(vm); // Instance
361+
push(vm, value);
362+
DISPATCH();
363+
}
364+
if (!bindMethod(instance->klass, name, vm)) {
365+
return INTERPRET_RUNTIME_ERROR;
366+
}
367+
} else if (IS_MODULE(target)) {
368+
ObjModule* module = AS_MODULE(target);
369+
Value value;
370+
if (tableGet(&module->exports, name, &value)) {
371+
pop(vm); // Module
372+
push(vm, value);
373+
DISPATCH();
374+
}
375+
runtimeError(vm, "Undefined property '%s' in module '%s'.", name->chars, module->name->chars);
376+
return INTERPRET_RUNTIME_ERROR;
377+
} else {
378+
runtimeError(vm, "Only instances and modules have properties.");
379+
return INTERPRET_RUNTIME_ERROR;
367380
}
368381
DISPATCH();
369382
}
@@ -741,21 +754,33 @@ static InterpretResult run(VM *vm) {
741754
break;
742755
}
743756
case OP_GET_PROPERTY: {
744-
if (!IS_INSTANCE(peek(vm, 0))) {
745-
runtimeError(vm, "Only instances have properties.");
746-
return INTERPRET_RUNTIME_ERROR;
747-
}
748-
ObjInstance* instance = AS_INSTANCE(peek(vm, 0));
757+
Value target = peek(vm, 0);
749758
ObjString* name = READ_STRING();
750-
Value value;
751-
if (tableGet(&instance->fields, name, &value)) {
752-
pop(vm); // Instance
753-
push(vm, value);
754-
break;
755-
}
756-
// Bind method
757-
if (!bindMethod(instance->klass, name, vm)) {
758-
return INTERPRET_RUNTIME_ERROR;
759+
760+
if (IS_INSTANCE(target)) {
761+
ObjInstance* instance = AS_INSTANCE(target);
762+
Value value;
763+
if (tableGet(&instance->fields, name, &value)) {
764+
pop(vm); // Instance
765+
push(vm, value);
766+
break;
767+
}
768+
if (!bindMethod(instance->klass, name, vm)) {
769+
return INTERPRET_RUNTIME_ERROR;
770+
}
771+
} else if (IS_MODULE(target)) {
772+
ObjModule* module = AS_MODULE(target);
773+
Value value;
774+
if (tableGet(&module->exports, name, &value)) {
775+
pop(vm); // Module
776+
push(vm, value);
777+
break;
778+
}
779+
runtimeError(vm, "Undefined property '%s' in module '%s'.", name->chars, module->name->chars);
780+
return INTERPRET_RUNTIME_ERROR;
781+
} else {
782+
runtimeError(vm, "Only instances and modules have properties.");
783+
return INTERPRET_RUNTIME_ERROR;
759784
}
760785
break;
761786
}
@@ -962,8 +987,14 @@ static InterpretResult run(VM *vm) {
962987
}
963988
case OP_USE: {
964989
ObjString* name = READ_STRING();
965-
runtimeError(vm, "Modules not yet implemented runtime-side.");
966-
return INTERPRET_RUNTIME_ERROR;
990+
Value moduleVal;
991+
if (tableGet(&vm->importer.modules, name, &moduleVal)) {
992+
// Module found.
993+
} else {
994+
runtimeError(vm, "Could not find module '%s'.", name->chars);
995+
return INTERPRET_RUNTIME_ERROR;
996+
}
997+
break;
967998
}
968999
case OP_TRY:
9691000
case OP_CATCH:

0 commit comments

Comments
 (0)