1 /* Copyright (c) 1982 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)predicates.c 1.3 02/17/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 if (t1 == t2) { 88 return(TRUE); 89 } 90 t1 = rtype(t1); 91 t2 = rtype(t2); 92 if (t1->type == t2->type) { 93 if (t1->class == RANGE && t2->class == RANGE) { 94 return TRUE; 95 } 96 if ((t1->class == SCAL || t1->class == CONST) && 97 (t2->class == SCAL || t2->class == CONST)) { 98 return TRUE; 99 } 100 if (t1->type == t_char && t1->class == ARRAY && t2->class == ARRAY) { 101 return TRUE; 102 } 103 } 104 /* 105 * A kludge here for "nil". Should be handled better. 106 * Opens a pandora's box for integer/pointer compatibility. 107 */ 108 if (t1->class == RANGE && t2->class == PTR) { 109 return TRUE; 110 } 111 if (t2->class == RANGE && t1->class == PTR) { 112 return TRUE; 113 } 114 return(FALSE); 115 } 116 117 /* 118 * Predicate to test if a symbol should be printed. We don't print 119 * files, for example, simply because there's no good way to do it. 120 * The symbol must be within the given function. 121 */ 122 123 BOOLEAN should_print(s, f) 124 SYM *s; 125 SYM *f; 126 { 127 SYM *t; 128 129 if (s->func != f || (s->class != VAR && s->class != FVAR)) { 130 return(FALSE); 131 } else if (s->chain != NIL) { 132 return(FALSE); 133 } else { 134 t = rtype(s->type); 135 if (t == NIL || t->class == FILET || t->class == SET) { 136 return(FALSE); 137 } else { 138 return(TRUE); 139 } 140 } 141 } 142 143 /* 144 * Test if the name of a symbol is uniquely defined or not. 145 */ 146 147 BOOLEAN isambiguous(s) 148 SYM *s; 149 { 150 SYM *t; 151 152 t = st_lookup(symtab, s->symbol); 153 if (t == NIL) { 154 panic("symbol name vanished"); 155 } 156 while (t != NIL && (s == t || !streq(t->symbol, s->symbol))) { 157 t = t->next_sym; 158 } 159 return t != NIL; 160 } 161