summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--com.c15
-rw-r--r--dis.c2
-rw-r--r--g.peg8
-rw-r--r--test.bþ2
-rw-r--r--val.c40
-rw-r--r--val.h50
-rw-r--r--vm.c9
7 files changed, 93 insertions, 33 deletions
diff --git a/com.c b/com.c
index 7540a6d..387d709 100644
--- a/com.c
+++ b/com.c
@@ -1,4 +1,5 @@
#include <stdlib.h>
+#include <string.h>
#include <stdio.h>
#include "vm.h"
@@ -11,15 +12,18 @@ static void compile_node(Chunk *ch, AstNode a) {
printf("can't compile ident\n");
exit(1);
break;
- case AST_STRING:
- printf("can't compile strings yet\n");
- exit(1);
- break;
case AST_NUM:
chunk_wbc(ch, OP_LOADK);
chunk_wbc(ch, chunk_wconst(ch, VAL_NUM(a.as.num)));
break;
- case AST_LIST:;
+ case AST_STRING: {
+ size_t len = strlen(a.as.str);
+ ObjString *o = objstring_new(a.as.str, len);
+ chunk_wbc(ch, OP_LOADK);
+ chunk_wbc(ch, chunk_wconst(ch, VAL_OBJ(o)));
+ break;
+ }
+ case AST_LIST: {
AstVec l = a.as.list;
#define CK(cond, msg) if (!(cond)) { puts(msg); exit(1); }
CK(l.len == 3, "can only compile binary ops");
@@ -43,6 +47,7 @@ static void compile_node(Chunk *ch, AstNode a) {
compile_node(ch, l.vals[2]);
chunk_wbc(ch, op);
}
+ }
}
diff --git a/dis.c b/dis.c
index 09e7571..b96f07c 100644
--- a/dis.c
+++ b/dis.c
@@ -18,7 +18,7 @@ void disasm_chunk(Chunk *ch) {
uint8_t ix = ch->b[ip++];
printf("loadk #%d\t; ",ix);
Val k = ch->c[ix];
- printf("%-4s : ",valty_str(k.ty));
+ printf("%-4s : ",valty_str(k));
println_val(k);
break;
SIMPLE_INSTR(OP_PRINT, "print")
diff --git a/g.peg b/g.peg
index 552d76f..c026e62 100644
--- a/g.peg
+++ b/g.peg
@@ -3,13 +3,15 @@
#include <stdlib.h>
#include <string.h>
-/*
+
+#ifdef DO_PARSE_DEBUG
static const char *dbg_str[] = { "Evaluating rule", "Matched rule", "Abandoning rule" };
#define PCC_DEBUG(auxil, event, rule, level, pos, buffer, length) \
fprintf(stderr, "%*s%s %s @%zu [%.*s]\n", (int)((level) * 2), "", dbg_str[event], rule, pos, (int)(length), buffer)
+#endif
+
-*/
}
@@ -35,7 +37,7 @@ list <- { $$ = astnode_new_list(); }
number <- < [0-9]+ > (! ident_char) _ { $$ = astnode_new_num(atoi($1)); }
ident <- < ident_char+ > _ { $$ = astnode_new_ident(strdup($1)); }
-string <- '"' < [^"]+ > '"' { $$ = astnode_new_string(strdup($1)); }
+string <- '"' < [^"]+ > '"' _ { $$ = astnode_new_string(strdup($1)); }
ident_char <- [-_a-zA-Z'+*0-9]
_ <- [ \t\n]*
diff --git a/test.bþ b/test.bþ
index f79fc6b..641d9f2 100644
--- a/test.bþ
+++ b/test.bþ
@@ -1 +1 @@
-(+ 6 (* 9 25))
+(+ "abc" (* 9 25))
diff --git a/val.c b/val.c
index 9e832a6..41d3a06 100644
--- a/val.c
+++ b/val.c
@@ -1,5 +1,18 @@
#include <stdio.h>
+#include <string.h>
#include "val.h"
+#include "vm.h"
+
+ObjString *objstring_new(char *src, size_t len) {
+ char *d = M(NULL, (1 + len) * sizeof (char));
+ memcpy(d, src, len);
+ d[len] = '\0';
+ ObjString *o = M(NULL, sizeof(ObjString));
+ o->obj.oty = OTY_STRING;
+ o->len = len;
+ o->b = d;
+ return o;
+}
void print_val(Val v) {
switch (v.ty) {
@@ -12,20 +25,33 @@ void print_val(Val v) {
case TY_BOOL:
printf("%s",AS_BOOL(v) ? "true" : "false");
break;
+ case TY_OBJ:
+ switch (AS_OBJ(v)->oty) {
+ case OTY_STRING:
+ printf("%s", AS_CSTRING(v));
+ break;
+ }
+ break;
}
}
+
void println_val(Val v) {
print_val(v);
putchar('\n');
}
-static const char *ty_names[] = {
- "nil",
- "num",
- "bool",
-};
-const char *valty_str(ValTy ty) {
- return ty_names[ty];
+const char *valty_str(Val v) {
+ switch(v.ty) {
+ case TY_NIL: return "nil";
+ case TY_NUM: return "num";
+ case TY_BOOL: return "bool";
+ case TY_OBJ:
+ switch (AS_OBJ(v)->oty) {
+ case OTY_STRING: return "String";
+ }
+ break;
+ }
+ return "???";
}
diff --git a/val.h b/val.h
index bf58c06..1ab716b 100644
--- a/val.h
+++ b/val.h
@@ -3,9 +3,7 @@
#include <stdbool.h>
-struct _val;
typedef struct _val Val;
-struct _obj;
typedef struct _obj Obj;
@@ -13,36 +11,60 @@ typedef enum {
TY_NIL,
TY_NUM,
TY_BOOL,
+ TY_OBJ,
} ValTy;
-struct _val {
+typedef struct _val {
ValTy ty;
union {
double d;
bool b;
Obj *o;
} as;
-};
-
-struct _obj {
- // some gc shit
- int foo;
-};
-
+} Val;
void print_val(Val v);
void println_val(Val v);
-const char *valty_str(ValTy ty);
+const char *valty_str(Val v);
+
+
+typedef enum {
+ OTY_STRING,
+} ObjTy;
+
+typedef struct _obj {
+ ObjTy oty;
+} Obj;
+typedef struct {
+ Obj obj;
+ size_t len;
+ char *b;
+} ObjString;
+// copies data
+ObjString *objstring_new(char *src, size_t len);
+
+#define IS_NIL(x) (x.ty == NIL)
#define IS_NUM(x) (x.ty == TY_NUM)
#define IS_BOOL(x) (x.ty == TY_BOOL)
-#define IS_NIL(x) (x.ty == NIL)
+#define IS_OBJ(x) (x.ty == TY_OBJ)
+
+#define IS_STRING(x) (is_obj_ty((x), OTY_STRING))
#define AS_NUM(x) (x.as.d)
#define AS_BOOL(x) (x.as.b)
+#define AS_OBJ(x) (x.as.o)
+
+#define AS_STRING(x) ((ObjString*)AS_OBJ(x))
+#define AS_CSTRING(x) (AS_STRING(x)->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})
+#define VAL_NUM(x) ((Val){.ty=TY_NUM, .as.d=(x) })
+#define VAL_BOOL(x) ((Val){.ty=TY_BOOL, .as.b=(x) })
+#define VAL_OBJ(x) ((Val){.ty=TY_OBJ, .as.o=(Obj*)(x) })
+
+static inline bool is_obj_ty(Val v, ObjTy t) {
+ return IS_OBJ(v) && (AS_OBJ(v)->oty == t);
+}
#endif
diff --git a/vm.c b/vm.c
index 70f065b..f7887d3 100644
--- a/vm.c
+++ b/vm.c
@@ -13,7 +13,12 @@ void *M(void *p, size_t sz) {
free(p);
return NULL;
} else {
- return realloc(p, sz);
+ void *x = realloc(p, sz);
+ if (x == NULL) {
+ printf("out of memory! aaaaaaa!!!!!\n");
+ exit(42);
+ }
+ return x;
}
}
@@ -107,7 +112,7 @@ void runvm(Chunk *ch) {
Val a = POP(); \
if (!IS_NUM(a) || !IS_NUM(b)) { \
printf("can't do arithmetic on %s and %s\n", \
- valty_str(a.ty), valty_str(b.ty)); \
+ valty_str(a), valty_str(b)); \
goto done; \
} \
PUSH(VAL_NUM(AS_NUM(a) OP AS_NUM(b))); \