From 60b3369ab24f9bd2a4a6d638ab1b3013ebc29814 Mon Sep 17 00:00:00 2001 From: ubq323 Date: Thu, 20 Jun 2024 16:00:34 +0100 Subject: pass State *S everywhere contains changes from a million years ago that i don't remember much about --- Makefile | 4 ++-- com.c | 35 ++++++++++++++++++++-------------- dis.c | 8 ++++---- ht.c | 26 +++++++++++--------------- ht.h | 11 +++++++---- mem.c | 6 +++--- mem.h | 18 ++++++++++-------- state.c | 5 +++++ state.h | 15 +++++++++++++++ todo | 10 ++++++++++ val.c | 14 +++++++------- val.h | 13 +++++++++---- vm.c | 65 +++++++++++++++++++++++++++++----------------------------------- vm.h | 35 +++++++++++++++++++--------------- 14 files changed, 153 insertions(+), 112 deletions(-) create mode 100644 state.c create mode 100644 state.h create mode 100644 todo diff --git a/Makefile b/Makefile index 02a5b97..1993b3f 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -CS=ast.c com.c dis.c ht.c mem.c prs.c read.c val.c vm.c -HS=ast.h dis.h ht.h mem.h prs.h read.h val.h vm.h +CS=ast.c com.c dis.c ht.c mem.c prs.c read.c state.c val.c vm.c +HS=ast.h dis.h ht.h mem.h prs.h read.h state.h val.h vm.h CFLAGS=-O3 -Wall -Wpedantic -Werror=implicit-function-declaration bþ: $(CS) $(HS) diff --git a/com.c b/com.c index e371e6d..64aee2e 100644 --- a/com.c +++ b/com.c @@ -5,22 +5,23 @@ #include "vm.h" #include "ast.h" #include "read.h" +#include "state.h" -static void compile_node(Chunk *ch, AstNode a) { +static void compile_node(State *S, Chunk *ch, AstNode a) { switch (a.ty) { case AST_IDENT: printf("can't compile ident\n"); exit(1); break; case AST_NUM: - chunk_wbc(ch, OP_LOADK); - chunk_wbc(ch, chunk_wconst(ch, VAL_NUM(a.as.num))); + chunk_wbc(S, ch, OP_LOADK); + chunk_wbc(S, ch, chunk_wconst(S, ch, VAL_NUM(a.as.num))); break; case AST_STRING: { size_t len = strlen(a.as.str); - ObjString *o = objstring_copy(a.as.str, len); - chunk_wbc(ch, OP_LOADK); - chunk_wbc(ch, chunk_wconst(ch, VAL_OBJ(o))); + ObjString *o = objstring_copy(S, a.as.str, len); + chunk_wbc(S, ch, OP_LOADK); + chunk_wbc(S, ch, chunk_wconst(S, ch, VAL_OBJ(o))); break; } case AST_LIST: { @@ -43,22 +44,28 @@ static void compile_node(Chunk *ch, AstNode a) { exit(1); break; } - compile_node(ch, l.vals[1]); - compile_node(ch, l.vals[2]); - chunk_wbc(ch, op); + compile_node(S, ch, l.vals[1]); + compile_node(S, ch, l.vals[2]); + chunk_wbc(S, ch, op); } } } int main() { - Chunk ch = chunk_new(); + State st = state_new(); + State *S = &st; + Thread th = thread_new(S); + st.th = &th; + Chunk ch = chunk_new(S); + th.ch = &ch; + AstNode an = read(); - compile_node(&ch, an); + compile_node(S, &ch, an); - chunk_wbc(&ch, OP_PRINT); - chunk_wbc(&ch, OP_RET); + chunk_wbc(S, &ch, OP_PRINT); + chunk_wbc(S, &ch, OP_RET); - runvm(&ch); + runvm(S); } diff --git a/dis.c b/dis.c index 0eb2720..6ba934d 100644 --- a/dis.c +++ b/dis.c @@ -6,8 +6,8 @@ void disasm_chunk(Chunk *ch) { - for (size_t ip = 0; ip < ch->blen; ) { - uint8_t instr = ch->b[ip]; + for (size_t ip = 0; ip < ch->bc.len; ) { + uint8_t instr = ch->bc.d[ip]; printf("%04zd\t",ip); ip ++; #define SIMPLE_INSTR(opcode, str) \ @@ -15,9 +15,9 @@ void disasm_chunk(Chunk *ch) { switch (instr) { SIMPLE_INSTR(OP_RET, "ret") case OP_LOADK:; - uint8_t ix = ch->b[ip++]; + uint8_t ix = ch->bc.d[ip++]; printf("loadk #%d\t; ",ix); - Val k = ch->c[ix]; + Val k = ch->consts.d[ix]; printf("%-4s : ",typename_str(k)); println_val(k); break; diff --git a/ht.c b/ht.c index ca93222..474361a 100644 --- a/ht.c +++ b/ht.c @@ -20,11 +20,7 @@ uint32_t hash(char *s, size_t len) { } Ht ht_new() { - return (Ht){ - .len = 0, - .cap = 0, - .b = NULL - }; + return (Ht){ 0 }; } static HtEntry *find(HtEntry *b, size_t cap, ObjString *k) { @@ -38,10 +34,10 @@ static HtEntry *find(HtEntry *b, size_t cap, ObjString *k) { } } -static void grow(Ht *h) { - HtEntry *old = h->b; +static void grow(State *S, Ht *h) { + HtEntry *old = h->d; size_t newsz = h->cap == 0 ? 8 : h->cap * 2; - HtEntry *new = NEW_ARR(HtEntry, newsz); + HtEntry *new = NEW_ARR(S, HtEntry, newsz); for (int i = 0; ib = new; - FREE_ARR(old, HtEntry, h->cap); + h->d = new; + FREE_ARR(S, old, HtEntry, h->cap); h->cap = newsz; } -void ht_put(Ht *h, ObjString *k, Val v) { +void ht_put(State *S, Ht *h, ObjString *k, Val v) { if (h->cap == 0 || h->len >= (h->cap/2)) { - grow(h); + grow(S, h); } - HtEntry *ent = find(h->b, h->cap, k); + HtEntry *ent = find(h->d, h->cap, k); if (ent->k == NULL) { ent->k = k; h->len++; @@ -76,8 +72,8 @@ void ht_put(Ht *h, ObjString *k, Val v) { ent->v = v; } -Val ht_get(Ht *h, ObjString *k) { - HtEntry *ent = find(h->b, h->cap, k); +Val ht_get(State *S, Ht *h, ObjString *k) { + HtEntry *ent = find(h->d, h->cap, k); if (ent->k == NULL) { return VAL_NIL; } else { diff --git a/ht.h b/ht.h index 65e9012..e0e6560 100644 --- a/ht.h +++ b/ht.h @@ -1,6 +1,9 @@ #ifndef _ht_h #define _ht_h +typedef struct _ht Ht; +typedef struct _state State; + #include "val.h" typedef struct { @@ -8,16 +11,16 @@ typedef struct { Val v; } HtEntry; -typedef struct { +typedef struct _ht { size_t len; size_t cap; - HtEntry *b; + HtEntry *d; } Ht; uint32_t hash(char *s, size_t len); Ht ht_new(); -void ht_put(Ht *h, ObjString *k, Val v); -Val ht_get(Ht *h, ObjString *k); +void ht_put(State *S, Ht *h, ObjString *k, Val v); +Val ht_get(State *S, Ht *h, ObjString *k); #endif diff --git a/mem.c b/mem.c index d464f7d..225834d 100644 --- a/mem.c +++ b/mem.c @@ -3,7 +3,7 @@ #include #include -void *M(void *p, size_t old, size_t new) { +void *M(State *S, void *p, size_t old, size_t new) { if (new == 0) { free(p); return NULL; @@ -17,8 +17,8 @@ void *M(void *p, size_t old, size_t new) { } } -Obj *alloc_obj(size_t sz, ObjTy oty) { - Obj *o = M(NULL, 0, sz); +Obj *alloc_obj(State *S, size_t sz, ObjTy oty) { + Obj *o = M(S, NULL, 0, sz); o->oty = oty; return o; } diff --git a/mem.h b/mem.h index 8c528b9..d13e02f 100644 --- a/mem.h +++ b/mem.h @@ -3,18 +3,20 @@ #include #include "val.h" +#include "vm.h" +#include "state.h" -void *M(void *p, size_t old, size_t new); +void *M(State *S, void *ptr, size_t old, size_t new); -#define NEW(t) (t*)M(NULL, 0, sizeof(t)) -#define NEW_ARR(t,n) (t*)M(NULL, 0, (n)*sizeof(t)) -#define RENEW_ARR(p,t,old,new) (t*)M((p), (old)*sizeof(t), (new)*sizeof(t)) -#define NEW_OBJ(t, oty) (t*)alloc_obj(sizeof(t), oty) +#define NEW(S,ty) (ty*)M(S, NULL, 0, sizeof(ty)) +#define NEW_ARR(S,ty,n) (ty*)M(S, NULL, 0, (n)*sizeof(ty)) +#define RENEW_ARR(S,p,ty,old,new) (ty*)M(S, (p), (old)*sizeof(ty), (new)*sizeof(ty)) +#define NEW_OBJ(S,ty, oty) (ty*)alloc_obj(S, sizeof(ty), oty) -#define FREE(p,t) M(p, sizeof(t), 0) -#define FREE_ARR(p,t,old) M(p, (old)*sizeof(t), 0) +#define FREE(S,p,ty) M(S, p, sizeof(ty), 0) +#define FREE_ARR(S,p,ty,old) M(S, p, (old)*sizeof(ty), 0) -Obj *alloc_obj(size_t sz, ObjTy oty); +Obj *alloc_obj(State *S, size_t sz, ObjTy oty); #endif diff --git a/state.c b/state.c new file mode 100644 index 0000000..bc0861b --- /dev/null +++ b/state.c @@ -0,0 +1,5 @@ +#include "state.h" + +State state_new() { + return (State){ 0 }; +} diff --git a/state.h b/state.h new file mode 100644 index 0000000..2316d1e --- /dev/null +++ b/state.h @@ -0,0 +1,15 @@ +#ifndef _state_h +#define _state_h + +typedef struct _state State; + +#include "vm.h" +#include "ht.h" + +struct _state { + Thread *th; + Ht strings; +}; +State state_new(); + +#endif diff --git a/todo b/todo new file mode 100644 index 0000000..0dbc87d --- /dev/null +++ b/todo @@ -0,0 +1,10 @@ +string interning + pass state through all allocation things + decide on state vs global state, terminology +globals, getting and setting +functions, returning +locals, lexical scoping, closures, upvalues +lists, hashes, other useful types +garbage collector +macros + diff --git a/val.c b/val.c index 530737d..22c92ce 100644 --- a/val.c +++ b/val.c @@ -5,22 +5,22 @@ #include "ht.h" -ObjString *objstring_copy(char *src, size_t len) { - char *d = NEW_ARR(char, 1+len); +ObjString *objstring_copy(State *S, char *src, size_t len) { + char *d = NEW_ARR(S, char, 1+len); memcpy(d, src, len); d[len] = '\0'; - ObjString *o = NEW_OBJ(ObjString, OTY_STRING); + ObjString *o = NEW_OBJ(S, ObjString, OTY_STRING); o->len = len; - o->b = d; + o->d = d; o->hash = hash(d, len); return o; } -ObjString *objstring_take(char *src, size_t len) { - ObjString *o = NEW_OBJ(ObjString, OTY_STRING); +ObjString *objstring_take(State *S, char *src, size_t len) { + ObjString *o = NEW_OBJ(S, ObjString, OTY_STRING); o->len = len; - o->b = src; + o->d = src; o->hash = hash(src, len); return o; diff --git a/val.h b/val.h index 3cf3251..d742c14 100644 --- a/val.h +++ b/val.h @@ -8,6 +8,7 @@ typedef struct _val Val; typedef struct _obj Obj; +typedef struct _state State; typedef enum { @@ -42,11 +43,15 @@ typedef struct { Obj obj; size_t len; uint32_t hash; - char *b; + char *d; } ObjString; -ObjString *objstring_copy(char *src, size_t len); -ObjString *objstring_take(char *src, size_t len); +// Constructs a new objstring from the given C string, +// creating its own fresh copy of the data. +ObjString *objstring_copy(State *S, char *src, size_t len); +// Constructs a new objstring from the given C string, +// taking ownership of the provided data. +ObjString *objstring_take(State *S, char *src, size_t len); #define IS_NIL(x) (x.ty == NIL) @@ -61,7 +66,7 @@ ObjString *objstring_take(char *src, size_t len); #define AS_OBJ(x) (x.as.o) #define AS_STRING(x) ((ObjString*)AS_OBJ(x)) -#define AS_CSTRING(x) (AS_STRING(x)->b) +#define AS_CSTRING(x) (AS_STRING(x)->d) #define VAL_NIL ((Val){.ty=TY_NIL}) #define VAL_NUM(x) ((Val){.ty=TY_NUM, .as.d=(x) }) diff --git a/vm.c b/vm.c index acbfaa3..eb041a0 100644 --- a/vm.c +++ b/vm.c @@ -10,59 +10,52 @@ #include "dis.h" -Chunk chunk_new() { - return (Chunk){ - .blen = 0, .bcap = 0, .b = NULL, - .clen = 0, .ccap = 0, .c = NULL, - }; +Chunk chunk_new(State *S) { + return (Chunk){ 0 }; } - -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 = RENEW_ARR(ch->b, uint8_t, ch->bcap, newsz); - ch->bcap = newsz; +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->blen; - ch->b[ix] = byte; - ch->blen ++; + size_t ix = ch->bc.len; + ch->bc.d[ix] = byte; + ch->bc.len ++; 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 = RENEW_ARR(ch->c, Val, ch->ccap, newsz); - ch->ccap = newsz; +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->clen; - ch->c[ix] = v; - ch->clen ++; + size_t ix = ch->consts.len; + ch->consts.d[ix] = v; + ch->consts.len ++; return ix; } -Vm vm_new(Chunk *ch) { - Vm vm = (Vm){ - .ch = ch, - .ip = 0, - .sp = 0 - }; +Thread thread_new(State *S) { + Thread th = (Thread){ 0 }; for (int i = 0; i < STACKSIZE; i++) { - vm.stack[i] = VAL_NIL; + th.stack[i] = VAL_NIL; } - return vm; + return th; } -void runvm(Chunk *ch) { +void runvm(State *S) { + Thread *th = S->th; + Chunk *ch = th->ch; disasm_chunk(ch); - Vm vm = vm_new(ch); -#define RBYTE() (vm.ch->b[vm.ip++]) +#define RBYTE() (ch->bc.d[th->ip++]) -#define PUSH(v) vm.stack[vm.sp++] = v; -#define POP() (vm.stack[--vm.sp]) +#define PUSH(v) th->stack[th->sp++] = v; +#define POP() (th->stack[--th->sp]) puts("---"); while (1) { @@ -74,7 +67,7 @@ void runvm(Chunk *ch) { break; case OP_LOADK:; uint8_t cix = RBYTE(); - Val v = vm.ch->c[cix]; + Val v = ch->consts.d[cix]; PUSH(v); // printf(" (pushing "); // print_val(v); diff --git a/vm.h b/vm.h index 9a17f77..4400564 100644 --- a/vm.h +++ b/vm.h @@ -5,30 +5,35 @@ #include #include +typedef struct _thread Thread; + #include "val.h" +#include "state.h" typedef struct { - // bytecode - size_t blen; - size_t bcap; - uint8_t *b; - // constants - size_t clen; - size_t ccap; - Val *c; + 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(); -size_t chunk_wbc(Chunk *ch, uint8_t byte); -size_t chunk_wconst(Chunk *ch, Val v); +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); #define STACKSIZE 128 -typedef struct { +typedef struct _thread { Chunk *ch; size_t ip; Val stack[STACKSIZE]; size_t sp; -} Vm; -Vm vm_new(Chunk *ch); +} Thread; +Thread thread_new(State *S); typedef enum { OP_RET, @@ -41,6 +46,6 @@ typedef enum { OP_DIV, } Op; -void runvm(Chunk *ch); +void runvm(State *S); #endif -- cgit v1.2.3