1*5527Slinton /* Copyright (c) 1982 Regents of the University of California */
2*5527Slinton 
3*5527Slinton static char sccsid[] = "@(#)predicates.c 1.1 01/18/82";
4*5527Slinton 
5*5527Slinton /*
6*5527Slinton  * The basic tests on a symbol.
7*5527Slinton  */
8*5527Slinton 
9*5527Slinton #include "defs.h"
10*5527Slinton #include "sym.h"
11*5527Slinton #include "symtab.h"
12*5527Slinton #include "classes.h"
13*5527Slinton #include "sym.rep"
14*5527Slinton 
15*5527Slinton /*
16*5527Slinton  * Test if a symbol is a parameter.  This is true if there
17*5527Slinton  * is a cycle from s->func to s via chain pointers.
18*5527Slinton  */
19*5527Slinton 
20*5527Slinton BOOLEAN isparam(s)
21*5527Slinton SYM *s;
22*5527Slinton {
23*5527Slinton 	register SYM *t;
24*5527Slinton 
25*5527Slinton 	for (t = s->func; t != NIL; t = t->chain) {
26*5527Slinton 		if (t == s) {
27*5527Slinton 			return(TRUE);
28*5527Slinton 		}
29*5527Slinton 	}
30*5527Slinton 	return(FALSE);
31*5527Slinton }
32*5527Slinton 
33*5527Slinton /*
34*5527Slinton  * Test if a symbol is a var parameter, i.e. has class REF.
35*5527Slinton  */
36*5527Slinton 
37*5527Slinton BOOLEAN isvarparam(s)
38*5527Slinton SYM *s;
39*5527Slinton {
40*5527Slinton 	return (BOOLEAN) s->class == REF;
41*5527Slinton }
42*5527Slinton 
43*5527Slinton /*
44*5527Slinton  * Test if a symbol is a block, e.g. function, procedure, or the
45*5527Slinton  * main program.
46*5527Slinton  */
47*5527Slinton 
48*5527Slinton BOOLEAN isblock(s)
49*5527Slinton register SYM *s;
50*5527Slinton {
51*5527Slinton 	return(s->class == FUNC || s->class == PROC || s->class == PROG);
52*5527Slinton }
53*5527Slinton 
54*5527Slinton /*
55*5527Slinton  * Test if a symbol is builtin, that is, a predefined type or
56*5527Slinton  * reserved word.
57*5527Slinton  */
58*5527Slinton 
59*5527Slinton BOOLEAN isbuiltin(s)
60*5527Slinton SYM *s;
61*5527Slinton {
62*5527Slinton 	return(s->blkno == 0 && s->class != PROG && s->class != VAR);
63*5527Slinton }
64*5527Slinton 
65*5527Slinton /*
66*5527Slinton  * Compatible tests if two types are compatible.  The issue
67*5527Slinton  * is complicated a bit by ranges.
68*5527Slinton  *
69*5527Slinton  * Integers and reals are not compatible since they cannot always be mixed.
70*5527Slinton  */
71*5527Slinton 
72*5527Slinton BOOLEAN compatible(t1, t2)
73*5527Slinton register SYM *t1, *t2;
74*5527Slinton {
75*5527Slinton 	if (t1 == t2) {
76*5527Slinton 		return(TRUE);
77*5527Slinton 	}
78*5527Slinton 	t1 = rtype(t1);
79*5527Slinton 	t2 = rtype(t2);
80*5527Slinton 	if (t1->type == t2->type) {
81*5527Slinton 		if (t1->class == RANGE && t2->class == RANGE) {
82*5527Slinton 			return TRUE;
83*5527Slinton 		}
84*5527Slinton 		if ((t1->class == SCAL || t1->class == CONST) &&
85*5527Slinton 		  (t2->class == SCAL || t2->class == CONST)) {
86*5527Slinton 			return TRUE;
87*5527Slinton 		}
88*5527Slinton 	}
89*5527Slinton /*
90*5527Slinton  * A kludge here for "nil".  Should be handled better.
91*5527Slinton  * Opens a pandora's box for integer/pointer compatibility.
92*5527Slinton  */
93*5527Slinton 	if (t1->class == RANGE && t2->class == PTR) {
94*5527Slinton 		return TRUE;
95*5527Slinton 	}
96*5527Slinton 	if (t2->class == RANGE && t1->class == PTR) {
97*5527Slinton 		return TRUE;
98*5527Slinton 	}
99*5527Slinton 	return(FALSE);
100*5527Slinton }
101*5527Slinton 
102*5527Slinton /*
103*5527Slinton  * Predicate to test if a symbol should be printed.  We don't print
104*5527Slinton  * files, for example, simply because there's no good way to do it.
105*5527Slinton  * The symbol must be within the given function.
106*5527Slinton  */
107*5527Slinton 
108*5527Slinton BOOLEAN should_print(s, f)
109*5527Slinton SYM *s;
110*5527Slinton SYM *f;
111*5527Slinton {
112*5527Slinton 	SYM *t;
113*5527Slinton 
114*5527Slinton 	if (s->func != f || (s->class != VAR && s->class != FVAR)) {
115*5527Slinton 		return(FALSE);
116*5527Slinton 	} else if (s->chain != NIL) {
117*5527Slinton 		return(FALSE);
118*5527Slinton 	} else {
119*5527Slinton 		t = rtype(s->type);
120*5527Slinton 		if (t == NIL || t->class == FILET) {
121*5527Slinton 			return(FALSE);
122*5527Slinton 		} else {
123*5527Slinton 			return(TRUE);
124*5527Slinton 		}
125*5527Slinton 	}
126*5527Slinton }
127*5527Slinton 
128*5527Slinton /*
129*5527Slinton  * Test if the name of a symbol is uniquely defined or not.
130*5527Slinton  */
131*5527Slinton 
132*5527Slinton BOOLEAN isambiguous(s)
133*5527Slinton SYM *s;
134*5527Slinton {
135*5527Slinton 	SYM *t;
136*5527Slinton 
137*5527Slinton 	t = st_lookup(symtab, s->symbol);
138*5527Slinton 	if (t == NIL) {
139*5527Slinton 		panic("symbol name vanished");
140*5527Slinton 	}
141*5527Slinton 	while (t != NIL && (s == t || !streq(t->symbol, s->symbol))) {
142*5527Slinton 		t = t->next_sym;
143*5527Slinton 	}
144*5527Slinton 	return t != NIL;
145*5527Slinton }
146