summaryrefslogtreecommitdiff
path: root/src/runtime/c/gu/intern.c
blob: 35eaa1c5f338874ab1f4cdb8eeac22508b211791 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include "intern.h"

struct GuIntern {
	GuPool* str_pool;
	GuMap* map;
};

GuIntern*
gu_new_intern(GuPool* str_pool, GuPool* pool)
{
	GuIntern* intern = gu_new(GuIntern, pool);
	intern->str_pool = str_pool;
	intern->map = gu_new_set(const char*, gu_str_hasher, pool);
	return intern;
}

const char*
gu_intern_str(GuIntern* intern, const char* cstr)
{
	const char* const* strp = gu_map_find_key(intern->map, &cstr);
	if (strp) {
		return *strp;
	}
	const char* str = gu_strdup(cstr, intern->str_pool);
	gu_map_insert(intern->map, &str);
	return str;
}




struct GuSymTable {
	GuPool* sym_pool;
	GuMap* map;
};

GuSymTable*
gu_new_symtable(GuPool* sym_pool, GuPool* pool)
{
	GuSymTable* tab = gu_new(GuSymTable, pool);
	tab->sym_pool = sym_pool;
	tab->map = gu_new_set(GuSymbol, gu_string_hasher, pool);
	return tab;
}

GuSymbol
gu_symtable_intern(GuSymTable* tab, GuString string)
{
	if (gu_string_is_stable(string)) {
		return string;
	}
	const GuSymbol* symp = gu_map_find_key(tab->map, &string);
	if (symp) {
		return *symp;
	}
	GuSymbol sym = gu_string_copy(string, tab->sym_pool);
	gu_map_insert(tab->map, &sym);
	return sym;
}