#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_copy_cstr(State *S, char *str) { size_t len = strlen(str); return objstring_copy(S, str, len); } 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; } ObjFunc *objfunc_new(State *S, uint8_t arity) { ObjFunc *o = NEW_OBJ(S, ObjFunc, OTY_FUNC); o->ch = chunk_new(S); o->arity = arity; return o; } void print_val(Val v) { switch (v.ty) { case TY_NIL: printf("nil"); break; case TY_NUM: printf("%g",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; case OTY_FUNC: printf("[function Function]"); break; } break; } } void println_val(Val v) { print_val(v); putchar('\n'); } bool is_truthy(Val v) { if (IS_BOOL(v)) return AS_BOOL(v); if (IS_NIL(v)) return false; return true; } bool val_equal(Val a, Val b) { if (a.ty != b.ty) return false; switch (a.ty) { case TY_NIL: return true; case TY_NUM: return AS_NUM(a) == AS_NUM(b); case TY_BOOL: return AS_BOOL(a) == AS_BOOL(b); case TY_OBJ: return AS_OBJ(a) == AS_OBJ(b); default: return false; } } 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"; case OTY_FUNC: return "Func"; } break; } return "???"; }