summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--com.c35
-rw-r--r--dis.c8
-rw-r--r--ht.c26
-rw-r--r--ht.h11
-rw-r--r--mem.c6
-rw-r--r--mem.h18
-rw-r--r--state.c5
-rw-r--r--state.h15
-rw-r--r--todo10
-rw-r--r--val.c14
-rw-r--r--val.h13
-rw-r--r--vm.c65
-rw-r--r--vm.h35
14 files changed, 153 insertions, 112 deletions
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; i<newsz; i++) {
new[i].k = NULL;
new[i].v = VAL_NIL;
@@ -58,17 +54,17 @@ static void grow(Ht *h) {
}
}
- h->b = 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 <stdio.h>
#include <stdlib.h>
-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 <stddef.h>
#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 <stdlib.h>
#include <stdint.h>
+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