#include #include #include "val.h" #include "mem.h" #include "ht.h" static ObjString *objstring_create(State*, char*, size_t, uint32_t); ObjString *objstring_copy(State *S, char *src, size_t len) { uint32_t hash = hash_string(src, len); ObjString *interned = ht_findstring(S, &S->strings, src, len, hash); if (interned != NULL) return interned; char *d = NEW_ARR(S, char, 1+len); memcpy(d, src, len); d[len] = '\0'; return objstring_create(S, d, len, hash); } ObjString *objstring_take(State *S, char *src, size_t len) { uint32_t hash = hash_string(src, len); ObjString *interned = ht_findstring(S, &S->strings, src, len, hash); if (interned != NULL) { FREE_ARR(S, src, char, len+1); return interned; }; return objstring_create(S, src, len, hash); } static ObjString *objstring_create(State *S, char *src, size_t len, uint32_t hash) { // assumes already deduplicated // and data is already owned ObjString *o = NEW_OBJ(S, ObjString, OTY_STRING); o->len = len; o->d = src; o->hash = hash; ht_put(S, &S->strings, o, VAL_TRUE); return o; } void print_val(Val v) { switch (v.ty) { case TY_NIL: printf("nil"); break; case TY_NUM: printf("%f",AS_NUM(v)); break; 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'); } const char *typename_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 "???"; }