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