15527Slinton /* Copyright (c) 1982 Regents of the University of California */ 25527Slinton 3*6580Slinton static char sccsid[] = "@(#)predicates.c 1.4 04/23/82"; 45527Slinton 55527Slinton /* 65527Slinton * The basic tests on a symbol. 75527Slinton */ 85527Slinton 95527Slinton #include "defs.h" 105527Slinton #include "sym.h" 115527Slinton #include "symtab.h" 125564Slinton #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 { 245885Slinton register SYM *t; 255527Slinton 265885Slinton for (t = s->func; t != NIL; t = t->chain) { 275885Slinton if (t == s) { 285885Slinton return(TRUE); 295527Slinton } 305885Slinton } 315885Slinton 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 { 415885Slinton return (BOOLEAN) s->class == REF; 425527Slinton } 435527Slinton 445527Slinton /* 455885Slinton * Test if a symbol is a variable (actually any addressible quantity 465885Slinton * with do). 475885Slinton */ 485885Slinton 495885Slinton BOOLEAN isvariable(s) 505885Slinton SYM *s; 515885Slinton { 525885Slinton return s->class == VAR || s->class == FVAR || s->class == REF; 535885Slinton } 545885Slinton 555885Slinton /* 565527Slinton * Test if a symbol is a block, e.g. function, procedure, or the 575527Slinton * main program. 585527Slinton */ 595527Slinton 605527Slinton BOOLEAN isblock(s) 615527Slinton register SYM *s; 625527Slinton { 635885Slinton return(s->class == FUNC || s->class == PROC || s->class == PROG); 645527Slinton } 655527Slinton 665527Slinton /* 675527Slinton * Test if a symbol is builtin, that is, a predefined type or 685527Slinton * reserved word. 695527Slinton */ 705527Slinton 715527Slinton BOOLEAN isbuiltin(s) 725527Slinton SYM *s; 735527Slinton { 745885Slinton return(s->blkno == 0 && s->class != PROG && s->class != VAR); 755527Slinton } 765527Slinton 775527Slinton /* 785527Slinton * Compatible tests if two types are compatible. The issue 795527Slinton * is complicated a bit by ranges. 805527Slinton * 815527Slinton * Integers and reals are not compatible since they cannot always be mixed. 825527Slinton */ 835527Slinton 845527Slinton BOOLEAN compatible(t1, t2) 855527Slinton register SYM *t1, *t2; 865527Slinton { 87*6580Slinton register BOOLEAN b; 88*6580Slinton 89*6580Slinton if (isvariable(t1)) { 90*6580Slinton t1 = t1->type; 91*6580Slinton } 92*6580Slinton if (isvariable(t2)) { 93*6580Slinton t2 = t2->type; 94*6580Slinton } 955885Slinton if (t1 == t2) { 96*6580Slinton b = TRUE; 97*6580Slinton } else { 98*6580Slinton t1 = rtype(t1); 99*6580Slinton t2 = rtype(t2); 100*6580Slinton if (t1->type == t2->type) { 101*6580Slinton if (t1->class == RANGE && t2->class == RANGE) { 102*6580Slinton b = TRUE; 103*6580Slinton } else if ((t1->class == SCAL || t1->class == CONST) && 104*6580Slinton (t2->class == SCAL || t2->class == CONST)) { 105*6580Slinton b = TRUE; 106*6580Slinton } else if (t1->type == t_char && 107*6580Slinton t1->class == ARRAY && t2->class == ARRAY) { 108*6580Slinton b = TRUE; 109*6580Slinton } else { 110*6580Slinton b = FALSE; 111*6580Slinton } 112*6580Slinton /* 113*6580Slinton * A kludge here for "nil". Should be handled better. 114*6580Slinton * Opens a pandora's box for integer/pointer compatibility. 115*6580Slinton */ 116*6580Slinton } else if ((t1->class == RANGE && t2->class == PTR) || 117*6580Slinton (t2->class == RANGE && t1->class == PTR)) { 118*6580Slinton b = TRUE; 119*6580Slinton } else { 120*6580Slinton b = FALSE; 1215527Slinton } 1225885Slinton } 123*6580Slinton return b; 1245527Slinton } 1255527Slinton 1265527Slinton /* 1275527Slinton * Predicate to test if a symbol should be printed. We don't print 1285527Slinton * files, for example, simply because there's no good way to do it. 1295527Slinton * The symbol must be within the given function. 1305527Slinton */ 1315527Slinton 1325527Slinton BOOLEAN should_print(s, f) 1335527Slinton SYM *s; 1345527Slinton SYM *f; 1355527Slinton { 1365885Slinton SYM *t; 1375527Slinton 1385885Slinton if (s->func != f || (s->class != VAR && s->class != FVAR)) { 1395885Slinton return(FALSE); 1405885Slinton } else if (s->chain != NIL) { 1415885Slinton return(FALSE); 1425885Slinton } else { 1435885Slinton t = rtype(s->type); 1445885Slinton if (t == NIL || t->class == FILET || t->class == SET) { 1455885Slinton return(FALSE); 1465527Slinton } else { 1475885Slinton return(TRUE); 1485527Slinton } 1495885Slinton } 1505527Slinton } 1515527Slinton 1525527Slinton /* 1535527Slinton * Test if the name of a symbol is uniquely defined or not. 1545527Slinton */ 1555527Slinton 1565527Slinton BOOLEAN isambiguous(s) 1575527Slinton SYM *s; 1585527Slinton { 1595885Slinton SYM *t; 1605527Slinton 1615885Slinton t = st_lookup(symtab, s->symbol); 1625885Slinton if (t == NIL) { 1635885Slinton panic("symbol name vanished"); 1645885Slinton } 1655885Slinton while (t != NIL && (s == t || !streq(t->symbol, s->symbol))) { 1665885Slinton t = t->next_sym; 1675885Slinton } 1685885Slinton return t != NIL; 1695527Slinton } 170