|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char sccsid[] = "@(#)keywords.c 5.2 (Berkeley) 6/4/85"; ! 9: #endif not lint ! 10: ! 11: static char rcsid[] = "$Header: keywords.c,v 1.5 84/12/26 10:39:45 linton Exp $"; ! 12: ! 13: /* ! 14: * Keywords, variables, and aliases (oh my!). ! 15: */ ! 16: ! 17: #include "defs.h" ! 18: #include "keywords.h" ! 19: #include "scanner.h" ! 20: #include "names.h" ! 21: #include "symbols.h" ! 22: #include "tree.h" ! 23: #include "lists.h" ! 24: #include "main.h" ! 25: #include "y.tab.h" ! 26: ! 27: #ifndef public ! 28: ! 29: #include "scanner.h" ! 30: #include "tree.h" ! 31: ! 32: #endif ! 33: ! 34: private String reserved[] ={ ! 35: "alias", "and", "assign", "at", "call", "catch", "cont", ! 36: "debug", "delete", "div", "down", "dump", "edit", "file", "func", ! 37: "gripe", "help", "if", "ignore", "in", ! 38: "list", "mod", "next", "nexti", "nil", "not", "or", ! 39: "print", "psym", "quit", "rerun", "return", "run", ! 40: "set", "sh", "skip", "source", "status", "step", "stepi", ! 41: "stop", "stopi", "trace", "tracei", "unalias", "unset", "up", "use", ! 42: "whatis", "when", "where", "whereis", "which", ! 43: "INT", "CHAR", "REAL", "NAME", "STRING", "->" ! 44: }; ! 45: ! 46: /* ! 47: * The keyword table is a traditional hash table with collisions ! 48: * resolved by chaining. ! 49: */ ! 50: ! 51: #define HASHTABLESIZE 1007 ! 52: ! 53: typedef enum { ISKEYWORD, ISALIAS, ISVAR } KeywordType; ! 54: ! 55: typedef struct Keyword { ! 56: Name name; ! 57: KeywordType class : 16; ! 58: union { ! 59: /* ISKEYWORD: */ ! 60: Token toknum; ! 61: ! 62: /* ISALIAS: */ ! 63: struct { ! 64: List paramlist; ! 65: String expansion; ! 66: } alias; ! 67: ! 68: /* ISVAR: */ ! 69: Node var; ! 70: } value; ! 71: struct Keyword *chain; ! 72: } *Keyword; ! 73: ! 74: typedef unsigned int Hashvalue; ! 75: ! 76: private Keyword hashtab[HASHTABLESIZE]; ! 77: ! 78: #define hash(n) ((((unsigned) n) >> 2) mod HASHTABLESIZE) ! 79: ! 80: /* ! 81: * Enter all the reserved words into the keyword table. ! 82: * ! 83: * If the vaddrs flag is set (through the -k command line option) then ! 84: * set the special "$mapaddrs" variable. This assumes that the ! 85: * command line arguments are scanned before this routine is called. ! 86: */ ! 87: ! 88: public enterkeywords() ! 89: { ! 90: register integer i; ! 91: ! 92: for (i = ALIAS; i <= WHICH; i++) { ! 93: keyword(reserved[ord(i) - ord(ALIAS)], i); ! 94: } ! 95: defalias("c", "cont"); ! 96: defalias("d", "delete"); ! 97: defalias("h", "help"); ! 98: defalias("e", "edit"); ! 99: defalias("l", "list"); ! 100: defalias("n", "next"); ! 101: defalias("p", "print"); ! 102: defalias("q", "quit"); ! 103: defalias("r", "run"); ! 104: defalias("s", "step"); ! 105: defalias("st", "stop"); ! 106: defalias("j", "status"); ! 107: defalias("t", "where"); ! 108: if (vaddrs) { ! 109: defvar(identname("$mapaddrs", true), nil); ! 110: } ! 111: } ! 112: ! 113: /* ! 114: * Deallocate the keyword table. ! 115: */ ! 116: ! 117: public keywords_free() ! 118: { ! 119: register Integer i; ! 120: register Keyword k, nextk; ! 121: ! 122: for (i = 0; i < HASHTABLESIZE; i++) { ! 123: k = hashtab[i]; ! 124: while (k != nil) { ! 125: nextk = k->chain; ! 126: dispose(k); ! 127: k = nextk; ! 128: } ! 129: hashtab[i] = nil; ! 130: } ! 131: } ! 132: ! 133: /* ! 134: * Insert a name into the keyword table and return the keyword for it. ! 135: */ ! 136: ! 137: private Keyword keywords_insert (n) ! 138: Name n; ! 139: { ! 140: Hashvalue h; ! 141: Keyword k; ! 142: ! 143: h = hash(n); ! 144: k = new(Keyword); ! 145: k->name = n; ! 146: k->chain = hashtab[h]; ! 147: hashtab[h] = k; ! 148: return k; ! 149: } ! 150: ! 151: /* ! 152: * Find the keyword associated with the given name. ! 153: */ ! 154: ! 155: private Keyword keywords_lookup (n) ! 156: Name n; ! 157: { ! 158: Hashvalue h; ! 159: register Keyword k; ! 160: ! 161: h = hash(n); ! 162: k = hashtab[h]; ! 163: while (k != nil and k->name != n) { ! 164: k = k->chain; ! 165: } ! 166: return k; ! 167: } ! 168: ! 169: /* ! 170: * Delete the given keyword of the given class. ! 171: */ ! 172: ! 173: private boolean keywords_delete (n, class) ! 174: Name n; ! 175: KeywordType class; ! 176: { ! 177: Hashvalue h; ! 178: register Keyword k, prevk; ! 179: boolean b; ! 180: ! 181: h = hash(n); ! 182: k = hashtab[h]; ! 183: prevk = nil; ! 184: while (k != nil and (k->name != n or k->class != class)) { ! 185: prevk = k; ! 186: k = k->chain; ! 187: } ! 188: if (k != nil) { ! 189: b = true; ! 190: if (prevk == nil) { ! 191: hashtab[h] = k->chain; ! 192: } else { ! 193: prevk->chain = k->chain; ! 194: } ! 195: dispose(k); ! 196: } else { ! 197: b = false; ! 198: } ! 199: return b; ! 200: } ! 201: ! 202: /* ! 203: * Enter a keyword into the table. It is assumed to not be there already. ! 204: * The string is assumed to be statically allocated. ! 205: */ ! 206: ! 207: private keyword (s, t) ! 208: String s; ! 209: Token t; ! 210: { ! 211: Keyword k; ! 212: Name n; ! 213: ! 214: n = identname(s, true); ! 215: k = keywords_insert(n); ! 216: k->class = ISKEYWORD; ! 217: k->value.toknum = t; ! 218: } ! 219: ! 220: /* ! 221: * Define a builtin command name alias. ! 222: */ ! 223: ! 224: private defalias (s1, s2) ! 225: String s1, s2; ! 226: { ! 227: alias(identname(s1, true), nil, s2); ! 228: } ! 229: ! 230: /* ! 231: * Look for a word of a particular class. ! 232: */ ! 233: ! 234: private Keyword findword (n, class) ! 235: Name n; ! 236: KeywordType class; ! 237: { ! 238: register Keyword k; ! 239: ! 240: k = keywords_lookup(n); ! 241: while (k != nil and (k->name != n or k->class != class)) { ! 242: k = k->chain; ! 243: } ! 244: return k; ! 245: } ! 246: ! 247: /* ! 248: * Return the token associated with a given keyword string. ! 249: * If there is none, return the given default value. ! 250: */ ! 251: ! 252: public Token findkeyword (n, def) ! 253: Name n; ! 254: Token def; ! 255: { ! 256: Keyword k; ! 257: Token t; ! 258: ! 259: k = findword(n, ISKEYWORD); ! 260: if (k == nil) { ! 261: t = def; ! 262: } else { ! 263: t = k->value.toknum; ! 264: } ! 265: return t; ! 266: } ! 267: ! 268: /* ! 269: * Return the associated string if there is an alias with the given name. ! 270: */ ! 271: ! 272: public boolean findalias (n, pl, str) ! 273: Name n; ! 274: List *pl; ! 275: String *str; ! 276: { ! 277: Keyword k; ! 278: boolean b; ! 279: ! 280: k = findword(n, ISALIAS); ! 281: if (k == nil) { ! 282: b = false; ! 283: } else { ! 284: *pl = k->value.alias.paramlist; ! 285: *str = k->value.alias.expansion; ! 286: b = true; ! 287: } ! 288: return b; ! 289: } ! 290: ! 291: /* ! 292: * Return the string associated with a token corresponding to a keyword. ! 293: */ ! 294: ! 295: public String keywdstring (t) ! 296: Token t; ! 297: { ! 298: return reserved[ord(t) - ord(ALIAS)]; ! 299: } ! 300: ! 301: /* ! 302: * Process an alias command, either entering a new alias or printing out ! 303: * an existing one. ! 304: */ ! 305: ! 306: public alias (newcmd, args, str) ! 307: Name newcmd; ! 308: List args; ! 309: String str; ! 310: { ! 311: Keyword k; ! 312: ! 313: if (str == nil) { ! 314: print_alias(newcmd); ! 315: } else { ! 316: k = findword(newcmd, ISALIAS); ! 317: if (k == nil) { ! 318: k = keywords_insert(newcmd); ! 319: } ! 320: k->class = ISALIAS; ! 321: k->value.alias.paramlist = args; ! 322: k->value.alias.expansion = str; ! 323: } ! 324: } ! 325: ! 326: /* ! 327: * Print out an alias. ! 328: */ ! 329: ! 330: private print_alias (cmd) ! 331: Name cmd; ! 332: { ! 333: register Keyword k; ! 334: register Integer i; ! 335: Name n; ! 336: ! 337: if (cmd == nil) { ! 338: for (i = 0; i < HASHTABLESIZE; i++) { ! 339: for (k = hashtab[i]; k != nil; k = k->chain) { ! 340: if (k->class == ISALIAS) { ! 341: if (isredirected()) { ! 342: printf("alias %s", ident(k->name)); ! 343: printparams(k->value.alias.paramlist); ! 344: printf("\t\"%s\"\n", k->value.alias.expansion); ! 345: } else { ! 346: printf("%s", ident(k->name)); ! 347: printparams(k->value.alias.paramlist); ! 348: printf("\t%s\n", k->value.alias.expansion); ! 349: } ! 350: } ! 351: } ! 352: } ! 353: } else { ! 354: k = findword(cmd, ISALIAS); ! 355: if (k == nil) { ! 356: printf("\n"); ! 357: } else { ! 358: printparams(k->value.alias.paramlist); ! 359: printf("%s\n", k->value.alias.expansion); ! 360: } ! 361: } ! 362: } ! 363: ! 364: private printparams (pl) ! 365: List pl; ! 366: { ! 367: Name n; ! 368: ! 369: if (pl != nil) { ! 370: printf("("); ! 371: foreach(Name, n, pl) ! 372: printf("%s", ident(n)); ! 373: if (not list_islast()) { ! 374: printf(", "); ! 375: } ! 376: endfor ! 377: printf(")"); ! 378: } ! 379: } ! 380: ! 381: /* ! 382: * Remove an alias. ! 383: */ ! 384: ! 385: public unalias (n) ! 386: Name n; ! 387: { ! 388: if (not keywords_delete(n, ISALIAS)) { ! 389: error("%s is not aliased", ident(n)); ! 390: } ! 391: } ! 392: ! 393: /* ! 394: * Define a variable. ! 395: */ ! 396: ! 397: public defvar (n, val) ! 398: Name n; ! 399: Node val; ! 400: { ! 401: Keyword k; ! 402: ! 403: if (n == nil) { ! 404: print_vars(); ! 405: } else { ! 406: if (lookup(n) != nil) { ! 407: error("\"%s\" is a program symbol -- use assign", ident(n)); ! 408: } ! 409: k = findword(n, ISVAR); ! 410: if (k == nil) { ! 411: k = keywords_insert(n); ! 412: } ! 413: k->class = ISVAR; ! 414: k->value.var = val; ! 415: if (n == identname("$mapaddrs", true)) { ! 416: vaddrs = true; ! 417: } ! 418: } ! 419: } ! 420: ! 421: /* ! 422: * Return the value associated with a variable. ! 423: */ ! 424: ! 425: public Node findvar (n) ! 426: Name n; ! 427: { ! 428: Keyword k; ! 429: Node val; ! 430: ! 431: k = findword(n, ISVAR); ! 432: if (k == nil) { ! 433: val = nil; ! 434: } else { ! 435: val = k->value.var; ! 436: } ! 437: return val; ! 438: } ! 439: ! 440: /* ! 441: * Return whether or not a variable is set. ! 442: */ ! 443: ! 444: public boolean varIsSet (s) ! 445: String s; ! 446: { ! 447: return (boolean) (findword(identname(s, false), ISVAR) != nil); ! 448: } ! 449: ! 450: /* ! 451: * Delete a variable. ! 452: */ ! 453: ! 454: public undefvar (n) ! 455: Name n; ! 456: { ! 457: if (not keywords_delete(n, ISVAR)) { ! 458: error("%s is not set", ident(n)); ! 459: } ! 460: if (n == identname("$mapaddrs", true)) { ! 461: vaddrs = false; ! 462: } ! 463: } ! 464: ! 465: /* ! 466: * Print out all the values of set variables. ! 467: */ ! 468: ! 469: private print_vars () ! 470: { ! 471: register integer i; ! 472: register Keyword k; ! 473: ! 474: for (i = 0; i < HASHTABLESIZE; i++) { ! 475: for (k = hashtab[i]; k != nil; k = k->chain) { ! 476: if (k->class == ISVAR) { ! 477: if (isredirected()) { ! 478: printf("set "); ! 479: } ! 480: printf("%s", ident(k->name)); ! 481: if (k->value.var != nil) { ! 482: printf("\t"); ! 483: prtree(stdout, k->value.var); ! 484: } ! 485: printf("\n"); ! 486: } ! 487: } ! 488: } ! 489: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.