xref: /csrg-svn/usr.bin/pascal/pdx/sym/which.c (revision 62149)
148093Sbostic /*-
2*62149Sbostic  * Copyright (c) 1980, 1993
3*62149Sbostic  *	The Regents of the University of California.  All rights reserved.
448093Sbostic  *
548093Sbostic  * %sccs.include.redist.c%
622529Sdist  */
75532Slinton 
822529Sdist #ifndef lint
9*62149Sbostic static char sccsid[] = "@(#)which.c	8.1 (Berkeley) 06/06/93";
1048093Sbostic #endif /* not lint */
115532Slinton 
125532Slinton /*
135532Slinton  * Routines to distinguish symbols of the same name.
145532Slinton  */
155532Slinton 
165532Slinton #include "defs.h"
175532Slinton #include "sym.h"
185532Slinton #include "classes.h"
195532Slinton #include "symtab.h"
205532Slinton #include "mappings.h"
215532Slinton #include "machine.h"
225532Slinton #include "sym.rep"
235532Slinton 
245532Slinton /*
255532Slinton  * Figure out the "current" symbol being referred to,
265532Slinton  * this is either the active one or the most visible from the
275532Slinton  * current scope.
285532Slinton  *
295532Slinton  * Fields are purposely ignored; these can be gotten to via "findclass".
305532Slinton  */
315532Slinton 
which(s)325532Slinton SYM *which(s)
335532Slinton SYM *s;
345532Slinton {
355532Slinton 	register SYM *p, *t, *f;
365532Slinton 
375532Slinton 	if (s == program || isbuiltin(s)) {
385532Slinton 		return(s);
395532Slinton 	}
405532Slinton 	if (!isactive(program)) {
415532Slinton 		f = program;
425532Slinton 	} else {
435532Slinton 		f = whatblock(pc);
445532Slinton 		if (f == NIL) {
455532Slinton 			panic("no block for addr 0x%x", pc);
465532Slinton 		}
475532Slinton 	}
485532Slinton 	for (p = f; p != NIL; p = p->func) {
495532Slinton 		if ((t = findsym(s, p)) != NIL) {
505532Slinton 			break;
515532Slinton 		}
525532Slinton 	}
535532Slinton 	if (t == NIL) {
545532Slinton 		error("\"%s\" is not known in \"%s\"", s->symbol, f->symbol);
555532Slinton 	}
565532Slinton 	return(t);
575532Slinton }
585532Slinton 
595532Slinton /*
605532Slinton  * Find a (non-field) symbol with name s->symbol belonging to block f.
615532Slinton  *
625532Slinton  * Parameters to the main program are purposely "not found" because
635532Slinton  * pi gives them no type.
645532Slinton  */
655532Slinton 
findsym(s,f)665532Slinton SYM *findsym(s, f)
675532Slinton SYM *s;
685532Slinton SYM *f;
695532Slinton {
705532Slinton 	register SYM *t;
715532Slinton 
725532Slinton 	if (!isblock(f)) {
735532Slinton 		error("%s is not a block", f->symbol);
745532Slinton 	}
755532Slinton 	for (t = s; t != NIL; t = t->next_sym) {
765532Slinton 		if (t->func == f && !(f == program && isparam(t)) &&
775532Slinton 		  t->class != FIELD && streq(t->symbol, s->symbol)) {
785532Slinton 			break;
795532Slinton 		}
805532Slinton 	}
815532Slinton 	return(t);
825532Slinton }
835532Slinton 
845532Slinton /*
855532Slinton  * Find the symbol which is has the same name and scope as the
865532Slinton  * given symbol but is of the given field.  Return NIL if there is none.
875532Slinton  */
885532Slinton 
findclass(s,cl)895532Slinton SYM *findclass(s, cl)
905532Slinton SYM *s;
915532Slinton char cl;
925532Slinton {
935532Slinton 	register SYM *t;
945532Slinton 
955532Slinton 	if (s->class == cl) {
965532Slinton 		return(s);
975532Slinton 	}
985532Slinton 	t = st_lookup(symtab, s->symbol);
995532Slinton 	while (t != NIL && (t->class != cl || t->func != s->func ||
1005532Slinton 	  !streq(s->symbol, t->symbol))) {
1015532Slinton 		t = t->next_sym;
1025532Slinton 	}
1035532Slinton 	return(t);
1045532Slinton }
105