1 /**************************************************************************/
2 /* */
3 /* OCaml */
4 /* */
5 /* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
6 /* */
7 /* Copyright 1996 Institut National de Recherche en Informatique et */
8 /* en Automatique. */
9 /* */
10 /* All rights reserved. This file is distributed under the terms of */
11 /* the GNU Lesser General Public License version 2.1, with the */
12 /* special exception on linking described in the file LICENSE. */
13 /* */
14 /**************************************************************************/
15
16 /* Based on public-domain code from Berkeley Yacc */
17
18 #include <string.h>
19 #include "defs.h"
20
21
22 bucket **symbol_table;
23 bucket *first_symbol;
24 bucket *last_symbol;
25
26
27 int
28 hash(char *name)
29 {
30 register char *s;
31 register int c, k;
32
33 assert(name && *name);
34 s = name;
35 k = *s;
36 while ((c = *++s))
37 k = (31*k + c) & (TABLE_SIZE - 1);
38
39 return (k);
40 }
41
42
43 bucket *
44 make_bucket(char *name)
45 {
46 register bucket *bp;
47
48 assert(name);
49 bp = (bucket *) MALLOC(sizeof(bucket));
50 if (bp == 0) no_space();
51 bp->link = 0;
52 bp->next = 0;
53 bp->name = MALLOC(strlen(name) + 1);
54 if (bp->name == 0) no_space();
55 bp->tag = 0;
56 bp->value = UNDEFINED;
57 bp->index = 0;
58 bp->prec = 0;
59 bp-> class = UNKNOWN;
60 bp->assoc = TOKEN;
61 bp->entry = 0;
62 bp->true_token = 0;
63
64 if (bp->name == 0) no_space();
65 strcpy(bp->name, name);
66
67 return (bp);
68 }
69
70
71 bucket *
72 lookup(char *name)
73 {
74 register bucket *bp, **bpp;
75
76 bpp = symbol_table + hash(name);
77 bp = *bpp;
78
79 while (bp)
80 {
81 if (strcmp(name, bp->name) == 0) return (bp);
82 bpp = &bp->link;
83 bp = *bpp;
84 }
85
86 *bpp = bp = make_bucket(name);
87 last_symbol->next = bp;
88 last_symbol = bp;
89
90 return (bp);
91 }
92
93
94 void create_symbol_table(void)
95 {
96 register int i;
97 register bucket *bp;
98
99 symbol_table = (bucket **) MALLOC(TABLE_SIZE*sizeof(bucket *));
100 if (symbol_table == 0) no_space();
101 for (i = 0; i < TABLE_SIZE; i++)
102 symbol_table[i] = 0;
103
104 bp = make_bucket("error");
105 bp->index = 1;
106 bp->class = TERM;
107
108 first_symbol = bp;
109 last_symbol = bp;
110 symbol_table[hash("error")] = bp;
111 }
112
113
114 void free_symbol_table(void)
115 {
116 FREE(symbol_table);
117 symbol_table = 0;
118 }
119
120
121 void free_symbols(void)
122 {
123 register bucket *p, *q;
124
125 for (p = first_symbol; p; p = q)
126 {
127 q = p->next;
128 FREE(p);
129 }
130 }
131