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