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