diff options
Diffstat (limited to 'vm.c')
-rw-r--r-- | vm.c | 51 |
1 files changed, 40 insertions, 11 deletions
@@ -6,6 +6,7 @@ #include "val.h" #include "vm.h" +#include "dis.h" void *M(void *p, size_t sz) { if (sz == 0) { @@ -61,22 +62,26 @@ Vm vm_new(Chunk *ch) { static void runvm() { Chunk ch = chunk_new(); + chunk_wbc(&ch, OP_LOADK); - chunk_wbc(&ch, 1); - chunk_wbc(&ch, OP_PRINT); - chunk_wbc(&ch, OP_LOADK); - chunk_wbc(&ch, 2); + chunk_wbc(&ch, chunk_wconst(&ch, VAL_NUM(10.0))); chunk_wbc(&ch, OP_LOADK); - chunk_wbc(&ch, 0); + chunk_wbc(&ch, chunk_wconst(&ch, VAL_NUM(3.0))); + chunk_wbc(&ch, OP_DIV); + chunk_wbc(&ch, OP_PRINT); + chunk_wbc(&ch, OP_RET); - chunk_wconst(&ch, VAL_BOOL(false)); - chunk_wconst(&ch, VAL_NIL); - chunk_wconst(&ch, VAL_NUM(420.69)); + + disasm_chunk(&ch); Vm vm = vm_new(&ch); #define RBYTE() (vm.ch->b[vm.ip++]) +#define PUSH(v) vm.stack[vm.sp++] = v; +#define POP() (vm.stack[--vm.sp]) + + puts("---"); while (1) { uint8_t instr = RBYTE(); switch (instr) { @@ -84,14 +89,38 @@ static void runvm() { printf("done!\n"); goto done; break; - case OP_LOADK: + case OP_LOADK:; uint8_t cix = RBYTE(); Val v = vm.ch->c[cix]; - print_val(v); + PUSH(v); + // printf(" (pushing "); + // print_val(v); + // printf(")\n"); break; case OP_PRINT: - printf("print\n"); + println_val(POP()); + break; + +#define ARITH_OP(opcode, OP) \ + case opcode: { \ + Val b = POP(); \ + Val a = POP(); \ + if (!IS_NUM(a) || !IS_NUM(b)) { \ + printf("can't do arithmetic on %s and %s\n", \ + valty_str(a.ty), valty_str(b.ty)); \ + goto done; \ + } \ + PUSH(VAL_NUM(AS_NUM(a) OP AS_NUM(b))); \ + } \ break; + + ARITH_OP(OP_ADD, +) + ARITH_OP(OP_SUB, -) + ARITH_OP(OP_MUL, *) + ARITH_OP(OP_DIV, /) +#undef ARITH_OP + + } } done:; |