diff options
-rw-r--r-- | dis.c | 36 | ||||
-rw-r--r-- | dis.h | 8 | ||||
-rw-r--r-- | val.c | 21 | ||||
-rw-r--r-- | val.h | 2 | ||||
-rwxr-xr-x | vm | bin | 20840 -> 0 bytes | |||
-rw-r--r-- | vm.c | 51 | ||||
-rw-r--r-- | vm.h | 5 |
7 files changed, 109 insertions, 14 deletions
@@ -0,0 +1,36 @@ +#include "dis.h" + +#include <stdio.h> +#include <stdint.h> + + + +void disasm_chunk(Chunk *ch) { + for (size_t ip = 0; ip < ch->blen; ) { + uint8_t instr = ch->b[ip]; + printf("%04zd\t",ip); + ip ++; +#define SIMPLE_INSTR(opcode, str) \ + case opcode: puts(str); break; + switch (instr) { + SIMPLE_INSTR(OP_RET, "ret") + case OP_LOADK:; + uint8_t ix = ch->b[ip++]; + printf("loadk #%d\t; ",ix); + Val k = ch->c[ix]; + printf("%-4s : ",valty_str(k.ty)); + println_val(k); + break; + SIMPLE_INSTR(OP_PRINT, "print") + SIMPLE_INSTR(OP_ADD, "add") + SIMPLE_INSTR(OP_SUB, "sub") + SIMPLE_INSTR(OP_MUL, "mul") + SIMPLE_INSTR(OP_DIV, "div") + } + } +#undef SIMPLE_INSTR +} + + + + @@ -0,0 +1,8 @@ +#ifndef _dis_h +#define _dis_h + +#include "vm.h" + +void disasm_chunk(Chunk *ch); + +#endif @@ -4,13 +4,28 @@ void print_val(Val v) { switch (v.ty) { case TY_NIL: - printf("nil\n"); + printf("nil"); break; case TY_NUM: - printf("%f\n",AS_NUM(v)); + printf("%f",AS_NUM(v)); break; case TY_BOOL: - printf("%s\n",AS_BOOL(v) ? "true" : "false"); + printf("%s",AS_BOOL(v) ? "true" : "false"); break; } } + +void println_val(Val v) { + print_val(v); + putchar('\n'); +} + +static const char *ty_names[] = { + "nil", + "num", + "bool", +}; + +const char *valty_str(ValTy ty) { + return ty_names[ty]; +} @@ -30,6 +30,8 @@ struct _obj { }; void print_val(Val v); +void println_val(Val v); +const char *valty_str(ValTy ty); #define IS_NUM(x) (x.ty == TY_NUM) Binary files differ@@ -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:; @@ -36,6 +36,11 @@ typedef enum { OP_RET, OP_LOADK, OP_PRINT, + + OP_ADD, + OP_SUB, + OP_MUL, + OP_DIV, } Op; |