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