diff options
author | ubq323 <ubq323@ubq323.website> | 2023-08-04 00:06:05 +0100 |
---|---|---|
committer | ubq323 <ubq323@ubq323.website> | 2023-08-04 00:06:49 +0100 |
commit | d8b50976ce7fd4a44ba9172d69e8ae4ca6cab596 (patch) | |
tree | a87f179fd4608da63acbfcbf584dab11a2167896 | |
parent | 8b96f9a4f27ed859bdd975608419c86841664dc9 (diff) |
add string object values. you can't do anything with them yet
-rw-r--r-- | com.c | 15 | ||||
-rw-r--r-- | dis.c | 2 | ||||
-rw-r--r-- | g.peg | 8 | ||||
-rw-r--r-- | test.bþ | 2 | ||||
-rw-r--r-- | val.c | 40 | ||||
-rw-r--r-- | val.h | 50 | ||||
-rw-r--r-- | vm.c | 9 |
7 files changed, 93 insertions, 33 deletions
@@ -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); } + } } @@ -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") @@ -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]* @@ -1 +1 @@ -(+ 6 (* 9 25)) +(+ "abc" (* 9 25)) @@ -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 "???"; } @@ -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 @@ -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))); \ |