Merge branch 'vendor/BYACC'
[dragonfly.git] / contrib / byacc / symtab.c
1 /* $Id: symtab.c,v 1.10 2012/05/26 15:16:12 tom Exp $ */
2
3 #include "defs.h"
4
5 /* TABLE_SIZE is the number of entries in the symbol table. */
6 /* TABLE_SIZE must be a power of two.                       */
7
8 #define TABLE_SIZE 1024
9
10 static bucket **symbol_table = 0;
11 bucket *first_symbol;
12 bucket *last_symbol;
13
14 static int
15 hash(const char *name)
16 {
17     const char *s;
18     int c, k;
19
20     assert(name && *name);
21     s = name;
22     k = *s;
23     while ((c = *++s) != 0)
24         k = (31 * k + c) & (TABLE_SIZE - 1);
25
26     return (k);
27 }
28
29 bucket *
30 make_bucket(const char *name)
31 {
32     bucket *bp;
33
34     assert(name != 0);
35
36     bp = TMALLOC(bucket, 1);
37     NO_SPACE(bp);
38
39     bp->link = 0;
40     bp->next = 0;
41
42     bp->name = TMALLOC(char, strlen(name) + 1);
43     NO_SPACE(bp->name);
44
45     bp->tag = 0;
46     bp->value = UNDEFINED;
47     bp->index = 0;
48     bp->prec = 0;
49     bp->class = UNKNOWN;
50     bp->assoc = TOKEN;
51     strcpy(bp->name, name);
52
53     return (bp);
54 }
55
56 bucket *
57 lookup(const char *name)
58 {
59     bucket *bp, **bpp;
60
61     bpp = symbol_table + hash(name);
62     bp = *bpp;
63
64     while (bp)
65     {
66         if (strcmp(name, bp->name) == 0)
67             return (bp);
68         bpp = &bp->link;
69         bp = *bpp;
70     }
71
72     *bpp = bp = make_bucket(name);
73     last_symbol->next = bp;
74     last_symbol = bp;
75
76     return (bp);
77 }
78
79 void
80 create_symbol_table(void)
81 {
82     int i;
83     bucket *bp;
84
85     symbol_table = TMALLOC(bucket *, TABLE_SIZE);
86     NO_SPACE(symbol_table);
87
88     for (i = 0; i < TABLE_SIZE; i++)
89         symbol_table[i] = 0;
90
91     bp = make_bucket("error");
92     bp->index = 1;
93     bp->class = TERM;
94
95     first_symbol = bp;
96     last_symbol = bp;
97     symbol_table[hash("error")] = bp;
98 }
99
100 void
101 free_symbol_table(void)
102 {
103     FREE(symbol_table);
104     symbol_table = 0;
105 }
106
107 void
108 free_symbols(void)
109 {
110     bucket *p, *q;
111
112     for (p = first_symbol; p; p = q)
113     {
114         q = p->next;
115         FREE(p);
116     }
117 }