diff options
author | ubq323 <ubq323@ubq323.website> | 2024-06-21 18:59:44 +0100 |
---|---|---|
committer | ubq323 <ubq323@ubq323.website> | 2024-06-21 18:59:44 +0100 |
commit | 24f5d4f4456fce3a9e8cd5a7c1225facd60ae979 (patch) | |
tree | 095ff7ea3e3620402a9346ae5a9b2817de72c436 | |
parent | fbdfd9bf74b178a34543e0e347f441d689f73438 (diff) |
put state and chunk into new compiler struct; refactor mildly
-rw-r--r-- | com.c | 189 | ||||
-rw-r--r-- | vm.c | 31 | ||||
-rw-r--r-- | vm.h | 18 |
3 files changed, 118 insertions, 120 deletions
@@ -2,28 +2,62 @@ #include <string.h> #include <stdio.h> -#include "vm.h" -#include "ast.h" -#include "read.h" -#include "state.h" - -static size_t placeholder(State *S, Chunk *ch) { - size_t old_ix = ch->bc.len; - chunk_wbc(S, ch, 0x00); - chunk_wbc(S, ch, 0x00); +#include "com.h" + +#define BYTECODE(C) (C->ch->bc) + +static size_t placeholder(Compiler *C) { + size_t old_ix = BYTECODE(C).len; + chunk_wbc(C, 0x00); + chunk_wbc(C, 0x00); return old_ix; } -static void patch(State *S, Chunk *ch, size_t addr, uint16_t val) { - ch->bc.d[addr] = val & 0xff; - ch->bc.d[addr+1] = (val & 0xff00) >> 8; +static void patch(Compiler *C, size_t addr, uint16_t val) { + BYTECODE(C).d[addr] = val & 0xff; + BYTECODE(C).d[addr+1] = (val & 0xff00) >> 8; +} + + +Chunk chunk_new(State *S) { + return (Chunk){ 0 }; +} + +size_t chunk_wbc(Compiler *C, uint8_t byte) { + Chunk *ch = C->ch; + if (ch->bc.len == ch->bc.cap) { + size_t newsz = (ch->bc.cap == 0 ? 8 : ch->bc.cap * 2); + ch->bc.d = RENEW_ARR(C->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(Compiler *C, Val v) { + Chunk *ch = C->ch; + for (int i = 0; i < ch->consts.len; i ++) + if (val_equal(v, ch->consts.d[i])) return i; + + if (ch->consts.len == ch->consts.cap) { + size_t newsz = (ch->consts.cap == 0 ? 8 : ch->consts.cap *2); + ch->consts.d = RENEW_ARR(C->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; +} -static void compile_node(State *S, Chunk *ch, AstNode a); -typedef void (*form_compiler)(State *S, Chunk *ch, AstVec l, Op op); + +static void compile_node(Compiler *C, AstNode a); + +typedef void (*form_compiler)(Compiler *C, AstVec l, Op op); typedef struct { char *name; int min_params; @@ -33,32 +67,32 @@ typedef struct { } BuiltinForm; -void single_form(State *S, Chunk *ch, AstVec l, Op op) { - compile_node(S, ch, l.vals[1]); - chunk_wbc(S, ch, op); +void single_form(Compiler *C, AstVec l, Op op) { + compile_node(C, l.vals[1]); + chunk_wbc(C, op); } -void set_form(State *S, Chunk *ch, AstVec l, Op op) { +void set_form(Compiler *C, AstVec l, Op op) { AstNode ident = l.vals[1]; if (ident.ty != AST_IDENT) { fprintf(stderr, "set's first argument must be identifier"); exit(1); } - ObjString *o = objstring_copy_cstr(S, ident.as.str); - compile_node(S, ch, l.vals[2]); - chunk_wbc(S, ch, OP_SETGLOBAL); - chunk_wbc(S, ch, chunk_wconst(S, ch, VAL_OBJ(o))); + ObjString *o = objstring_copy_cstr(C->S, ident.as.str); + compile_node(C, l.vals[2]); + chunk_wbc(C, OP_SETGLOBAL); + chunk_wbc(C, chunk_wconst(C, VAL_OBJ(o))); } -void do_form(State *S, Chunk *ch, AstVec l, Op op) { +void do_form(Compiler *C, AstVec l, Op op) { for (int i = 1; i < l.len - 1; i++) { - compile_node(S, ch, l.vals[i]); - chunk_wbc(S, ch, OP_DROP); + compile_node(C, l.vals[i]); + chunk_wbc(C, OP_DROP); } - compile_node(S, ch, l.vals[l.len - 1]); + compile_node(C, l.vals[l.len - 1]); } -void if_form(State *S, Chunk *ch, AstVec l, Op op) { +void if_form(Compiler *C, AstVec l, Op op) { // (if cond if-true if-false) // cond // 0branch ->A @@ -66,21 +100,21 @@ void if_form(State *S, Chunk *ch, AstVec l, Op op) { // skip ->B // A: if-false // B: - compile_node(S, ch, l.vals[1]); - chunk_wbc(S, ch, OP_0BRANCH); - size_t ph_a = placeholder(S, ch); - compile_node(S, ch, l.vals[2]); - chunk_wbc(S, ch, OP_SKIP); - size_t ph_b = placeholder(S, ch); - size_t dest_a = ch->bc.len; - compile_node(S, ch, l.vals[3]); - size_t dest_b = ch->bc.len; - - patch(S, ch, ph_a, dest_a - ph_a - 2); - patch(S, ch, ph_b, dest_b - ph_b - 2); + compile_node(C, l.vals[1]); + chunk_wbc(C, OP_0BRANCH); + size_t ph_a = placeholder(C); + compile_node(C, l.vals[2]); + chunk_wbc(C, OP_SKIP); + size_t ph_b = placeholder(C); + size_t dest_a = BYTECODE(C).len; + compile_node(C, l.vals[3]); + size_t dest_b = BYTECODE(C).len; + + patch(C, ph_a, dest_a - ph_a - 2); + patch(C, ph_b, dest_b - ph_b - 2); } -void while_form(State *S, Chunk *ch, AstVec l, Op op) { +void while_form(Compiler *C, AstVec l, Op op) { // (while cond body ...) // A: // cond @@ -89,27 +123,27 @@ void while_form(State *S, Chunk *ch, AstVec l, Op op) { // redo ->A // B: // nil (while loop always returns nil) - size_t dest_a = ch->bc.len; - compile_node(S, ch, l.vals[1]); - chunk_wbc(S, ch, OP_0BRANCH); - size_t ph_b = placeholder(S, ch); + size_t dest_a = BYTECODE(C).len; + compile_node(C, l.vals[1]); + chunk_wbc(C, OP_0BRANCH); + size_t ph_b = placeholder(C); for (int i = 2; i < l.len; i++) { - compile_node(S, ch, l.vals[i]); - chunk_wbc(S, ch, OP_DROP); + compile_node(C, l.vals[i]); + chunk_wbc(C, OP_DROP); } - chunk_wbc(S, ch, OP_REDO); - size_t ph_a = placeholder(S, ch); - size_t dest_b = ch->bc.len; - chunk_wbc(S, ch, OP_NIL); + chunk_wbc(C, OP_REDO); + size_t ph_a = placeholder(C); + size_t dest_b = BYTECODE(C).len; + chunk_wbc(C, OP_NIL); - patch(S, ch, ph_a, ph_a - dest_a + 2); - patch(S, ch, ph_b, dest_b - ph_b - 2); + patch(C, ph_a, ph_a - dest_a + 2); + patch(C, ph_b, dest_b - ph_b - 2); } -void arith_form(State *S, Chunk *ch, AstVec l, Op op) { - compile_node(S, ch, l.vals[1]); - compile_node(S, ch, l.vals[2]); - chunk_wbc(S, ch, op); +void arith_form(Compiler *C, AstVec l, Op op) { + compile_node(C, l.vals[1]); + compile_node(C, l.vals[2]); + chunk_wbc(C, op); } static BuiltinForm builtin_forms[] = { @@ -143,7 +177,7 @@ static BuiltinIdent builtin_idents[] = { { 0 }, }; -static void compile_node(State *S, Chunk *ch, AstNode a) { +static void compile_node(Compiler *C, AstNode a) { switch (a.ty) { case AST_IDENT:; char *ident = a.as.str; @@ -155,22 +189,22 @@ static void compile_node(State *S, Chunk *ch, AstNode a) { } } if (found_builtin != NULL) { - chunk_wbc(S, ch, found_builtin->op); + chunk_wbc(C, found_builtin->op); } else { // read global variable - ObjString *o = objstring_copy_cstr(S, a.as.str); - chunk_wbc(S, ch, OP_GETGLOBAL); - chunk_wbc(S, ch, chunk_wconst(S, ch, VAL_OBJ(o))); + ObjString *o = objstring_copy_cstr(C->S, a.as.str); + chunk_wbc(C, OP_GETGLOBAL); + chunk_wbc(C, chunk_wconst(C, VAL_OBJ(o))); } break; case AST_NUM: - chunk_wbc(S, ch, OP_LOADK); - chunk_wbc(S, ch, chunk_wconst(S, ch, VAL_NUM(a.as.num))); + chunk_wbc(C, OP_LOADK); + chunk_wbc(C, chunk_wconst(C, VAL_NUM(a.as.num))); break; case AST_STRING: { - ObjString *o = objstring_copy_cstr(S, a.as.str); - chunk_wbc(S, ch, OP_LOADK); - chunk_wbc(S, ch, chunk_wconst(S, ch, VAL_OBJ(o))); + ObjString *o = objstring_copy_cstr(C->S, a.as.str); + chunk_wbc(C, OP_LOADK); + chunk_wbc(C, chunk_wconst(C, VAL_OBJ(o))); break; } case AST_LIST: { @@ -179,6 +213,7 @@ static void compile_node(State *S, Chunk *ch, AstNode a) { #define CK(cond, msg) if (!(cond)) { fputs(msg "\n", stderr); exit(1); } CK(l.len > 0, "can't handle empty list"); CK(l.vals[0].ty == AST_IDENT, "can only call ops"); + #undef CK char *head = l.vals[0].as.str; @@ -201,7 +236,7 @@ static void compile_node(State *S, Chunk *ch, AstNode a) { exit(1); } - form->action(S, ch, l, form->op); + form->action(C, l, form->op); } else { fprintf(stderr, "unknown form %s\n", head); exit(1); @@ -215,10 +250,7 @@ static void compile_node(State *S, Chunk *ch, AstNode a) { int main(int argc, char **argv) { State st = state_new(); State *S = &st; - Thread th = thread_new(S); - st.th = &th; Chunk ch = chunk_new(S); - th.ch = &ch; S->do_disasm = (argc > 1 && 0 == strcmp(argv[1], "-l")); @@ -234,10 +266,21 @@ int main(int argc, char **argv) { ht_put(S, &st.globals, o3, VAL_NUM(3)); AstNode an = read(); - compile_node(S, &ch, an); - chunk_wbc(S, &ch, OP_PUTS); - chunk_wbc(S, &ch, OP_RET); + Compiler com = (Compiler){ + .S = S, + .ch = &ch, + }; + Compiler *C = &com; + compile_node(C, an); + + + chunk_wbc(C, OP_PUTS); + chunk_wbc(C, OP_RET); + + Thread th = thread_new(S); + th.ch = &ch; + S->th = &th; return runvm(S); } @@ -9,38 +9,9 @@ #include "vm.h" #include "mem.h" #include "dis.h" +#include "com.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) { - for (int i = 0; i < ch->consts.len; i ++) - if (val_equal(v, ch->consts.d[i])) return i; - - 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 }; @@ -8,23 +8,7 @@ typedef struct _thread Thread; #include "val.h" -#include "state.h" - -typedef struct { - struct { - size_t len; - size_t cap; - uint8_t *d; - } bc; - struct { - size_t len; - size_t cap; - Val *d; - } consts; -} Chunk; -Chunk chunk_new(State *S); -size_t chunk_wbc(State *S, Chunk *ch, uint8_t byte); -size_t chunk_wconst(State *S, Chunk *ch, Val v); +#include "com.h" #define STACKSIZE 128 typedef struct _thread { |