summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--run.h2
-rw-r--r--run_old.c (renamed from run.c)0
-rw-r--r--val.c16
-rw-r--r--val.h9
-rwxr-xr-xvmbin0 -> 20840 bytes
-rw-r--r--vm.c102
-rw-r--r--vm.h42
7 files changed, 169 insertions, 2 deletions
diff --git a/run.h b/run.h
index 155b59b..291897c 100644
--- a/run.h
+++ b/run.h
@@ -3,8 +3,8 @@
#include "ast.h"
#include "ht.h"
+#include "val.h"
-int eval(Env *s, AstNode a);
#endif
diff --git a/run.c b/run_old.c
index e4fa540..e4fa540 100644
--- a/run.c
+++ b/run_old.c
diff --git a/val.c b/val.c
new file mode 100644
index 0000000..4456148
--- /dev/null
+++ b/val.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include "val.h"
+
+void print_val(Val v) {
+ switch (v.ty) {
+ case TY_NIL:
+ printf("nil\n");
+ break;
+ case TY_NUM:
+ printf("%f\n",AS_NUM(v));
+ break;
+ case TY_BOOL:
+ printf("%s\n",AS_BOOL(v) ? "true" : "false");
+ break;
+ }
+}
diff --git a/val.h b/val.h
index 4560a1c..1f2bd8d 100644
--- a/val.h
+++ b/val.h
@@ -10,9 +10,9 @@ typedef struct _obj Obj;
typedef enum {
+ TY_NIL,
TY_NUM,
TY_BOOL,
- TY_NIL,
} ValTy;
struct _val {
@@ -29,11 +29,18 @@ struct _obj {
int foo;
};
+void print_val(Val v);
+
#define IS_NUM(x) (x.ty == TY_NUM)
#define IS_BOOL(x) (x.ty == TY_BOOL)
#define IS_NIL(x) (x.ty == NIL)
+#define AS_NUM(x) (x.as.d)
+#define AS_BOOL(x) (x.as.b)
+#define VAL_NUM(x) ((Val){.ty=TY_NUM, .as.d=x})
+#define VAL_BOOL(x) ((Val){.ty=TY_BOOL, .as.b=x})
+#define VAL_NIL ((Val){.ty=TY_NIL})
#endif
diff --git a/vm b/vm
new file mode 100755
index 0000000..9ecf078
--- /dev/null
+++ b/vm
Binary files differ
diff --git a/vm.c b/vm.c
new file mode 100644
index 0000000..00692b0
--- /dev/null
+++ b/vm.c
@@ -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(); }
+
+
diff --git a/vm.h b/vm.h
new file mode 100644
index 0000000..7f76e05
--- /dev/null
+++ b/vm.h
@@ -0,0 +1,42 @@
+#ifndef _vm_h
+#define _vm_h
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "val.h"
+
+void *M(void *p, size_t sz);
+
+typedef struct {
+ // bytecode
+ size_t blen;
+ size_t bcap;
+ uint8_t *b;
+ // constants
+ size_t clen;
+ size_t ccap;
+ Val *c;
+} Chunk;
+Chunk chunk_new();
+size_t chunk_wbc(Chunk *ch, uint8_t byte);
+size_t chunk_wconst(Chunk *ch, Val v);
+
+#define STACKSIZE 128
+typedef struct {
+ Chunk *ch;
+ size_t ip;
+ Val stack[STACKSIZE];
+ size_t sp;
+} Vm;
+Vm vm_new(Chunk *ch);
+
+typedef enum {
+ OP_RET,
+ OP_LOADK,
+ OP_PRINT,
+} Op;
+
+
+#endif