15529Slinton /* Copyright (c) 1982 Regents of the University of California */ 25529Slinton 3*11065Slinton static char sccsid[] = "@(#)printval.c 1.7 02/14/83"; 45529Slinton 55529Slinton /* 65529Slinton * Print out the value at the top of the stack using the given type. 75529Slinton */ 85529Slinton 95529Slinton #include "defs.h" 105529Slinton #include "sym.h" 115529Slinton #include "btypes.h" 125529Slinton #include "classes.h" 135529Slinton #include "tree.h" 145529Slinton #include "process.h" 155529Slinton #include "mappings.h" 165529Slinton #include "sym.rep" 175529Slinton 185529Slinton printval(s) 195529Slinton SYM *s; 205529Slinton { 215783Slinton SYM *t; 225783Slinton ADDRESS a; 235783Slinton int len; 245876Slinton double r; 255529Slinton 265783Slinton if (s->class == REF) { 275783Slinton s = s->type; 285783Slinton } 29*11065Slinton switch (s->class) { 305783Slinton case ARRAY: 315783Slinton t = rtype(s->type); 32*11065Slinton if (t == t_char || (t->class == RANGE && t->type == t_char)) { 335783Slinton len = size(s); 345783Slinton sp -= len; 355783Slinton printf("'%.*s'", len, sp); 365783Slinton break; 375783Slinton } else { 385783Slinton printarray(s); 395783Slinton } 405783Slinton break; 415529Slinton 425783Slinton case RECORD: 435783Slinton printrecord(s); 445783Slinton break; 455529Slinton 465783Slinton case VARNT: 475783Slinton error("can't print out variant records"); 485783Slinton break; 495529Slinton 505783Slinton case RANGE: 515783Slinton if (s == t_real) { 526085Slinton prtreal(pop(double)); 535783Slinton } else { 54*11065Slinton printordinal(popsmall(s), rtype(s->type)); 555783Slinton } 565783Slinton break; 575529Slinton 585783Slinton case FILET: 59*11065Slinton case PTR: 60*11065Slinton a = pop(ADDRESS); 61*11065Slinton if (a == 0) { 625783Slinton printf("nil"); 635783Slinton } else { 64*11065Slinton printf("0%o", a); 655783Slinton } 665783Slinton break; 675529Slinton 685783Slinton case FIELD: 695783Slinton error("missing record specification"); 705783Slinton break; 715529Slinton 72*11065Slinton case SCAL: 73*11065Slinton printordinal(popsmall(s), s); 745783Slinton break; 755529Slinton 765783Slinton case FPROC: 775783Slinton case FFUNC: 785783Slinton a = fparamaddr(pop(long)); 795783Slinton t = whatblock(a); 805783Slinton if (t == NIL) { 815783Slinton printf("(proc %d)", a); 825783Slinton } else { 835783Slinton printf("%s", t->symbol); 845783Slinton } 855783Slinton break; 865529Slinton 875783Slinton default: 885783Slinton if (s->class < BADUSE || s->class > VARNT) { 895783Slinton panic("printval: bad class %d", s->class); 905783Slinton } 915783Slinton error("don't know how to print a %s", classname(s)); 925783Slinton /* NOTREACHED */ 935783Slinton } 945529Slinton } 955529Slinton 965529Slinton /* 97*11065Slinton * Print out an ordinal value (either an integer, character, or 98*11065Slinton * an enumeration constant). 99*11065Slinton */ 100*11065Slinton 101*11065Slinton printordinal(v, t) 102*11065Slinton long v; 103*11065Slinton SYM *t; 104*11065Slinton { 105*11065Slinton BOOLEAN found; 106*11065Slinton SYM *c; 107*11065Slinton int iv; 108*11065Slinton 109*11065Slinton iv = v; 110*11065Slinton if (t->class == SCAL) { 111*11065Slinton c = t->chain; 112*11065Slinton while (c != NIL && c->symvalue.iconval != iv) { 113*11065Slinton c = c->chain; 114*11065Slinton } 115*11065Slinton if (c == NIL) { 116*11065Slinton printf("(scalar = %d)", iv); 117*11065Slinton } else { 118*11065Slinton printf("%s", c->symbol); 119*11065Slinton } 120*11065Slinton } else if (t == t_char) { 121*11065Slinton printf("'%c'", iv); 122*11065Slinton } else if (t == t_boolean) { 123*11065Slinton printf("%s", (iv == TRUE) ? "true" : "false"); 124*11065Slinton } else { 125*11065Slinton printf("%ld", v); 126*11065Slinton } 127*11065Slinton } 128*11065Slinton 129*11065Slinton /* 1305529Slinton * Print out the value of a record, field by field. 1315529Slinton */ 1325529Slinton 1335529Slinton LOCAL printrecord(s) 1345529Slinton SYM *s; 1355529Slinton { 1365783Slinton SYM *t; 1375529Slinton 1385783Slinton if ((t = s->chain) == NIL) { 1395783Slinton error("record has no fields"); 1405783Slinton } 1415783Slinton printf("("); 1425783Slinton sp -= size(s); 1435783Slinton printfield(t); 1445783Slinton printf(")"); 1455529Slinton } 1465529Slinton 1475529Slinton /* 1485529Slinton * Print out a field, first printing out other fields. 1495529Slinton * This is done because the fields are chained together backwards. 1505529Slinton */ 1515529Slinton 1525529Slinton LOCAL printfield(s) 1535529Slinton SYM *s; 1545529Slinton { 1555783Slinton STACK *savesp; 1565529Slinton 1575783Slinton if (s->chain != NIL) { 1585783Slinton printfield(s->chain); 1595783Slinton printf(", "); 1605783Slinton } 1615783Slinton printf("%s = ", s->symbol); 1625783Slinton savesp = sp; 1635783Slinton sp += (s->symvalue.offset + size(s->type)); 1645783Slinton printval(s->type); 1655783Slinton sp = savesp; 1665529Slinton } 1675529Slinton 1685529Slinton /* 1695529Slinton * Print out the contents of an array. 1705529Slinton * Haven't quite figured out what the best format is. 1715529Slinton * 1725529Slinton * This is rather inefficient. 1735529Slinton * 1745529Slinton * The "2*elsize" is there since "printval" drops the stack by elsize. 1755529Slinton */ 1765529Slinton 1775529Slinton LOCAL printarray(a) 1785529Slinton SYM *a; 1795529Slinton { 1805783Slinton STACK *savesp, *newsp; 1815783Slinton SYM *eltype; 1825783Slinton long elsize; 1835529Slinton 1845783Slinton savesp = sp; 1855783Slinton sp -= size(a); 1865783Slinton newsp = sp; 1875783Slinton eltype = a->type; 1885783Slinton elsize = size(eltype); 1895783Slinton printf("("); 1905783Slinton for (sp += elsize; sp <= savesp; sp += 2*elsize) { 1915783Slinton if (sp - elsize != newsp) { 1925783Slinton printf(", "); 1935529Slinton } 1945783Slinton printval(eltype); 1955783Slinton } 1965783Slinton sp = newsp; 1975783Slinton printf(")"); 1985529Slinton } 1995876Slinton 2005876Slinton /* 2015876Slinton * Print out the value of a real number. 2025876Slinton * Pascal notation is somewhat different that what one gets 2035876Slinton * from "%g" in printf. 2045876Slinton */ 2055876Slinton 2066085Slinton LOCAL prtreal(r) 2075876Slinton double r; 2085876Slinton { 2095876Slinton extern char *index(); 2105876Slinton char *p, buf[256]; 2115876Slinton 2125876Slinton sprintf(buf, "%g", r); 2135876Slinton if (buf[0] == '.') { 2145876Slinton printf("0%s", buf); 2155876Slinton } else if (buf[0] == '-' && buf[1] == '.') { 2165876Slinton printf("-0%s", &buf[1]); 2175876Slinton } else { 2185876Slinton printf("%s", buf); 2195876Slinton } 2205876Slinton if (index(buf, '.') == NIL) { 2215876Slinton printf(".0"); 2225876Slinton } 2235876Slinton } 224