diff options
Diffstat (limited to 'vm.c')
-rw-r--r-- | vm.c | 102 |
1 files changed, 102 insertions, 0 deletions
@@ -0,0 +1,102 @@ +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <stdbool.h> +#include <stdio.h> + +#include "val.h" +#include "vm.h" + +void *M(void *p, size_t sz) { + if (sz == 0) { + free(p); + return NULL; + } else { + return realloc(p, sz); + } +} + + +Chunk chunk_new() { + return (Chunk){ + .blen = 0, .bcap = 0, .b = NULL, + .clen = 0, .ccap = 0, .c = NULL, + }; +} +size_t chunk_wbc(Chunk *ch, uint8_t byte) { + if (ch->blen == ch->bcap) { + size_t newsz = (ch->bcap == 0 ? 8 : ch->bcap * 2); + ch->b = M(ch->b, newsz * sizeof(uint8_t)); + ch->bcap = newsz; + } + size_t ix = ch->blen; + ch->b[ix] = byte; + ch->blen ++; + return ix; +} +size_t chunk_wconst(Chunk *ch, Val v) { + if (ch->clen == ch->ccap) { + size_t newsz = (ch->ccap == 0 ? 8 : ch->ccap *2); + ch->c = M(ch->c, newsz * sizeof(Val)); + ch->ccap = newsz; + } + size_t ix = ch->clen; + ch->c[ix] = v; + ch->clen ++; + return ix; +} + +Vm vm_new(Chunk *ch) { + Vm vm = (Vm){ + .ch = ch, + .ip = 0, + .sp = 0 + }; + for (int i = 0; i < STACKSIZE; i++) { + vm.stack[i] = VAL_NIL; + } + return vm; +} + + +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, OP_LOADK); + chunk_wbc(&ch, 0); + chunk_wbc(&ch, OP_RET); + + chunk_wconst(&ch, VAL_BOOL(false)); + chunk_wconst(&ch, VAL_NIL); + chunk_wconst(&ch, VAL_NUM(420.69)); + + Vm vm = vm_new(&ch); +#define RBYTE() (vm.ch->b[vm.ip++]) + + while (1) { + uint8_t instr = RBYTE(); + switch (instr) { + case OP_RET: + printf("done!\n"); + goto done; + break; + case OP_LOADK: + uint8_t cix = RBYTE(); + Val v = vm.ch->c[cix]; + print_val(v); + break; + case OP_PRINT: + printf("print\n"); + break; + } + } + done:; +} + +int main() { runvm(); } + + |