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