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