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