15527Slinton /* Copyright (c) 1982 Regents of the University of California */
25527Slinton 
3*5564Slinton static char sccsid[] = "@(#)predicates.c 1.2 01/19/82";
45527Slinton 
55527Slinton /*
65527Slinton  * The basic tests on a symbol.
75527Slinton  */
85527Slinton 
95527Slinton #include "defs.h"
105527Slinton #include "sym.h"
115527Slinton #include "symtab.h"
12*5564Slinton #include "btypes.h"
135527Slinton #include "classes.h"
145527Slinton #include "sym.rep"
155527Slinton 
165527Slinton /*
175527Slinton  * Test if a symbol is a parameter.  This is true if there
185527Slinton  * is a cycle from s->func to s via chain pointers.
195527Slinton  */
205527Slinton 
215527Slinton BOOLEAN isparam(s)
225527Slinton SYM *s;
235527Slinton {
245527Slinton 	register SYM *t;
255527Slinton 
265527Slinton 	for (t = s->func; t != NIL; t = t->chain) {
275527Slinton 		if (t == s) {
285527Slinton 			return(TRUE);
295527Slinton 		}
305527Slinton 	}
315527Slinton 	return(FALSE);
325527Slinton }
335527Slinton 
345527Slinton /*
355527Slinton  * Test if a symbol is a var parameter, i.e. has class REF.
365527Slinton  */
375527Slinton 
385527Slinton BOOLEAN isvarparam(s)
395527Slinton SYM *s;
405527Slinton {
415527Slinton 	return (BOOLEAN) s->class == REF;
425527Slinton }
435527Slinton 
445527Slinton /*
455527Slinton  * Test if a symbol is a block, e.g. function, procedure, or the
465527Slinton  * main program.
475527Slinton  */
485527Slinton 
495527Slinton BOOLEAN isblock(s)
505527Slinton register SYM *s;
515527Slinton {
525527Slinton 	return(s->class == FUNC || s->class == PROC || s->class == PROG);
535527Slinton }
545527Slinton 
555527Slinton /*
565527Slinton  * Test if a symbol is builtin, that is, a predefined type or
575527Slinton  * reserved word.
585527Slinton  */
595527Slinton 
605527Slinton BOOLEAN isbuiltin(s)
615527Slinton SYM *s;
625527Slinton {
635527Slinton 	return(s->blkno == 0 && s->class != PROG && s->class != VAR);
645527Slinton }
655527Slinton 
665527Slinton /*
675527Slinton  * Compatible tests if two types are compatible.  The issue
685527Slinton  * is complicated a bit by ranges.
695527Slinton  *
705527Slinton  * Integers and reals are not compatible since they cannot always be mixed.
715527Slinton  */
725527Slinton 
735527Slinton BOOLEAN compatible(t1, t2)
745527Slinton register SYM *t1, *t2;
755527Slinton {
765527Slinton 	if (t1 == t2) {
775527Slinton 		return(TRUE);
785527Slinton 	}
795527Slinton 	t1 = rtype(t1);
805527Slinton 	t2 = rtype(t2);
815527Slinton 	if (t1->type == t2->type) {
825527Slinton 		if (t1->class == RANGE && t2->class == RANGE) {
835527Slinton 			return TRUE;
845527Slinton 		}
855527Slinton 		if ((t1->class == SCAL || t1->class == CONST) &&
865527Slinton 		  (t2->class == SCAL || t2->class == CONST)) {
875527Slinton 			return TRUE;
885527Slinton 		}
89*5564Slinton 		if (t1->type == t_char && t1->class == ARRAY && t2->class == ARRAY) {
90*5564Slinton 			return TRUE;
91*5564Slinton 		}
925527Slinton 	}
935527Slinton /*
945527Slinton  * A kludge here for "nil".  Should be handled better.
955527Slinton  * Opens a pandora's box for integer/pointer compatibility.
965527Slinton  */
975527Slinton 	if (t1->class == RANGE && t2->class == PTR) {
985527Slinton 		return TRUE;
995527Slinton 	}
1005527Slinton 	if (t2->class == RANGE && t1->class == PTR) {
1015527Slinton 		return TRUE;
1025527Slinton 	}
1035527Slinton 	return(FALSE);
1045527Slinton }
1055527Slinton 
1065527Slinton /*
1075527Slinton  * Predicate to test if a symbol should be printed.  We don't print
1085527Slinton  * files, for example, simply because there's no good way to do it.
1095527Slinton  * The symbol must be within the given function.
1105527Slinton  */
1115527Slinton 
1125527Slinton BOOLEAN should_print(s, f)
1135527Slinton SYM *s;
1145527Slinton SYM *f;
1155527Slinton {
1165527Slinton 	SYM *t;
1175527Slinton 
1185527Slinton 	if (s->func != f || (s->class != VAR && s->class != FVAR)) {
1195527Slinton 		return(FALSE);
1205527Slinton 	} else if (s->chain != NIL) {
1215527Slinton 		return(FALSE);
1225527Slinton 	} else {
1235527Slinton 		t = rtype(s->type);
124*5564Slinton 		if (t == NIL || t->class == FILET || t->class == SET) {
1255527Slinton 			return(FALSE);
1265527Slinton 		} else {
1275527Slinton 			return(TRUE);
1285527Slinton 		}
1295527Slinton 	}
1305527Slinton }
1315527Slinton 
1325527Slinton /*
1335527Slinton  * Test if the name of a symbol is uniquely defined or not.
1345527Slinton  */
1355527Slinton 
1365527Slinton BOOLEAN isambiguous(s)
1375527Slinton SYM *s;
1385527Slinton {
1395527Slinton 	SYM *t;
1405527Slinton 
1415527Slinton 	t = st_lookup(symtab, s->symbol);
1425527Slinton 	if (t == NIL) {
1435527Slinton 		panic("symbol name vanished");
1445527Slinton 	}
1455527Slinton 	while (t != NIL && (s == t || !streq(t->symbol, s->symbol))) {
1465527Slinton 		t = t->next_sym;
1475527Slinton 	}
1485527Slinton 	return t != NIL;
1495527Slinton }
150