xref: /freebsd/contrib/byacc/symtab.c (revision c9083b850aed19fff781fd82084e8308c9ae6df6)
1 /* $Id: symtab.c,v 1.11 2014/03/26 00:17:09 Tom.Shields 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 #if defined(YYBTYACC)
52     bp->args = -1;
53     bp->argnames = 0;
54     bp->argtags = 0;
55     bp->destructor = 0;
56 #endif
57     strcpy(bp->name, name);
58 
59     return (bp);
60 }
61 
62 bucket *
63 lookup(const char *name)
64 {
65     bucket *bp, **bpp;
66 
67     bpp = symbol_table + hash(name);
68     bp = *bpp;
69 
70     while (bp)
71     {
72 	if (strcmp(name, bp->name) == 0)
73 	    return (bp);
74 	bpp = &bp->link;
75 	bp = *bpp;
76     }
77 
78     *bpp = bp = make_bucket(name);
79     last_symbol->next = bp;
80     last_symbol = bp;
81 
82     return (bp);
83 }
84 
85 void
86 create_symbol_table(void)
87 {
88     int i;
89     bucket *bp;
90 
91     symbol_table = TMALLOC(bucket *, TABLE_SIZE);
92     NO_SPACE(symbol_table);
93 
94     for (i = 0; i < TABLE_SIZE; i++)
95 	symbol_table[i] = 0;
96 
97     bp = make_bucket("error");
98     bp->index = 1;
99     bp->class = TERM;
100 
101     first_symbol = bp;
102     last_symbol = bp;
103     symbol_table[hash("error")] = bp;
104 }
105 
106 void
107 free_symbol_table(void)
108 {
109     FREE(symbol_table);
110     symbol_table = 0;
111 }
112 
113 void
114 free_symbols(void)
115 {
116     bucket *p, *q;
117 
118     for (p = first_symbol; p; p = q)
119     {
120 	q = p->next;
121 	FREE(p);
122     }
123 }
124