#include #include #include #include #include #include "val.h" #include "vm.h" #include "mem.h" #include "dis.h" Chunk chunk_new(State *S) { return (Chunk){ 0 }; } size_t chunk_wbc(State *S, Chunk *ch, uint8_t byte) { if (ch->bc.len == ch->bc.cap) { size_t newsz = (ch->bc.cap == 0 ? 8 : ch->bc.cap * 2); ch->bc.d = RENEW_ARR(S, ch->bc.d, uint8_t, ch->bc.cap, newsz); ch->bc.cap = newsz; } size_t ix = ch->bc.len; ch->bc.d[ix] = byte; ch->bc.len ++; return ix; } size_t chunk_wconst(State *S, Chunk *ch, Val v) { if (ch->consts.len == ch->consts.cap) { size_t newsz = (ch->consts.cap == 0 ? 8 : ch->consts.cap *2); ch->consts.d = RENEW_ARR(S, ch->consts.d, Val, ch->consts.cap, newsz); ch->consts.cap = newsz; } size_t ix = ch->consts.len; ch->consts.d[ix] = v; ch->consts.len ++; return ix; } Thread thread_new(State *S) { Thread th = (Thread){ 0 }; for (int i = 0; i < STACKSIZE; i++) { th.stack[i] = VAL_NIL; } return th; } void runvm(State *S) { Thread *th = S->th; Chunk *ch = th->ch; disasm_chunk(ch); #define RBYTE() (ch->bc.d[th->ip++]) #define PUSH(v) th->stack[th->sp++] = v; #define POP() (th->stack[--th->sp]) puts("---"); 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 = ch->consts.d[cix]; PUSH(v); // printf(" (pushing "); // print_val(v); // printf(")\n"); break; case OP_PRINT: 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", \ typename_str(a), typename_str(b)); \ 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:; }