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