1 /* Copyright (c) 1982 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)keywords.c 1.5 (Berkeley) 08/12/84"; 4 5 /* 6 * Keyword and alias management. 7 */ 8 9 #include "defs.h" 10 #include "keywords.h" 11 #include "scanner.h" 12 #include "names.h" 13 #include "symbols.h" 14 #include "tree.h" 15 #include "y.tab.h" 16 17 #ifndef public 18 #include "scanner.h" 19 #endif 20 21 private String reserved[] ={ 22 "alias", "and", "assign", "at", "call", "catch", "cont", 23 "debug", "delete", "div", "down", "dump", "edit", "file", "func", 24 "gripe", "help", "if", "ignore", "in", 25 "list", "mod", "next", "nexti", "nil", "not", "or", 26 "print", "psym", "quit", "rerun", "return", "run", 27 "sh", "skip", "source", "status", "step", "stepi", 28 "stop", "stopi", "trace", "tracei", "up", 29 "use", "whatis", "when", "where", "whereis", "which", 30 "INT", "REAL", "NAME", "STRING", 31 "LFORMER", "RFORMER", "#^", "->" 32 }; 33 34 /* 35 * The keyword table is a traditional hash table with collisions 36 * resolved by chaining. 37 */ 38 typedef struct Keyword { 39 Name name; 40 Token toknum : 16; 41 struct Keyword *chain; 42 } *Keyword; 43 44 typedef unsigned int Hashvalue; 45 46 #define KEYWORDHASH 101 47 private Keyword hashtab[KEYWORDHASH]; 48 #define keyhash(n) ((((unsigned) n) >> 2) mod KEYWORDHASH) 49 50 /* 51 * The alias table is virtually the same, just 52 * replace the token id with a string to which 53 * the alias expands. 54 */ 55 typedef struct Alias { 56 Name name; 57 Name expansion; 58 struct Alias *chain; 59 } *Alias; 60 61 #define ALIASHASH 503 62 private Alias aliashashtab[ALIASHASH]; 63 #define aliashash(n) ((((unsigned) n) >> 2) mod ALIASHASH) 64 65 /* 66 * Enter all the reserved words into the keyword table. 67 */ 68 public enterkeywords() 69 { 70 register Integer i; 71 72 for (i = ALIAS; i <= WHICH; i++) 73 keyword(reserved[ord(i) - ord(ALIAS)], i); 74 keyword("set", ASSIGN); 75 76 alias(identname("c", true), identname(keywdstring(CONT), true)); 77 alias(identname("d", true), identname(keywdstring(DELETE), true)); 78 alias(identname("h", true), identname(keywdstring(HELP), true)); 79 alias(identname("e", true), identname(keywdstring(EDIT), true)); 80 alias(identname("l", true), identname(keywdstring(LIST), true)); 81 alias(identname("n", true), identname(keywdstring(NEXT), true)); 82 alias(identname("p", true), identname(keywdstring(PRINT), true)); 83 alias(identname("q", true), identname(keywdstring(QUIT), true)); 84 alias(identname("r", true), identname(keywdstring(RUN), true)); 85 alias(identname("s", true), identname(keywdstring(STEP), true)); 86 alias(identname("st", true), identname(keywdstring(STOP), true)); 87 alias(identname("j", true), identname(keywdstring(STATUS), true)); 88 alias(identname("t", true), identname(keywdstring(WHERE), true)); 89 } 90 91 /* 92 * Deallocate the keyword and alias tables. 93 */ 94 public keywords_free() 95 { 96 register Integer i; 97 register Keyword k, nextk; 98 register Alias a, nexta; 99 100 for (i = 0; i < KEYWORDHASH; i++) { 101 for (k = hashtab[i]; k != nil; k = nextk) { 102 nextk = k->chain; 103 dispose(k); 104 } 105 hashtab[i] = nil; 106 } 107 for (i = 0; i < ALIASHASH; i++) { 108 for (a = aliashashtab[i]; a != nil; a = nexta) { 109 nexta = a->chain; 110 dispose(a); 111 } 112 aliashashtab[i] = nil; 113 } 114 } 115 116 /* 117 * Enter a keyword into the name table. 118 * It is assumed to not be there already. 119 * The string is assumed to be statically allocated. 120 */ 121 private keyword(s, t) 122 String s; 123 Token t; 124 { 125 register Keyword k; 126 Hashvalue h; 127 Name n; 128 129 n = identname(s, true); 130 h = keyhash(n); 131 k = new(Keyword); 132 k->name = n; 133 k->toknum = t; 134 k->chain = hashtab[h]; 135 hashtab[h] = k; 136 } 137 138 /* 139 * Return the string associated with a token corresponding to a keyword. 140 */ 141 public String keywdstring(t) 142 Token t; 143 { 144 return reserved[ord(t) - ord(ALIAS)]; 145 } 146 147 /* 148 * Return the token associated with a given keyword string. 149 * We assume that tokens cannot legitimately be nil (0). 150 */ 151 152 public Token findkeyword(n) 153 Name n; 154 { 155 register Keyword k; 156 157 for (k = hashtab[keyhash(n)]; k != nil && k->name != n; k = k->chain) 158 ; 159 return (k == nil ? nil : k->toknum); 160 } 161 162 public String findalias(n) 163 Name n; 164 { 165 register Alias a; 166 167 for (a = aliashashtab[aliashash(n)]; a != nil && a->name != n; a = a->chain) 168 ; 169 return (a == nil ? nil : ident(a->expansion)); 170 } 171 172 /* 173 * Create an alias. 174 */ 175 public enter_alias(cmd, p) 176 Name cmd; 177 Node p; 178 { 179 Token t; 180 Name n; 181 182 t = findkeyword(cmd); 183 if (t != nil) { 184 error("\"%s\" can't redefine a command", ident(cmd)); 185 return; 186 } 187 if (p->op == O_SCON) 188 n = identname(p->value.scon, true); 189 else 190 n = identname(ident(p->value.name), true); 191 alias(cmd, n); 192 } 193 194 private alias(cmd, n) 195 Name cmd, n; 196 { 197 register Alias a; 198 Hashvalue h; 199 200 h = aliashash(cmd); 201 for (a = aliashashtab[h]; a != nil && a->name != cmd; a = a->chain) 202 ; 203 if (a != nil) { 204 a->expansion = n; 205 return; 206 } 207 a = new(Alias); 208 a->name = cmd; 209 a->expansion = n; 210 a->chain = aliashashtab[h]; 211 aliashashtab[h] = a; 212 } 213 214 /* 215 * Print out an alias. 216 */ 217 public print_alias(cmd) 218 Name cmd; 219 { 220 register Alias a; 221 register Integer i; 222 String s; 223 224 if (cmd != nil) { 225 s = findalias(cmd); 226 printf(s == nil ? "\n" : "%s\n", s); 227 return; 228 } 229 /* 230 * Dump the alias table. 231 */ 232 for (i = 0; i < ALIASHASH; i++) { 233 for (a = aliashashtab[i]; a != nil; a = a->chain) { 234 if (isredirected()) 235 printf("alias "); 236 printf("%s\t%s\n", ident(a->name), ident(a->expansion)); 237 } 238 } 239 } 240