summaryrefslogtreecommitdiff
path: root/val.c
diff options
context:
space:
mode:
Diffstat (limited to 'val.c')
-rw-r--r--val.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/val.c b/val.c
index 22c92ce..40b7c5b 100644
--- a/val.c
+++ b/val.c
@@ -5,27 +5,44 @@
#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';
- ObjString *o = NEW_OBJ(S, ObjString, OTY_STRING);
- o->len = len;
- o->d = d;
- o->hash = hash(d, len);
- return o;
+ 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(src, len);
+ o->hash = hash;
+ ht_put(S, &S->strings, o, VAL_TRUE);
return o;
}
+
void print_val(Val v) {
switch (v.ty) {
case TY_NIL: