xref: /csrg-svn/old/dbx/keywords.c (revision 16928)
19664Slinton /* Copyright (c) 1982 Regents of the University of California */
29664Slinton 
3*16928Ssam static	char sccsid[] = "@(#)keywords.c	1.5 (Berkeley) 08/12/84";
49664Slinton 
59664Slinton /*
6*16928Ssam  * Keyword and alias management.
79664Slinton  */
89664Slinton 
99664Slinton #include "defs.h"
109664Slinton #include "keywords.h"
119664Slinton #include "scanner.h"
129664Slinton #include "names.h"
139664Slinton #include "symbols.h"
149664Slinton #include "tree.h"
159664Slinton #include "y.tab.h"
169664Slinton 
179664Slinton #ifndef public
189664Slinton #include "scanner.h"
199664Slinton #endif
209664Slinton 
219664Slinton private String reserved[] ={
229664Slinton     "alias", "and", "assign", "at", "call", "catch", "cont",
2316611Ssam     "debug", "delete", "div", "down", "dump", "edit", "file", "func",
249664Slinton     "gripe", "help", "if", "ignore", "in",
259664Slinton     "list", "mod", "next", "nexti", "nil", "not", "or",
2616611Ssam     "print", "psym", "quit", "rerun", "return", "run",
279664Slinton     "sh", "skip", "source", "status", "step", "stepi",
2816611Ssam     "stop", "stopi", "trace", "tracei", "up",
299664Slinton     "use", "whatis", "when", "where", "whereis", "which",
309664Slinton     "INT", "REAL", "NAME", "STRING",
319664Slinton     "LFORMER", "RFORMER", "#^", "->"
329664Slinton };
339664Slinton 
349664Slinton /*
359664Slinton  * The keyword table is a traditional hash table with collisions
369664Slinton  * resolved by chaining.
379664Slinton  */
389664Slinton typedef struct Keyword {
399664Slinton     Name name;
409664Slinton     Token toknum : 16;
419664Slinton     struct Keyword *chain;
429664Slinton } *Keyword;
439664Slinton 
449664Slinton typedef unsigned int Hashvalue;
459664Slinton 
46*16928Ssam #define KEYWORDHASH	101
47*16928Ssam private Keyword hashtab[KEYWORDHASH];
48*16928Ssam #define keyhash(n) ((((unsigned) n) >> 2) mod KEYWORDHASH)
499664Slinton 
50*16928Ssam /*
51*16928Ssam  * The alias table is virtually the same, just
52*16928Ssam  * replace the token id with a string to which
53*16928Ssam  * the alias expands.
54*16928Ssam  */
55*16928Ssam typedef struct Alias {
56*16928Ssam      Name name;
57*16928Ssam      Name expansion;
58*16928Ssam      struct Alias *chain;
59*16928Ssam } *Alias;
609664Slinton 
61*16928Ssam #define	ALIASHASH	503
62*16928Ssam private	Alias aliashashtab[ALIASHASH];
63*16928Ssam #define aliashash(n) ((((unsigned) n) >> 2) mod ALIASHASH)
64*16928Ssam 
659664Slinton /*
669664Slinton  * Enter all the reserved words into the keyword table.
679664Slinton  */
689664Slinton public enterkeywords()
699664Slinton {
709664Slinton     register Integer i;
719664Slinton 
72*16928Ssam     for (i = ALIAS; i <= WHICH; i++)
73*16928Ssam 	keyword(reserved[ord(i) - ord(ALIAS)], i);
74*16928Ssam     keyword("set", ASSIGN);
75*16928Ssam 
76*16928Ssam     alias(identname("c", true), identname(keywdstring(CONT), true));
77*16928Ssam     alias(identname("d", true), identname(keywdstring(DELETE), true));
78*16928Ssam     alias(identname("h", true), identname(keywdstring(HELP), true));
79*16928Ssam     alias(identname("e", true), identname(keywdstring(EDIT), true));
80*16928Ssam     alias(identname("l", true), identname(keywdstring(LIST), true));
81*16928Ssam     alias(identname("n", true), identname(keywdstring(NEXT), true));
82*16928Ssam     alias(identname("p", true), identname(keywdstring(PRINT), true));
83*16928Ssam     alias(identname("q", true), identname(keywdstring(QUIT), true));
84*16928Ssam     alias(identname("r", true), identname(keywdstring(RUN), true));
85*16928Ssam     alias(identname("s", true), identname(keywdstring(STEP), true));
86*16928Ssam     alias(identname("st", true), identname(keywdstring(STOP), true));
87*16928Ssam     alias(identname("j", true), identname(keywdstring(STATUS), true));
88*16928Ssam     alias(identname("t", true), identname(keywdstring(WHERE), true));
899664Slinton }
909664Slinton 
919664Slinton /*
92*16928Ssam  * Deallocate the keyword and alias tables.
939664Slinton  */
949664Slinton public keywords_free()
959664Slinton {
969664Slinton     register Integer i;
979664Slinton     register Keyword k, nextk;
98*16928Ssam     register Alias a, nexta;
999664Slinton 
100*16928Ssam     for (i = 0; i < KEYWORDHASH; i++) {
101*16928Ssam 	for (k = hashtab[i]; k != nil; k = nextk) {
1029664Slinton 	    nextk = k->chain;
1039664Slinton 	    dispose(k);
1049664Slinton 	}
1059664Slinton 	hashtab[i] = nil;
1069664Slinton     }
107*16928Ssam     for (i = 0; i < ALIASHASH; i++) {
108*16928Ssam 	for (a = aliashashtab[i]; a != nil; a = nexta) {
109*16928Ssam 	    nexta = a->chain;
110*16928Ssam 	    dispose(a);
111*16928Ssam 	}
112*16928Ssam 	aliashashtab[i] = nil;
113*16928Ssam     }
1149664Slinton }
1159664Slinton 
1169664Slinton /*
117*16928Ssam  * Enter a keyword into the name table.
118*16928Ssam  * It is assumed to not be there already.
1199664Slinton  * The string is assumed to be statically allocated.
1209664Slinton  */
121*16928Ssam private keyword(s, t)
1229664Slinton String s;
1239664Slinton Token t;
1249664Slinton {
1259664Slinton     register Keyword k;
126*16928Ssam     Hashvalue h;
1279664Slinton     Name n;
1289664Slinton 
1299664Slinton     n = identname(s, true);
130*16928Ssam     h = keyhash(n);
1319664Slinton     k = new(Keyword);
1329664Slinton     k->name = n;
1339664Slinton     k->toknum = t;
1349664Slinton     k->chain = hashtab[h];
1359664Slinton     hashtab[h] = k;
1369664Slinton }
1379664Slinton 
1389664Slinton /*
1399664Slinton  * Return the string associated with a token corresponding to a keyword.
1409664Slinton  */
1419664Slinton public String keywdstring(t)
1429664Slinton Token t;
1439664Slinton {
1449664Slinton     return reserved[ord(t) - ord(ALIAS)];
1459664Slinton }
1469664Slinton 
1479664Slinton /*
148*16928Ssam  * Return the token associated with a given keyword string.
149*16928Ssam  * We assume that tokens cannot legitimately be nil (0).
1509664Slinton  */
1519664Slinton 
152*16928Ssam public Token findkeyword(n)
1539664Slinton Name n;
1549664Slinton {
1559664Slinton     register Keyword k;
1569664Slinton 
157*16928Ssam     for (k = hashtab[keyhash(n)]; k != nil && k->name != n; k = k->chain)
158*16928Ssam 	;
159*16928Ssam     return (k == nil ? nil : k->toknum);
16016611Ssam }
16116611Ssam 
162*16928Ssam public String findalias(n)
16316611Ssam Name n;
16416611Ssam {
165*16928Ssam     register Alias a;
16616611Ssam 
167*16928Ssam     for (a = aliashashtab[aliashash(n)]; a != nil && a->name != n; a = a->chain)
168*16928Ssam 	;
169*16928Ssam     return (a == nil ? nil : ident(a->expansion));
1709664Slinton }
1719664Slinton 
1729664Slinton /*
1739664Slinton  * Create an alias.
1749664Slinton  */
175*16928Ssam public enter_alias(cmd, p)
176*16928Ssam Name cmd;
177*16928Ssam Node p;
1789664Slinton {
1799664Slinton     Token t;
180*16928Ssam     Name n;
1819664Slinton 
182*16928Ssam     t = findkeyword(cmd);
183*16928Ssam     if (t != nil) {
184*16928Ssam 	error("\"%s\" can't redefine a command", ident(cmd));
185*16928Ssam 	return;
1869664Slinton     }
187*16928Ssam     if (p->op == O_SCON)
188*16928Ssam 	n = identname(p->value.scon, true);
189*16928Ssam     else
190*16928Ssam 	n = identname(ident(p->value.name), true);
191*16928Ssam     alias(cmd, n);
1929664Slinton }
1939664Slinton 
194*16928Ssam private alias(cmd, n)
195*16928Ssam Name cmd, n;
196*16928Ssam {
197*16928Ssam     register Alias a;
198*16928Ssam     Hashvalue h;
199*16928Ssam 
200*16928Ssam     h = aliashash(cmd);
201*16928Ssam     for (a = aliashashtab[h]; a != nil && a->name != cmd; a = a->chain)
202*16928Ssam 	;
203*16928Ssam     if (a != nil) {
204*16928Ssam 	a->expansion = n;
205*16928Ssam 	return;
206*16928Ssam     }
207*16928Ssam     a = new(Alias);
208*16928Ssam     a->name = cmd;
209*16928Ssam     a->expansion = n;
210*16928Ssam     a->chain = aliashashtab[h];
211*16928Ssam     aliashashtab[h] = a;
212*16928Ssam }
213*16928Ssam 
2149664Slinton /*
2159664Slinton  * Print out an alias.
2169664Slinton  */
2179664Slinton public print_alias(cmd)
2189664Slinton Name cmd;
2199664Slinton {
220*16928Ssam     register Alias a;
2219664Slinton     register Integer i;
222*16928Ssam     String s;
2239664Slinton 
224*16928Ssam     if (cmd != nil) {
225*16928Ssam 	s = findalias(cmd);
226*16928Ssam 	printf(s == nil ? "\n" : "%s\n", s);
227*16928Ssam 	return;
228*16928Ssam     }
229*16928Ssam     /*
230*16928Ssam      * Dump the alias table.
231*16928Ssam      */
232*16928Ssam     for (i = 0; i < ALIASHASH; i++) {
233*16928Ssam 	for (a = aliashashtab[i]; a != nil; a = a->chain) {
234*16928Ssam 	    if (isredirected())
235*16928Ssam 		printf("alias ");
236*16928Ssam 	    printf("%s\t%s\n", ident(a->name), ident(a->expansion));
2379664Slinton 	}
2389664Slinton     }
2399664Slinton }
240