summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vm.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/vm.c b/vm.c
index 9a69472..a5ffbc6 100644
--- a/vm.c
+++ b/vm.c
@@ -36,17 +36,19 @@ int runvm(State *S) {
#define RBYTE() (ch->bc.d[th->ip++])
#define RSHORT() (th->ip += 2, (uint16_t)( ch->bc.d[th->ip-2] | ch->bc.d[th->ip-1] << 8 ))
-#define PUSH(v) th->stack[th->fp + th->sp++] = v;
-#define POP() (th->stack[th->fp + --th->sp])
-#define PEEK() (th->stack[th->fp + th->sp-1])
+#define PUSH(v) th->stack[th->sp++] = v;
+#define POP() (th->stack[--th->sp])
+#define PEEK() (th->stack[th->sp-1])
+// 1 is TOS
+#define PEEKN(n) (th->stack[th->sp-n])
while (1) {
ch = th->ch;
if (S->do_trace) {
- printf("\t[%lu + %lu] : ",th->fp, th->sp);
- for (int i = 0; i < th->sp; i++) {
+ printf("\t[%lu -> %lu] : ",th->fp, th->sp);
+ for (int i = th->fp; i < th->sp; i++) {
printf("(%d) ",i);
- print_val(th->stack[th->fp + i]);
+ print_val(th->stack[i]);
printf(" ; ");
}
printf("\n%p ",(void *)ch);
@@ -178,25 +180,25 @@ int runvm(State *S) {
case OP_FALSE: PUSH(VAL_FALSE); break;
case OP_CALL: {
+ // nargs + 1 = function and args
uint8_t len = RBYTE();
- th->sp -= len-1;
- Val callee = POP();
+ Val callee = PEEKN(len);
if (!IS_FUNC(callee)) {
- fprintf(stderr, "can only call functions\n");
- goto done;
+ fprintf(stderr,"can only call functions");
+ exit(1);
}
ObjFunc *func = AS_FUNC(callee);
StackFrame *sf = &th->rstack[th->rsp++];
- sf->ch = th->ch;
sf->ip = th->ip;
+ sf->ch = th->ch;
sf->fp = th->fp;
- th->ch = &func->ch;
th->ip = 0;
- th->fp = th->sp;
- th->sp = len;
+ th->ch = &func->ch;
+ th->fp = th->sp - len;
+
break;
}
@@ -210,11 +212,10 @@ int runvm(State *S) {
case OP_RET: {
StackFrame *sf = &th->rstack[--th->rsp];
- size_t orig_fp = th->fp;
- th->ch = sf->ch;
+
th->ip = sf->ip;
+ th->ch = sf->ch;
th->fp = sf->fp;
- th->sp += (orig_fp - th->fp);
break;
}
case OP_HALT: