From 24fb17017e9d6238488c9827da0ee6d0f4f84356 Mon Sep 17 00:00:00 2001 From: ubq323 Date: Tue, 1 Aug 2023 00:05:35 +0100 Subject: dissasembler and basic arithmetic --- dis.c | 36 ++++++++++++++++++++++++++++++++++++ dis.h | 8 ++++++++ val.c | 21 ++++++++++++++++++--- val.h | 2 ++ vm | Bin 20840 -> 0 bytes vm.c | 51 ++++++++++++++++++++++++++++++++++++++++----------- vm.h | 5 +++++ 7 files changed, 109 insertions(+), 14 deletions(-) create mode 100644 dis.c create mode 100644 dis.h delete mode 100755 vm diff --git a/dis.c b/dis.c new file mode 100644 index 0000000..09e7571 --- /dev/null +++ b/dis.c @@ -0,0 +1,36 @@ +#include "dis.h" + +#include +#include + + + +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 +} + + + + diff --git a/dis.h b/dis.h new file mode 100644 index 0000000..47aff62 --- /dev/null +++ b/dis.h @@ -0,0 +1,8 @@ +#ifndef _dis_h +#define _dis_h + +#include "vm.h" + +void disasm_chunk(Chunk *ch); + +#endif diff --git a/val.c b/val.c index 4456148..9e832a6 100644 --- a/val.c +++ b/val.c @@ -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]; +} diff --git a/val.h b/val.h index 1f2bd8d..bf58c06 100644 --- a/val.h +++ b/val.h @@ -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) diff --git a/vm b/vm deleted file mode 100755 index 9ecf078..0000000 Binary files a/vm and /dev/null differ diff --git a/vm.c b/vm.c index 00692b0..72f69fa 100644 --- a/vm.c +++ b/vm.c @@ -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:; diff --git a/vm.h b/vm.h index 7f76e05..cfa3f6d 100644 --- a/vm.h +++ b/vm.h @@ -36,6 +36,11 @@ typedef enum { OP_RET, OP_LOADK, OP_PRINT, + + OP_ADD, + OP_SUB, + OP_MUL, + OP_DIV, } Op; -- cgit v1.2.3