symbol interning
This commit is contained in:
parent
5e6bc2679d
commit
d64b0f0a6f
6 changed files with 174 additions and 10 deletions
81
sym.c
Normal file
81
sym.c
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "wscm.h"
|
||||
|
||||
St syms = {0, 0, NULL};
|
||||
|
||||
static S *findsym(const char *str, Z len, U32 hash) {
|
||||
if (syms.capacity == 0)
|
||||
return NULL;
|
||||
|
||||
Z ix = hash % syms.capacity;
|
||||
for (Z i = 0; i < syms.capacity; i++) {
|
||||
S *s = syms.data[ix];
|
||||
if (!s)
|
||||
return NULL;
|
||||
if (s->hash == hash && s->len == len)
|
||||
return s;
|
||||
ix = (ix + 1) % syms.capacity;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void symtabresize(void) {
|
||||
Z cap = syms.capacity;
|
||||
if (cap == 0) {
|
||||
syms.capacity = 16;
|
||||
} else {
|
||||
syms.capacity *= 2;
|
||||
}
|
||||
S **nb = calloc(syms.capacity, sizeof(S *));
|
||||
for (Z i = 0; i < cap; i++) {
|
||||
if (syms.data[i]) {
|
||||
S *s = syms.data[i];
|
||||
Z ix = s->hash % syms.capacity;
|
||||
while (nb[ix])
|
||||
ix = (ix + 1) % syms.capacity;
|
||||
nb[ix] = s;
|
||||
}
|
||||
}
|
||||
if (syms.data != NULL)
|
||||
free(syms.data);
|
||||
syms.data = nb;
|
||||
}
|
||||
|
||||
U32 hashstring(const char *data, Z len) {
|
||||
U32 hash = 2166136261u;
|
||||
for (Z i = 0; i < len; i++) {
|
||||
hash ^= (uint8_t)data[i];
|
||||
hash *= 16777619u;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
S *intern(const char *str, I len) {
|
||||
if (len < 0)
|
||||
len = strlen(str);
|
||||
|
||||
U32 hash = hashstring(str, len);
|
||||
S *s = findsym(str, len, hash);
|
||||
if (s)
|
||||
return s;
|
||||
|
||||
s = malloc(sizeof(S));
|
||||
s->data = malloc(len);
|
||||
memcpy(s->data, str, len);
|
||||
s->len = len;
|
||||
s->hash = hash;
|
||||
|
||||
if (syms.count + 1 > syms.capacity)
|
||||
symtabresize();
|
||||
|
||||
Z ix = hash % syms.capacity;
|
||||
while (syms.data[ix])
|
||||
ix = (ix + 1) % syms.capacity;
|
||||
|
||||
syms.data[ix] = s;
|
||||
syms.count++;
|
||||
|
||||
return s;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue