xref: /original-bsd/usr.bin/pascal/pdx/sym/which.c (revision 18f6d767)
1 /* Copyright (c) 1982 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)which.c 1.1 01/18/82";
4 
5 /*
6  * Routines to distinguish symbols of the same name.
7  */
8 
9 #include "defs.h"
10 #include "sym.h"
11 #include "classes.h"
12 #include "symtab.h"
13 #include "mappings.h"
14 #include "machine.h"
15 #include "sym.rep"
16 
17 /*
18  * Figure out the "current" symbol being referred to,
19  * this is either the active one or the most visible from the
20  * current scope.
21  *
22  * Fields are purposely ignored; these can be gotten to via "findclass".
23  */
24 
25 SYM *which(s)
26 SYM *s;
27 {
28 	register SYM *p, *t, *f;
29 
30 	if (s == program || isbuiltin(s)) {
31 		return(s);
32 	}
33 	if (!isactive(program)) {
34 		f = program;
35 	} else {
36 		f = whatblock(pc);
37 		if (f == NIL) {
38 			panic("no block for addr 0x%x", pc);
39 		}
40 	}
41 	for (p = f; p != NIL; p = p->func) {
42 		if ((t = findsym(s, p)) != NIL) {
43 			break;
44 		}
45 	}
46 	if (t == NIL) {
47 		error("\"%s\" is not known in \"%s\"", s->symbol, f->symbol);
48 	}
49 	return(t);
50 }
51 
52 /*
53  * Find a (non-field) symbol with name s->symbol belonging to block f.
54  *
55  * Parameters to the main program are purposely "not found" because
56  * pi gives them no type.
57  */
58 
59 SYM *findsym(s, f)
60 SYM *s;
61 SYM *f;
62 {
63 	register SYM *t;
64 
65 	if (!isblock(f)) {
66 		error("%s is not a block", f->symbol);
67 	}
68 	for (t = s; t != NIL; t = t->next_sym) {
69 		if (t->func == f && !(f == program && isparam(t)) &&
70 		  t->class != FIELD && streq(t->symbol, s->symbol)) {
71 			break;
72 		}
73 	}
74 	return(t);
75 }
76 
77 /*
78  * Find the symbol which is has the same name and scope as the
79  * given symbol but is of the given field.  Return NIL if there is none.
80  */
81 
82 SYM *findclass(s, cl)
83 SYM *s;
84 char cl;
85 {
86 	register SYM *t;
87 
88 	if (s->class == cl) {
89 		return(s);
90 	}
91 	t = st_lookup(symtab, s->symbol);
92 	while (t != NIL && (t->class != cl || t->func != s->func ||
93 	  !streq(s->symbol, t->symbol))) {
94 		t = t->next_sym;
95 	}
96 	return(t);
97 }
98