121604Sdist /* 221604Sdist * Copyright (c) 1983 Regents of the University of California. 321604Sdist * All rights reserved. The Berkeley software License Agreement 421604Sdist * specifies the terms and conditions for redistribution. 521604Sdist */ 69664Slinton 721604Sdist #ifndef lint 8*22017Ssam static char sccsid[] = "@(#)keywords.c 5.2 (Berkeley) 06/04/85"; 921604Sdist #endif not lint 109664Slinton 1118220Slinton static char rcsid[] = "$Header: keywords.c,v 1.5 84/12/26 10:39:45 linton Exp $"; 1218220Slinton 139664Slinton /* 1418220Slinton * Keywords, variables, and aliases (oh my!). 159664Slinton */ 169664Slinton 179664Slinton #include "defs.h" 189664Slinton #include "keywords.h" 199664Slinton #include "scanner.h" 209664Slinton #include "names.h" 219664Slinton #include "symbols.h" 229664Slinton #include "tree.h" 2318220Slinton #include "lists.h" 2418220Slinton #include "main.h" 259664Slinton #include "y.tab.h" 269664Slinton 279664Slinton #ifndef public 2818220Slinton 299664Slinton #include "scanner.h" 3018220Slinton #include "tree.h" 3118220Slinton 329664Slinton #endif 339664Slinton 349664Slinton private String reserved[] ={ 359664Slinton "alias", "and", "assign", "at", "call", "catch", "cont", 3616611Ssam "debug", "delete", "div", "down", "dump", "edit", "file", "func", 379664Slinton "gripe", "help", "if", "ignore", "in", 389664Slinton "list", "mod", "next", "nexti", "nil", "not", "or", 3916611Ssam "print", "psym", "quit", "rerun", "return", "run", 4018220Slinton "set", "sh", "skip", "source", "status", "step", "stepi", 4118220Slinton "stop", "stopi", "trace", "tracei", "unalias", "unset", "up", "use", 4218220Slinton "whatis", "when", "where", "whereis", "which", 4318220Slinton "INT", "CHAR", "REAL", "NAME", "STRING", "->" 449664Slinton }; 459664Slinton 469664Slinton /* 479664Slinton * The keyword table is a traditional hash table with collisions 489664Slinton * resolved by chaining. 499664Slinton */ 5018220Slinton 5118220Slinton #define HASHTABLESIZE 1007 5218220Slinton 5318220Slinton typedef enum { ISKEYWORD, ISALIAS, ISVAR } KeywordType; 5418220Slinton 559664Slinton typedef struct Keyword { 569664Slinton Name name; 5718220Slinton KeywordType class : 16; 5818220Slinton union { 5918220Slinton /* ISKEYWORD: */ 6018220Slinton Token toknum; 6118220Slinton 6218220Slinton /* ISALIAS: */ 6318220Slinton struct { 6418220Slinton List paramlist; 6518220Slinton String expansion; 6618220Slinton } alias; 6718220Slinton 6818220Slinton /* ISVAR: */ 6918220Slinton Node var; 7018220Slinton } value; 719664Slinton struct Keyword *chain; 729664Slinton } *Keyword; 739664Slinton 749664Slinton typedef unsigned int Hashvalue; 759664Slinton 7618220Slinton private Keyword hashtab[HASHTABLESIZE]; 779664Slinton 7818220Slinton #define hash(n) ((((unsigned) n) >> 2) mod HASHTABLESIZE) 799664Slinton 809664Slinton /* 819664Slinton * Enter all the reserved words into the keyword table. 8218220Slinton * 8318220Slinton * If the vaddrs flag is set (through the -k command line option) then 8418220Slinton * set the special "$mapaddrs" variable. This assumes that the 8518220Slinton * command line arguments are scanned before this routine is called. 869664Slinton */ 8718220Slinton 889664Slinton public enterkeywords() 899664Slinton { 9018220Slinton register integer i; 919664Slinton 9218220Slinton for (i = ALIAS; i <= WHICH; i++) { 9316928Ssam keyword(reserved[ord(i) - ord(ALIAS)], i); 9418220Slinton } 9518220Slinton defalias("c", "cont"); 9618220Slinton defalias("d", "delete"); 9718220Slinton defalias("h", "help"); 9818220Slinton defalias("e", "edit"); 9918220Slinton defalias("l", "list"); 10018220Slinton defalias("n", "next"); 10118220Slinton defalias("p", "print"); 10218220Slinton defalias("q", "quit"); 10318220Slinton defalias("r", "run"); 10418220Slinton defalias("s", "step"); 10518220Slinton defalias("st", "stop"); 10618220Slinton defalias("j", "status"); 10718220Slinton defalias("t", "where"); 10818220Slinton if (vaddrs) { 10918220Slinton defvar(identname("$mapaddrs", true), nil); 11018220Slinton } 1119664Slinton } 1129664Slinton 1139664Slinton /* 11418220Slinton * Deallocate the keyword table. 1159664Slinton */ 11618220Slinton 1179664Slinton public keywords_free() 1189664Slinton { 1199664Slinton register Integer i; 1209664Slinton register Keyword k, nextk; 1219664Slinton 12218220Slinton for (i = 0; i < HASHTABLESIZE; i++) { 12318220Slinton k = hashtab[i]; 12418220Slinton while (k != nil) { 1259664Slinton nextk = k->chain; 1269664Slinton dispose(k); 12718220Slinton k = nextk; 1289664Slinton } 1299664Slinton hashtab[i] = nil; 1309664Slinton } 13118220Slinton } 13218220Slinton 13318220Slinton /* 13418220Slinton * Insert a name into the keyword table and return the keyword for it. 13518220Slinton */ 13618220Slinton 13718220Slinton private Keyword keywords_insert (n) 13818220Slinton Name n; 13918220Slinton { 14018220Slinton Hashvalue h; 14118220Slinton Keyword k; 14218220Slinton 14318220Slinton h = hash(n); 14418220Slinton k = new(Keyword); 14518220Slinton k->name = n; 14618220Slinton k->chain = hashtab[h]; 14718220Slinton hashtab[h] = k; 14818220Slinton return k; 14918220Slinton } 15018220Slinton 15118220Slinton /* 15218220Slinton * Find the keyword associated with the given name. 15318220Slinton */ 15418220Slinton 15518220Slinton private Keyword keywords_lookup (n) 15618220Slinton Name n; 15718220Slinton { 15818220Slinton Hashvalue h; 15918220Slinton register Keyword k; 16018220Slinton 16118220Slinton h = hash(n); 16218220Slinton k = hashtab[h]; 16318220Slinton while (k != nil and k->name != n) { 16418220Slinton k = k->chain; 16518220Slinton } 16618220Slinton return k; 16718220Slinton } 16818220Slinton 16918220Slinton /* 17018220Slinton * Delete the given keyword of the given class. 17118220Slinton */ 17218220Slinton 17318220Slinton private boolean keywords_delete (n, class) 17418220Slinton Name n; 17518220Slinton KeywordType class; 17618220Slinton { 17718220Slinton Hashvalue h; 17818220Slinton register Keyword k, prevk; 17918220Slinton boolean b; 18018220Slinton 18118220Slinton h = hash(n); 18218220Slinton k = hashtab[h]; 18318220Slinton prevk = nil; 18418220Slinton while (k != nil and (k->name != n or k->class != class)) { 18518220Slinton prevk = k; 18618220Slinton k = k->chain; 18718220Slinton } 18818220Slinton if (k != nil) { 18918220Slinton b = true; 19018220Slinton if (prevk == nil) { 19118220Slinton hashtab[h] = k->chain; 19218220Slinton } else { 19318220Slinton prevk->chain = k->chain; 19416928Ssam } 19518220Slinton dispose(k); 19618220Slinton } else { 19718220Slinton b = false; 19816928Ssam } 19918220Slinton return b; 2009664Slinton } 2019664Slinton 2029664Slinton /* 20318220Slinton * Enter a keyword into the table. It is assumed to not be there already. 2049664Slinton * The string is assumed to be statically allocated. 2059664Slinton */ 20618220Slinton 20718220Slinton private keyword (s, t) 2089664Slinton String s; 2099664Slinton Token t; 2109664Slinton { 21118220Slinton Keyword k; 2129664Slinton Name n; 2139664Slinton 2149664Slinton n = identname(s, true); 21518220Slinton k = keywords_insert(n); 21618220Slinton k->class = ISKEYWORD; 21718220Slinton k->value.toknum = t; 2189664Slinton } 2199664Slinton 2209664Slinton /* 22118220Slinton * Define a builtin command name alias. 2229664Slinton */ 22318220Slinton 22418220Slinton private defalias (s1, s2) 22518220Slinton String s1, s2; 2269664Slinton { 22718220Slinton alias(identname(s1, true), nil, s2); 2289664Slinton } 2299664Slinton 2309664Slinton /* 23118220Slinton * Look for a word of a particular class. 2329664Slinton */ 2339664Slinton 23418220Slinton private Keyword findword (n, class) 2359664Slinton Name n; 23618220Slinton KeywordType class; 2379664Slinton { 2389664Slinton register Keyword k; 2399664Slinton 24018220Slinton k = keywords_lookup(n); 24118220Slinton while (k != nil and (k->name != n or k->class != class)) { 24218220Slinton k = k->chain; 24318220Slinton } 24418220Slinton return k; 24516611Ssam } 24616611Ssam 24718220Slinton /* 24818220Slinton * Return the token associated with a given keyword string. 24918220Slinton * If there is none, return the given default value. 25018220Slinton */ 25118220Slinton 25218220Slinton public Token findkeyword (n, def) 25316611Ssam Name n; 25418220Slinton Token def; 25516611Ssam { 25618220Slinton Keyword k; 25718220Slinton Token t; 25816611Ssam 25918220Slinton k = findword(n, ISKEYWORD); 26018220Slinton if (k == nil) { 26118220Slinton t = def; 26218220Slinton } else { 26318220Slinton t = k->value.toknum; 26418220Slinton } 26518220Slinton return t; 2669664Slinton } 2679664Slinton 2689664Slinton /* 26918220Slinton * Return the associated string if there is an alias with the given name. 2709664Slinton */ 27118220Slinton 27218220Slinton public boolean findalias (n, pl, str) 27318220Slinton Name n; 27418220Slinton List *pl; 27518220Slinton String *str; 27618220Slinton { 27718220Slinton Keyword k; 27818220Slinton boolean b; 27918220Slinton 28018220Slinton k = findword(n, ISALIAS); 28118220Slinton if (k == nil) { 28218220Slinton b = false; 28318220Slinton } else { 28418220Slinton *pl = k->value.alias.paramlist; 28518220Slinton *str = k->value.alias.expansion; 286*22017Ssam b = true; 28718220Slinton } 28818220Slinton return b; 28918220Slinton } 29018220Slinton 29118220Slinton /* 29218220Slinton * Return the string associated with a token corresponding to a keyword. 29318220Slinton */ 29418220Slinton 29518220Slinton public String keywdstring (t) 29618220Slinton Token t; 29718220Slinton { 29818220Slinton return reserved[ord(t) - ord(ALIAS)]; 29918220Slinton } 30018220Slinton 30118220Slinton /* 30218220Slinton * Process an alias command, either entering a new alias or printing out 30318220Slinton * an existing one. 30418220Slinton */ 30518220Slinton 30618220Slinton public alias (newcmd, args, str) 30718220Slinton Name newcmd; 30818220Slinton List args; 30918220Slinton String str; 31018220Slinton { 31118220Slinton Keyword k; 31218220Slinton 31318220Slinton if (str == nil) { 31418220Slinton print_alias(newcmd); 31518220Slinton } else { 31618220Slinton k = findword(newcmd, ISALIAS); 31718220Slinton if (k == nil) { 31818220Slinton k = keywords_insert(newcmd); 31918220Slinton } 32018220Slinton k->class = ISALIAS; 32118220Slinton k->value.alias.paramlist = args; 32218220Slinton k->value.alias.expansion = str; 32318220Slinton } 32418220Slinton } 32518220Slinton 32618220Slinton /* 32718220Slinton * Print out an alias. 32818220Slinton */ 32918220Slinton 33018220Slinton private print_alias (cmd) 33116928Ssam Name cmd; 3329664Slinton { 33318220Slinton register Keyword k; 33418220Slinton register Integer i; 33516928Ssam Name n; 3369664Slinton 33718220Slinton if (cmd == nil) { 33818220Slinton for (i = 0; i < HASHTABLESIZE; i++) { 33918220Slinton for (k = hashtab[i]; k != nil; k = k->chain) { 34018220Slinton if (k->class == ISALIAS) { 34118220Slinton if (isredirected()) { 34218220Slinton printf("alias %s", ident(k->name)); 34318220Slinton printparams(k->value.alias.paramlist); 34418220Slinton printf("\t\"%s\"\n", k->value.alias.expansion); 34518220Slinton } else { 34618220Slinton printf("%s", ident(k->name)); 34718220Slinton printparams(k->value.alias.paramlist); 34818220Slinton printf("\t%s\n", k->value.alias.expansion); 34918220Slinton } 35018220Slinton } 35118220Slinton } 35218220Slinton } 35318220Slinton } else { 35418220Slinton k = findword(cmd, ISALIAS); 35518220Slinton if (k == nil) { 35618220Slinton printf("\n"); 35718220Slinton } else { 35818220Slinton printparams(k->value.alias.paramlist); 35918220Slinton printf("%s\n", k->value.alias.expansion); 36018220Slinton } 3619664Slinton } 3629664Slinton } 3639664Slinton 36418220Slinton private printparams (pl) 36518220Slinton List pl; 36616928Ssam { 36718220Slinton Name n; 36816928Ssam 36918220Slinton if (pl != nil) { 37018220Slinton printf("("); 37118220Slinton foreach(Name, n, pl) 37218220Slinton printf("%s", ident(n)); 37318220Slinton if (not list_islast()) { 37418220Slinton printf(", "); 37518220Slinton } 37618220Slinton endfor 37718220Slinton printf(")"); 37816928Ssam } 37918220Slinton } 38018220Slinton 38118220Slinton /* 38218220Slinton * Remove an alias. 38318220Slinton */ 38418220Slinton 38518220Slinton public unalias (n) 38618220Slinton Name n; 38718220Slinton { 38818220Slinton if (not keywords_delete(n, ISALIAS)) { 38918220Slinton error("%s is not aliased", ident(n)); 39016949Ssam } 39116928Ssam } 39216928Ssam 39318220Slinton /* 39418220Slinton * Define a variable. 39518220Slinton */ 39618220Slinton 39718220Slinton public defvar (n, val) 39818220Slinton Name n; 39918220Slinton Node val; 40016949Ssam { 40118220Slinton Keyword k; 40216949Ssam 40318220Slinton if (n == nil) { 40418220Slinton print_vars(); 40518220Slinton } else { 40618220Slinton if (lookup(n) != nil) { 40718220Slinton error("\"%s\" is a program symbol -- use assign", ident(n)); 40818220Slinton } 40918220Slinton k = findword(n, ISVAR); 41018220Slinton if (k == nil) { 41118220Slinton k = keywords_insert(n); 41218220Slinton } 41318220Slinton k->class = ISVAR; 41418220Slinton k->value.var = val; 41518220Slinton if (n == identname("$mapaddrs", true)) { 41618220Slinton vaddrs = true; 41718220Slinton } 41818220Slinton } 41916949Ssam } 42016949Ssam 4219664Slinton /* 42218220Slinton * Return the value associated with a variable. 4239664Slinton */ 42418220Slinton 42518220Slinton public Node findvar (n) 42618220Slinton Name n; 4279664Slinton { 42818220Slinton Keyword k; 42918220Slinton Node val; 4309664Slinton 43118220Slinton k = findword(n, ISVAR); 43218220Slinton if (k == nil) { 43318220Slinton val = nil; 43418220Slinton } else { 43518220Slinton val = k->value.var; 43616928Ssam } 43718220Slinton return val; 43818220Slinton } 43918220Slinton 44018220Slinton /* 44118220Slinton * Return whether or not a variable is set. 44218220Slinton */ 44318220Slinton 44418220Slinton public boolean varIsSet (s) 44518220Slinton String s; 44618220Slinton { 44718220Slinton return (boolean) (findword(identname(s, false), ISVAR) != nil); 44818220Slinton } 44918220Slinton 45018220Slinton /* 45118220Slinton * Delete a variable. 45218220Slinton */ 45318220Slinton 45418220Slinton public undefvar (n) 45518220Slinton Name n; 45618220Slinton { 45718220Slinton if (not keywords_delete(n, ISVAR)) { 45818220Slinton error("%s is not set", ident(n)); 45918220Slinton } 46018220Slinton if (n == identname("$mapaddrs", true)) { 46118220Slinton vaddrs = false; 46218220Slinton } 46318220Slinton } 46418220Slinton 46518220Slinton /* 46618220Slinton * Print out all the values of set variables. 46718220Slinton */ 46818220Slinton 46918220Slinton private print_vars () 47018220Slinton { 47118220Slinton register integer i; 47218220Slinton register Keyword k; 47318220Slinton 47418220Slinton for (i = 0; i < HASHTABLESIZE; i++) { 47518220Slinton for (k = hashtab[i]; k != nil; k = k->chain) { 47618220Slinton if (k->class == ISVAR) { 47718220Slinton if (isredirected()) { 47818220Slinton printf("set "); 47918220Slinton } 48018220Slinton printf("%s", ident(k->name)); 48118220Slinton if (k->value.var != nil) { 48218220Slinton printf("\t"); 48318220Slinton prtree(stdout, k->value.var); 48418220Slinton } 48518220Slinton printf("\n"); 48618220Slinton } 4879664Slinton } 4889664Slinton } 4899664Slinton } 490