|
|
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.