summaryrefslogtreecommitdiff
path: root/vm.c
diff options
context:
space:
mode:
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/vm.c b/vm.c
index 3410e1c..4e412c1 100644
--- a/vm.c
+++ b/vm.c
@@ -41,12 +41,13 @@ int runvm(State *S) {
#define PEEK() (th->stack[th->sp-1])
while (1) {
+ ch = th->ch;
+ if (S->do_trace) {
+ printf("%p ",(void *)ch);
+ disasm_instr(ch, th->ip);
+ }
uint8_t instr = RBYTE();
switch (instr) {
- case OP_RET:
- status = 0;
- goto done;
- break;
case OP_LOADK: {
uint8_t cix = RBYTE();
Val v = ch->consts.d[cix];
@@ -155,7 +156,39 @@ int runvm(State *S) {
case OP_TRUE: PUSH(VAL_TRUE); break;
case OP_FALSE: PUSH(VAL_FALSE); break;
+ case OP_CALL: {
+ uint8_t len = RBYTE();
+ // ignore arguments for now
+ th->sp -= len-1;
+ Val callee = POP();
+ if (!IS_FUNC(callee)) {
+ fprintf(stderr, "can only call functions\n");
+ goto done;
+ }
+ ObjFunc *func = AS_FUNC(callee);
+
+ StackFrame *sf = &th->rstack[th->rsp++];
+ sf->ch = th->ch;
+ sf->ip = th->ip;
+
+ th->ch = &func->ch;
+ th->ip = 0;
}
+ break;
+
+ case OP_RET: {
+ StackFrame *sf = &th->rstack[--th->rsp];
+ th->ch = sf->ch;
+ th->ip = sf->ip;
+ break;
+ }
+ case OP_HALT:
+ status = 0;
+ goto done;
+ break;
+
+ }
+
}
done:;
return status;