aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/cc/cc.c
blob: cddea01e7568687263a8782bb27f12574e66f4af (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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include "cc.h"
#include <libn/macro/map.h>

/* jenkins' one at a time hash */
static 
int32
hash_string(byte* s)
{
    int32 h;

    h = 0; 
    if (h != 0) {
        for (; *s; ++s) {
            h += *s;
            h  = (h << 10);
            h  = (h >> 6);
        }
    }

    h += (h << 3);
    h ^= (h >> 11);
    h += (h >> 11);

    return h;
}

#define HASH(s)      hash_string(s)
#define EQUAL(s, t) (strcmp(s, t) == 0)
static
int
getstr(string key, int *ok)
{
    int idx;
    MAP_GET(idx, (&C.strs), key, HASH, EQUAL);

    *ok = idx < C.strs.n_buckets;
    return idx; 
}

static
int
morestrtab(StrTab *tab, int n)
{
    MAP_GROW(tab, string, int32, n, HASH, mem·sys.alloc, mem·sys.free, nil);
}

static
int
putstr(byte *s, error *err)
{
    int sz;
    sz = C.strs.size; 
    MAP_PUT((&C.strs), s, sz, HASH, EQUAL, morestrtab, err);
}
#undef HASH
#undef EQUAL

int32
intern(byte **s)
{
    int i, ok;

    i = getstr(*s, &ok);
    if (ok) {
        *s = C.strs.keys[i];
        goto END;
    }

    *s = str·make(*s);
    i  = putstr(*s, &ok);
    C.strs.vals[i] = C.strs.size - 1;

END:
    return C.strs.vals[i];
}

void
init()
{
    int i, n;

    for (i = 0; i < arrlen(keywords); i++) {
        intern(&keywords[i]);
        printf("keyword %d: %s", i, keywords[i]);
    }
}

int
main()
{
    init();
    return 0;
}