xref: /csrg-svn/old/dbx/keywords.c (revision 16949)
19664Slinton /* Copyright (c) 1982 Regents of the University of California */
29664Slinton 
3*16949Ssam static	char sccsid[] = "@(#)keywords.c	1.6 (Berkeley) 08/17/84";
49664Slinton 
59664Slinton /*
616928Ssam  * 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 
4616928Ssam #define KEYWORDHASH	101
4716928Ssam private Keyword hashtab[KEYWORDHASH];
4816928Ssam #define keyhash(n) ((((unsigned) n) >> 2) mod KEYWORDHASH)
499664Slinton 
5016928Ssam /*
5116928Ssam  * The alias table is virtually the same, just
5216928Ssam  * replace the token id with a string to which
5316928Ssam  * the alias expands.
5416928Ssam  */
5516928Ssam typedef struct Alias {
5616928Ssam      Name name;
5716928Ssam      Name expansion;
5816928Ssam      struct Alias *chain;
5916928Ssam } *Alias;
609664Slinton 
6116928Ssam #define	ALIASHASH	503
6216928Ssam private	Alias aliashashtab[ALIASHASH];
6316928Ssam #define aliashash(n) ((((unsigned) n) >> 2) mod ALIASHASH)
6416928Ssam 
659664Slinton /*
669664Slinton  * Enter all the reserved words into the keyword table.
679664Slinton  */
689664Slinton public enterkeywords()
699664Slinton {
709664Slinton     register Integer i;
719664Slinton 
7216928Ssam     for (i = ALIAS; i <= WHICH; i++)
7316928Ssam 	keyword(reserved[ord(i) - ord(ALIAS)], i);
7416928Ssam     keyword("set", ASSIGN);
7516928Ssam 
7616928Ssam     alias(identname("c", true), identname(keywdstring(CONT), true));
7716928Ssam     alias(identname("d", true), identname(keywdstring(DELETE), true));
7816928Ssam     alias(identname("h", true), identname(keywdstring(HELP), true));
7916928Ssam     alias(identname("e", true), identname(keywdstring(EDIT), true));
8016928Ssam     alias(identname("l", true), identname(keywdstring(LIST), true));
8116928Ssam     alias(identname("n", true), identname(keywdstring(NEXT), true));
8216928Ssam     alias(identname("p", true), identname(keywdstring(PRINT), true));
8316928Ssam     alias(identname("q", true), identname(keywdstring(QUIT), true));
8416928Ssam     alias(identname("r", true), identname(keywdstring(RUN), true));
8516928Ssam     alias(identname("s", true), identname(keywdstring(STEP), true));
8616928Ssam     alias(identname("st", true), identname(keywdstring(STOP), true));
8716928Ssam     alias(identname("j", true), identname(keywdstring(STATUS), true));
8816928Ssam     alias(identname("t", true), identname(keywdstring(WHERE), true));
899664Slinton }
909664Slinton 
919664Slinton /*
9216928Ssam  * Deallocate the keyword and alias tables.
939664Slinton  */
949664Slinton public keywords_free()
959664Slinton {
969664Slinton     register Integer i;
979664Slinton     register Keyword k, nextk;
9816928Ssam     register Alias a, nexta;
999664Slinton 
10016928Ssam     for (i = 0; i < KEYWORDHASH; i++) {
10116928Ssam 	for (k = hashtab[i]; k != nil; k = nextk) {
1029664Slinton 	    nextk = k->chain;
1039664Slinton 	    dispose(k);
1049664Slinton 	}
1059664Slinton 	hashtab[i] = nil;
1069664Slinton     }
10716928Ssam     for (i = 0; i < ALIASHASH; i++) {
10816928Ssam 	for (a = aliashashtab[i]; a != nil; a = nexta) {
10916928Ssam 	    nexta = a->chain;
11016928Ssam 	    dispose(a);
11116928Ssam 	}
11216928Ssam 	aliashashtab[i] = nil;
11316928Ssam     }
1149664Slinton }
1159664Slinton 
1169664Slinton /*
11716928Ssam  * Enter a keyword into the name table.
11816928Ssam  * It is assumed to not be there already.
1199664Slinton  * The string is assumed to be statically allocated.
1209664Slinton  */
12116928Ssam private keyword(s, t)
1229664Slinton String s;
1239664Slinton Token t;
1249664Slinton {
1259664Slinton     register Keyword k;
12616928Ssam     Hashvalue h;
1279664Slinton     Name n;
1289664Slinton 
1299664Slinton     n = identname(s, true);
13016928Ssam     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 /*
14816928Ssam  * Return the token associated with a given keyword string.
14916928Ssam  * We assume that tokens cannot legitimately be nil (0).
1509664Slinton  */
1519664Slinton 
15216928Ssam public Token findkeyword(n)
1539664Slinton Name n;
1549664Slinton {
1559664Slinton     register Keyword k;
1569664Slinton 
15716928Ssam     for (k = hashtab[keyhash(n)]; k != nil && k->name != n; k = k->chain)
15816928Ssam 	;
15916928Ssam     return (k == nil ? nil : k->toknum);
16016611Ssam }
16116611Ssam 
16216928Ssam public String findalias(n)
16316611Ssam Name n;
16416611Ssam {
16516928Ssam     register Alias a;
16616611Ssam 
16716928Ssam     for (a = aliashashtab[aliashash(n)]; a != nil && a->name != n; a = a->chain)
16816928Ssam 	;
16916928Ssam     return (a == nil ? nil : ident(a->expansion));
1709664Slinton }
1719664Slinton 
1729664Slinton /*
1739664Slinton  * Create an alias.
1749664Slinton  */
17516928Ssam public enter_alias(cmd, p)
17616928Ssam Name cmd;
17716928Ssam Node p;
1789664Slinton {
1799664Slinton     Token t;
18016928Ssam     Name n;
1819664Slinton 
18216928Ssam     t = findkeyword(cmd);
18316928Ssam     if (t != nil) {
184*16949Ssam 	error("\"%s\" can't alias a command", ident(cmd));
18516928Ssam 	return;
1869664Slinton     }
18716928Ssam     if (p->op == O_SCON)
18816928Ssam 	n = identname(p->value.scon, true);
18916928Ssam     else
19016928Ssam 	n = identname(ident(p->value.name), true);
19116928Ssam     alias(cmd, n);
1929664Slinton }
1939664Slinton 
19416928Ssam private alias(cmd, n)
19516928Ssam Name cmd, n;
19616928Ssam {
19716928Ssam     register Alias a;
19816928Ssam     Hashvalue h;
19916928Ssam 
20016928Ssam     h = aliashash(cmd);
20116928Ssam     for (a = aliashashtab[h]; a != nil && a->name != cmd; a = a->chain)
20216928Ssam 	;
20316928Ssam     if (a != nil) {
204*16949Ssam 	/* interpret ``alias x x'' as ``unalias x'' */
205*16949Ssam 	if (streq(ident(cmd), ident(n)))
206*16949Ssam 	    unalias(h, a);
207*16949Ssam 	else
208*16949Ssam 	    a->expansion = n;
20916928Ssam 	return;
21016928Ssam     }
211*16949Ssam     if (!streq(ident(cmd), ident(n))) {		/* as above */
212*16949Ssam 	a = new(Alias);
213*16949Ssam 	a->name = cmd;
214*16949Ssam 	a->expansion = n;
215*16949Ssam 	a->chain = aliashashtab[h];
216*16949Ssam 	aliashashtab[h] = a;
217*16949Ssam     }
21816928Ssam }
21916928Ssam 
220*16949Ssam private unalias(h, a)
221*16949Ssam Alias a;
222*16949Ssam Hashvalue h;
223*16949Ssam {
224*16949Ssam     register Alias *ap;
225*16949Ssam 
226*16949Ssam     for (ap = &aliashashtab[h]; *ap != nil && *ap != a; ap = &(*ap)->chain)
227*16949Ssam 	;
228*16949Ssam     assert(*ap == a);
229*16949Ssam     *ap = a->chain;
230*16949Ssam     dispose(a);
231*16949Ssam }
232*16949Ssam 
2339664Slinton /*
2349664Slinton  * Print out an alias.
2359664Slinton  */
2369664Slinton public print_alias(cmd)
2379664Slinton Name cmd;
2389664Slinton {
23916928Ssam     register Alias a;
2409664Slinton     register Integer i;
24116928Ssam     String s;
2429664Slinton 
24316928Ssam     if (cmd != nil) {
24416928Ssam 	s = findalias(cmd);
245*16949Ssam 	if (s != nil)
246*16949Ssam 	    printf("%s\n", s);
24716928Ssam 	return;
24816928Ssam     }
24916928Ssam     /*
25016928Ssam      * Dump the alias table.
25116928Ssam      */
25216928Ssam     for (i = 0; i < ALIASHASH; i++) {
25316928Ssam 	for (a = aliashashtab[i]; a != nil; a = a->chain) {
25416928Ssam 	    if (isredirected())
25516928Ssam 		printf("alias ");
25616928Ssam 	    printf("%s\t%s\n", ident(a->name), ident(a->expansion));
2579664Slinton 	}
2589664Slinton     }
2599664Slinton }
260