From d8b50976ce7fd4a44ba9172d69e8ae4ca6cab596 Mon Sep 17 00:00:00 2001 From: ubq323 Date: Fri, 4 Aug 2023 00:06:05 +0100 Subject: add string object values. you can't do anything with them yet --- com.c | 15 ++++++++++----- dis.c | 2 +- g.peg | 8 +++++--- "test.b\303\276" | 2 +- val.c | 40 +++++++++++++++++++++++++++++++++------- val.h | 50 ++++++++++++++++++++++++++++++++++++-------------- vm.c | 9 +++++++-- 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 +#include #include #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 #include -/* + +#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\303\276" "b/test.b\303\276" index f79fc6b..641d9f2 100644 --- "a/test.b\303\276" +++ "b/test.b\303\276" @@ -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 +#include #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 -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))); \ -- cgit v1.2.3