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