1*22527Sdist /* 2*22527Sdist * Copyright (c) 1980 Regents of the University of California. 3*22527Sdist * All rights reserved. The Berkeley software License Agreement 4*22527Sdist * specifies the terms and conditions for redistribution. 5*22527Sdist */ 65529Slinton 7*22527Sdist #ifndef lint 8*22527Sdist static char sccsid[] = "@(#)printval.c 5.1 (Berkeley) 06/06/85"; 9*22527Sdist #endif not lint 105529Slinton 115529Slinton /* 125529Slinton * Print out the value at the top of the stack using the given type. 135529Slinton */ 145529Slinton 155529Slinton #include "defs.h" 165529Slinton #include "sym.h" 175529Slinton #include "btypes.h" 185529Slinton #include "classes.h" 195529Slinton #include "tree.h" 205529Slinton #include "process.h" 215529Slinton #include "mappings.h" 225529Slinton #include "sym.rep" 235529Slinton 245529Slinton printval(s) 255529Slinton SYM *s; 265529Slinton { 275783Slinton SYM *t; 285783Slinton ADDRESS a; 295783Slinton int len; 305876Slinton double r; 315529Slinton 325783Slinton if (s->class == REF) { 335783Slinton s = s->type; 345783Slinton } 3511065Slinton switch (s->class) { 365783Slinton case ARRAY: 375783Slinton t = rtype(s->type); 3811065Slinton if (t == t_char || (t->class == RANGE && t->type == t_char)) { 395783Slinton len = size(s); 405783Slinton sp -= len; 415783Slinton printf("'%.*s'", len, sp); 425783Slinton break; 435783Slinton } else { 445783Slinton printarray(s); 455783Slinton } 465783Slinton break; 475529Slinton 485783Slinton case RECORD: 495783Slinton printrecord(s); 505783Slinton break; 515529Slinton 525783Slinton case VARNT: 535783Slinton error("can't print out variant records"); 545783Slinton break; 555529Slinton 565783Slinton case RANGE: 575783Slinton if (s == t_real) { 586085Slinton prtreal(pop(double)); 595783Slinton } else { 6011065Slinton printordinal(popsmall(s), rtype(s->type)); 615783Slinton } 625783Slinton break; 635529Slinton 645783Slinton case FILET: 6511065Slinton case PTR: 6611065Slinton a = pop(ADDRESS); 6711065Slinton if (a == 0) { 685783Slinton printf("nil"); 695783Slinton } else { 7011065Slinton printf("0%o", a); 715783Slinton } 725783Slinton break; 735529Slinton 745783Slinton case FIELD: 755783Slinton error("missing record specification"); 765783Slinton break; 775529Slinton 7811065Slinton case SCAL: 7911065Slinton printordinal(popsmall(s), s); 805783Slinton break; 815529Slinton 825783Slinton case FPROC: 835783Slinton case FFUNC: 845783Slinton a = fparamaddr(pop(long)); 855783Slinton t = whatblock(a); 865783Slinton if (t == NIL) { 875783Slinton printf("(proc %d)", a); 885783Slinton } else { 895783Slinton printf("%s", t->symbol); 905783Slinton } 915783Slinton break; 925529Slinton 935783Slinton default: 945783Slinton if (s->class < BADUSE || s->class > VARNT) { 955783Slinton panic("printval: bad class %d", s->class); 965783Slinton } 975783Slinton error("don't know how to print a %s", classname(s)); 985783Slinton /* NOTREACHED */ 995783Slinton } 1005529Slinton } 1015529Slinton 1025529Slinton /* 10311065Slinton * Print out an ordinal value (either an integer, character, or 10411065Slinton * an enumeration constant). 10511065Slinton */ 10611065Slinton 10711065Slinton printordinal(v, t) 10811065Slinton long v; 10911065Slinton SYM *t; 11011065Slinton { 11111065Slinton BOOLEAN found; 11211065Slinton SYM *c; 11311065Slinton int iv; 11411065Slinton 11511065Slinton iv = v; 11611065Slinton if (t->class == SCAL) { 11711065Slinton c = t->chain; 11811065Slinton while (c != NIL && c->symvalue.iconval != iv) { 11911065Slinton c = c->chain; 12011065Slinton } 12111065Slinton if (c == NIL) { 12211065Slinton printf("(scalar = %d)", iv); 12311065Slinton } else { 12411065Slinton printf("%s", c->symbol); 12511065Slinton } 12611065Slinton } else if (t == t_char) { 12711065Slinton printf("'%c'", iv); 12811065Slinton } else if (t == t_boolean) { 12911065Slinton printf("%s", (iv == TRUE) ? "true" : "false"); 13011065Slinton } else { 13111065Slinton printf("%ld", v); 13211065Slinton } 13311065Slinton } 13411065Slinton 13511065Slinton /* 1365529Slinton * Print out the value of a record, field by field. 1375529Slinton */ 1385529Slinton 1395529Slinton LOCAL printrecord(s) 1405529Slinton SYM *s; 1415529Slinton { 1425783Slinton SYM *t; 1435529Slinton 1445783Slinton if ((t = s->chain) == NIL) { 1455783Slinton error("record has no fields"); 1465783Slinton } 1475783Slinton printf("("); 1485783Slinton sp -= size(s); 1495783Slinton printfield(t); 1505783Slinton printf(")"); 1515529Slinton } 1525529Slinton 1535529Slinton /* 1545529Slinton * Print out a field, first printing out other fields. 1555529Slinton * This is done because the fields are chained together backwards. 1565529Slinton */ 1575529Slinton 1585529Slinton LOCAL printfield(s) 1595529Slinton SYM *s; 1605529Slinton { 1615783Slinton STACK *savesp; 1625529Slinton 1635783Slinton if (s->chain != NIL) { 1645783Slinton printfield(s->chain); 1655783Slinton printf(", "); 1665783Slinton } 1675783Slinton printf("%s = ", s->symbol); 1685783Slinton savesp = sp; 1695783Slinton sp += (s->symvalue.offset + size(s->type)); 1705783Slinton printval(s->type); 1715783Slinton sp = savesp; 1725529Slinton } 1735529Slinton 1745529Slinton /* 1755529Slinton * Print out the contents of an array. 1765529Slinton * Haven't quite figured out what the best format is. 1775529Slinton * 1785529Slinton * This is rather inefficient. 1795529Slinton * 1805529Slinton * The "2*elsize" is there since "printval" drops the stack by elsize. 1815529Slinton */ 1825529Slinton 1835529Slinton LOCAL printarray(a) 1845529Slinton SYM *a; 1855529Slinton { 1865783Slinton STACK *savesp, *newsp; 1875783Slinton SYM *eltype; 1885783Slinton long elsize; 1895529Slinton 1905783Slinton savesp = sp; 1915783Slinton sp -= size(a); 1925783Slinton newsp = sp; 1935783Slinton eltype = a->type; 1945783Slinton elsize = size(eltype); 1955783Slinton printf("("); 1965783Slinton for (sp += elsize; sp <= savesp; sp += 2*elsize) { 1975783Slinton if (sp - elsize != newsp) { 1985783Slinton printf(", "); 1995529Slinton } 2005783Slinton printval(eltype); 2015783Slinton } 2025783Slinton sp = newsp; 2035783Slinton printf(")"); 2045529Slinton } 2055876Slinton 2065876Slinton /* 2075876Slinton * Print out the value of a real number. 2085876Slinton * Pascal notation is somewhat different that what one gets 2095876Slinton * from "%g" in printf. 2105876Slinton */ 2115876Slinton 2126085Slinton LOCAL prtreal(r) 2135876Slinton double r; 2145876Slinton { 2155876Slinton extern char *index(); 2165876Slinton char *p, buf[256]; 2175876Slinton 2185876Slinton sprintf(buf, "%g", r); 2195876Slinton if (buf[0] == '.') { 2205876Slinton printf("0%s", buf); 2215876Slinton } else if (buf[0] == '-' && buf[1] == '.') { 2225876Slinton printf("-0%s", &buf[1]); 2235876Slinton } else { 2245876Slinton printf("%s", buf); 2255876Slinton } 2265876Slinton if (index(buf, '.') == NIL) { 2275876Slinton printf(".0"); 2285876Slinton } 2295876Slinton } 230