aboutsummaryrefslogtreecommitdiff
path: root/src/symtab.c
blob: 8fcba3c49d65297ec1154b688c580c52931044c0 (plain) (blame)
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
#include <stddef.h>
#include <stdint.h>

#include "alloc.h"
#include "symtab.h"
#include "strview.h"

struct symtab {
	symtab_t *child[4];
	strview_t key;
	symval_t val;
};

struct typetab {
	typetab_t *child[4];
	strview_t key;
	type_t *val;
};

symval_t *
symtab_insert(symtab_t **m, strview_t sv, arena_t *a)
{
	for (uint64_t h = strview_hash(sv); *m; h <<= 2) {
		if (strview_eq(sv, (*m)->key))
			return &(*m)->val;
		m = &(*m)->child[h >> 62];
	}
	if (a == NULL)
		return NULL;
	*m = arena_new(a, symtab_t, 1);
	(*m)->key = sv;
	return &(*m)->val;
}

type_t **
typetab_insert(typetab_t **m, strview_t sv, arena_t *a)
{
	for (uint64_t h = strview_hash(sv); *m; h <<= 2) {
		if (strview_eq(sv, (*m)->key))
			return &(*m)->val;
		m = &(*m)->child[h >> 62];
	}
	if (a == NULL)
		return NULL;
	*m = arena_new(a, typetab_t, 1);
	(*m)->key = sv;
	return &(*m)->val;
}