xref: /csrg-svn/old/dbx/keywords.c (revision 16928)
1 /* Copyright (c) 1982 Regents of the University of California */
2 
3 static	char sccsid[] = "@(#)keywords.c	1.5 (Berkeley) 08/12/84";
4 
5 /*
6  * Keyword and alias management.
7  */
8 
9 #include "defs.h"
10 #include "keywords.h"
11 #include "scanner.h"
12 #include "names.h"
13 #include "symbols.h"
14 #include "tree.h"
15 #include "y.tab.h"
16 
17 #ifndef public
18 #include "scanner.h"
19 #endif
20 
21 private String reserved[] ={
22     "alias", "and", "assign", "at", "call", "catch", "cont",
23     "debug", "delete", "div", "down", "dump", "edit", "file", "func",
24     "gripe", "help", "if", "ignore", "in",
25     "list", "mod", "next", "nexti", "nil", "not", "or",
26     "print", "psym", "quit", "rerun", "return", "run",
27     "sh", "skip", "source", "status", "step", "stepi",
28     "stop", "stopi", "trace", "tracei", "up",
29     "use", "whatis", "when", "where", "whereis", "which",
30     "INT", "REAL", "NAME", "STRING",
31     "LFORMER", "RFORMER", "#^", "->"
32 };
33 
34 /*
35  * The keyword table is a traditional hash table with collisions
36  * resolved by chaining.
37  */
38 typedef struct Keyword {
39     Name name;
40     Token toknum : 16;
41     struct Keyword *chain;
42 } *Keyword;
43 
44 typedef unsigned int Hashvalue;
45 
46 #define KEYWORDHASH	101
47 private Keyword hashtab[KEYWORDHASH];
48 #define keyhash(n) ((((unsigned) n) >> 2) mod KEYWORDHASH)
49 
50 /*
51  * The alias table is virtually the same, just
52  * replace the token id with a string to which
53  * the alias expands.
54  */
55 typedef struct Alias {
56      Name name;
57      Name expansion;
58      struct Alias *chain;
59 } *Alias;
60 
61 #define	ALIASHASH	503
62 private	Alias aliashashtab[ALIASHASH];
63 #define aliashash(n) ((((unsigned) n) >> 2) mod ALIASHASH)
64 
65 /*
66  * Enter all the reserved words into the keyword table.
67  */
68 public enterkeywords()
69 {
70     register Integer i;
71 
72     for (i = ALIAS; i <= WHICH; i++)
73 	keyword(reserved[ord(i) - ord(ALIAS)], i);
74     keyword("set", ASSIGN);
75 
76     alias(identname("c", true), identname(keywdstring(CONT), true));
77     alias(identname("d", true), identname(keywdstring(DELETE), true));
78     alias(identname("h", true), identname(keywdstring(HELP), true));
79     alias(identname("e", true), identname(keywdstring(EDIT), true));
80     alias(identname("l", true), identname(keywdstring(LIST), true));
81     alias(identname("n", true), identname(keywdstring(NEXT), true));
82     alias(identname("p", true), identname(keywdstring(PRINT), true));
83     alias(identname("q", true), identname(keywdstring(QUIT), true));
84     alias(identname("r", true), identname(keywdstring(RUN), true));
85     alias(identname("s", true), identname(keywdstring(STEP), true));
86     alias(identname("st", true), identname(keywdstring(STOP), true));
87     alias(identname("j", true), identname(keywdstring(STATUS), true));
88     alias(identname("t", true), identname(keywdstring(WHERE), true));
89 }
90 
91 /*
92  * Deallocate the keyword and alias tables.
93  */
94 public keywords_free()
95 {
96     register Integer i;
97     register Keyword k, nextk;
98     register Alias a, nexta;
99 
100     for (i = 0; i < KEYWORDHASH; i++) {
101 	for (k = hashtab[i]; k != nil; k = nextk) {
102 	    nextk = k->chain;
103 	    dispose(k);
104 	}
105 	hashtab[i] = nil;
106     }
107     for (i = 0; i < ALIASHASH; i++) {
108 	for (a = aliashashtab[i]; a != nil; a = nexta) {
109 	    nexta = a->chain;
110 	    dispose(a);
111 	}
112 	aliashashtab[i] = nil;
113     }
114 }
115 
116 /*
117  * Enter a keyword into the name table.
118  * It is assumed to not be there already.
119  * The string is assumed to be statically allocated.
120  */
121 private keyword(s, t)
122 String s;
123 Token t;
124 {
125     register Keyword k;
126     Hashvalue h;
127     Name n;
128 
129     n = identname(s, true);
130     h = keyhash(n);
131     k = new(Keyword);
132     k->name = n;
133     k->toknum = t;
134     k->chain = hashtab[h];
135     hashtab[h] = k;
136 }
137 
138 /*
139  * Return the string associated with a token corresponding to a keyword.
140  */
141 public String keywdstring(t)
142 Token t;
143 {
144     return reserved[ord(t) - ord(ALIAS)];
145 }
146 
147 /*
148  * Return the token associated with a given keyword string.
149  * We assume that tokens cannot legitimately be nil (0).
150  */
151 
152 public Token findkeyword(n)
153 Name n;
154 {
155     register Keyword k;
156 
157     for (k = hashtab[keyhash(n)]; k != nil && k->name != n; k = k->chain)
158 	;
159     return (k == nil ? nil : k->toknum);
160 }
161 
162 public String findalias(n)
163 Name n;
164 {
165     register Alias a;
166 
167     for (a = aliashashtab[aliashash(n)]; a != nil && a->name != n; a = a->chain)
168 	;
169     return (a == nil ? nil : ident(a->expansion));
170 }
171 
172 /*
173  * Create an alias.
174  */
175 public enter_alias(cmd, p)
176 Name cmd;
177 Node p;
178 {
179     Token t;
180     Name n;
181 
182     t = findkeyword(cmd);
183     if (t != nil) {
184 	error("\"%s\" can't redefine a command", ident(cmd));
185 	return;
186     }
187     if (p->op == O_SCON)
188 	n = identname(p->value.scon, true);
189     else
190 	n = identname(ident(p->value.name), true);
191     alias(cmd, n);
192 }
193 
194 private alias(cmd, n)
195 Name cmd, n;
196 {
197     register Alias a;
198     Hashvalue h;
199 
200     h = aliashash(cmd);
201     for (a = aliashashtab[h]; a != nil && a->name != cmd; a = a->chain)
202 	;
203     if (a != nil) {
204 	a->expansion = n;
205 	return;
206     }
207     a = new(Alias);
208     a->name = cmd;
209     a->expansion = n;
210     a->chain = aliashashtab[h];
211     aliashashtab[h] = a;
212 }
213 
214 /*
215  * Print out an alias.
216  */
217 public print_alias(cmd)
218 Name cmd;
219 {
220     register Alias a;
221     register Integer i;
222     String s;
223 
224     if (cmd != nil) {
225 	s = findalias(cmd);
226 	printf(s == nil ? "\n" : "%s\n", s);
227 	return;
228     }
229     /*
230      * Dump the alias table.
231      */
232     for (i = 0; i < ALIASHASH; i++) {
233 	for (a = aliashashtab[i]; a != nil; a = a->chain) {
234 	    if (isredirected())
235 		printf("alias ");
236 	    printf("%s\t%s\n", ident(a->name), ident(a->expansion));
237 	}
238     }
239 }
240