19664Slinton /* Copyright (c) 1982 Regents of the University of California */ 29664Slinton 3*16611Ssam static char sccsid[] = "@(#)keywords.c 1.3 5/18/83"; 49664Slinton 5*16611Ssam static char rcsid[] = "$Header: keywords.c,v 1.3 84/03/27 10:21:05 linton Exp $"; 6*16611Ssam 79664Slinton /* 89664Slinton * Keyword management. 99664Slinton */ 109664Slinton 119664Slinton #include "defs.h" 129664Slinton #include "keywords.h" 139664Slinton #include "scanner.h" 149664Slinton #include "names.h" 159664Slinton #include "symbols.h" 169664Slinton #include "tree.h" 179664Slinton #include "y.tab.h" 189664Slinton 199664Slinton #ifndef public 209664Slinton #include "scanner.h" 219664Slinton #endif 229664Slinton 239664Slinton private String reserved[] ={ 249664Slinton "alias", "and", "assign", "at", "call", "catch", "cont", 25*16611Ssam "debug", "delete", "div", "down", "dump", "edit", "file", "func", 269664Slinton "gripe", "help", "if", "ignore", "in", 279664Slinton "list", "mod", "next", "nexti", "nil", "not", "or", 28*16611Ssam "print", "psym", "quit", "rerun", "return", "run", 299664Slinton "sh", "skip", "source", "status", "step", "stepi", 30*16611Ssam "stop", "stopi", "trace", "tracei", "up", 319664Slinton "use", "whatis", "when", "where", "whereis", "which", 329664Slinton "INT", "REAL", "NAME", "STRING", 339664Slinton "LFORMER", "RFORMER", "#^", "->" 349664Slinton }; 359664Slinton 369664Slinton /* 379664Slinton * The keyword table is a traditional hash table with collisions 389664Slinton * resolved by chaining. 399664Slinton */ 409664Slinton 419664Slinton #define HASHTABLESIZE 503 429664Slinton 439664Slinton typedef struct Keyword { 449664Slinton Name name; 459664Slinton Token toknum : 16; 469664Slinton Boolean isalias : 16; 479664Slinton struct Keyword *chain; 489664Slinton } *Keyword; 499664Slinton 509664Slinton typedef unsigned int Hashvalue; 519664Slinton 529664Slinton private Keyword hashtab[HASHTABLESIZE]; 539664Slinton 549664Slinton #define hash(n) ((((unsigned) n) >> 2) mod HASHTABLESIZE) 559664Slinton 569664Slinton /* 579664Slinton * Enter all the reserved words into the keyword table. 589664Slinton */ 599664Slinton 609664Slinton public enterkeywords() 619664Slinton { 629664Slinton register Integer i; 639664Slinton 649664Slinton for (i = ALIAS; i <= WHICH; i++) { 659664Slinton keyword(reserved[ord(i) - ord(ALIAS)], i, false); 669664Slinton } 679664Slinton keyword("set", ASSIGN, false); 68*16611Ssam keyword("c", CONT, true); 69*16611Ssam keyword("d", DELETE, true); 70*16611Ssam keyword("h", HELP, true); 71*16611Ssam keyword("e", EDIT, true); 72*16611Ssam keyword("l", LIST, true); 73*16611Ssam keyword("n", NEXT, true); 74*16611Ssam keyword("p", PRINT, true); 75*16611Ssam keyword("q", QUIT, true); 76*16611Ssam keyword("r", RUN, true); 77*16611Ssam keyword("s", STEP, true); 78*16611Ssam keyword("st", STOP, true); 79*16611Ssam keyword("j", STATUS, true); 80*16611Ssam keyword("t", WHERE, true); 819664Slinton } 829664Slinton 839664Slinton /* 849664Slinton * Deallocate the keyword table. 859664Slinton */ 869664Slinton 879664Slinton public keywords_free() 889664Slinton { 899664Slinton register Integer i; 909664Slinton register Keyword k, nextk; 919664Slinton 929664Slinton for (i = 0; i < HASHTABLESIZE; i++) { 939664Slinton k = hashtab[i]; 949664Slinton while (k != nil) { 959664Slinton nextk = k->chain; 969664Slinton dispose(k); 979664Slinton k = nextk; 989664Slinton } 999664Slinton hashtab[i] = nil; 1009664Slinton } 1019664Slinton } 1029664Slinton 1039664Slinton /* 1049664Slinton * Enter a keyword into the name table. It is assumed to not be there already. 1059664Slinton * The string is assumed to be statically allocated. 1069664Slinton */ 1079664Slinton 1089664Slinton private keyword(s, t, isalias) 1099664Slinton String s; 1109664Slinton Token t; 1119664Slinton Boolean isalias; 1129664Slinton { 1139664Slinton register Hashvalue h; 1149664Slinton register Keyword k; 1159664Slinton Name n; 1169664Slinton 1179664Slinton n = identname(s, true); 1189664Slinton h = hash(n); 1199664Slinton k = new(Keyword); 1209664Slinton k->name = n; 1219664Slinton k->toknum = t; 1229664Slinton k->isalias = isalias; 1239664Slinton k->chain = hashtab[h]; 1249664Slinton hashtab[h] = k; 1259664Slinton } 1269664Slinton 1279664Slinton /* 1289664Slinton * Return the string associated with a token corresponding to a keyword. 1299664Slinton */ 1309664Slinton 1319664Slinton public String keywdstring(t) 1329664Slinton Token t; 1339664Slinton { 1349664Slinton return reserved[ord(t) - ord(ALIAS)]; 1359664Slinton } 1369664Slinton 1379664Slinton /* 138*16611Ssam * Find the keyword associated with the given string. 1399664Slinton */ 1409664Slinton 141*16611Ssam private Keyword kwlookup (n) 1429664Slinton Name n; 1439664Slinton { 144*16611Ssam Hashvalue h; 1459664Slinton register Keyword k; 1469664Slinton 1479664Slinton h = hash(n); 1489664Slinton k = hashtab[h]; 1499664Slinton while (k != nil and k->name != n) { 1509664Slinton k = k->chain; 1519664Slinton } 152*16611Ssam return k; 153*16611Ssam } 154*16611Ssam 155*16611Ssam /* 156*16611Ssam * Return the token associated with a given keyword string. 157*16611Ssam * We assume that tokens cannot legitimately be nil (0). 158*16611Ssam */ 159*16611Ssam 160*16611Ssam public Token findkeyword(n) 161*16611Ssam Name n; 162*16611Ssam { 163*16611Ssam Keyword k; 164*16611Ssam Token t; 165*16611Ssam 166*16611Ssam k = kwlookup(n); 1679664Slinton if (k == nil) { 1689664Slinton t = nil; 1699664Slinton } else { 1709664Slinton t = k->toknum; 1719664Slinton } 1729664Slinton return t; 1739664Slinton } 1749664Slinton 1759664Slinton /* 1769664Slinton * Create an alias. 1779664Slinton */ 1789664Slinton 1799664Slinton public enter_alias(newcmd, oldcmd) 1809664Slinton Name newcmd; 1819664Slinton Name oldcmd; 1829664Slinton { 1839664Slinton Token t; 184*16611Ssam Keyword k; 1859664Slinton 1869664Slinton t = findkeyword(oldcmd); 1879664Slinton if (t == nil) { 1889664Slinton error("\"%s\" is not a command", ident(oldcmd)); 1899664Slinton } else { 190*16611Ssam k = kwlookup(newcmd); 191*16611Ssam if (k == nil) { 192*16611Ssam keyword(ident(newcmd), t, true); 193*16611Ssam } else { 194*16611Ssam k->toknum = t; 195*16611Ssam } 1969664Slinton } 1979664Slinton } 1989664Slinton 1999664Slinton /* 2009664Slinton * Print out an alias. 2019664Slinton */ 2029664Slinton 2039664Slinton public print_alias(cmd) 2049664Slinton Name cmd; 2059664Slinton { 2069664Slinton register Keyword k; 2079664Slinton register Integer i; 2089664Slinton Token t; 2099664Slinton 2109664Slinton if (cmd == nil) { 2119664Slinton for (i = 0; i < HASHTABLESIZE; i++) { 2129664Slinton for (k = hashtab[i]; k != nil; k = k->chain) { 2139664Slinton if (k->isalias) { 2149664Slinton if (isredirected()) { 2159664Slinton printf("alias "); 2169664Slinton } 2179664Slinton printf("%s\t%s\n", ident(k->name), keywdstring(k->toknum)); 2189664Slinton } 2199664Slinton } 2209664Slinton } 2219664Slinton } else { 2229664Slinton t = findkeyword(cmd); 2239664Slinton if (t == nil) { 2249664Slinton printf("\n"); 2259664Slinton } else { 2269664Slinton printf("%s\n", keywdstring(t)); 2279664Slinton } 2289664Slinton } 2299664Slinton } 230