1*48093Sbostic /*- 2*48093Sbostic * Copyright (c) 1980 The Regents of the University of California. 3*48093Sbostic * All rights reserved. 4*48093Sbostic * 5*48093Sbostic * %sccs.include.redist.c% 622527Sdist */ 75529Slinton 822527Sdist #ifndef lint 9*48093Sbostic static char sccsid[] = "@(#)printval.c 5.3 (Berkeley) 04/16/91"; 10*48093Sbostic #endif /* not lint */ 115529Slinton 125529Slinton /* 135529Slinton * Print out the value at the top of the stack using the given type. 145529Slinton */ 155529Slinton 165529Slinton #include "defs.h" 175529Slinton #include "sym.h" 185529Slinton #include "btypes.h" 195529Slinton #include "classes.h" 205529Slinton #include "tree.h" 215529Slinton #include "process.h" 225529Slinton #include "mappings.h" 235529Slinton #include "sym.rep" 245529Slinton 255529Slinton printval(s) 265529Slinton SYM *s; 275529Slinton { 285783Slinton SYM *t; 295783Slinton ADDRESS a; 305783Slinton int len; 315876Slinton double r; 325529Slinton 335783Slinton if (s->class == REF) { 345783Slinton s = s->type; 355783Slinton } 3611065Slinton switch (s->class) { 375783Slinton case ARRAY: 385783Slinton t = rtype(s->type); 3911065Slinton if (t == t_char || (t->class == RANGE && t->type == t_char)) { 405783Slinton len = size(s); 415783Slinton sp -= len; 4230850Smckusick #ifdef tahoe 4330850Smckusick downalignstack(); 4430850Smckusick #endif 455783Slinton printf("'%.*s'", len, sp); 465783Slinton break; 475783Slinton } else { 485783Slinton printarray(s); 495783Slinton } 505783Slinton break; 515529Slinton 525783Slinton case RECORD: 535783Slinton printrecord(s); 545783Slinton break; 555529Slinton 565783Slinton case VARNT: 575783Slinton error("can't print out variant records"); 585783Slinton break; 595529Slinton 605783Slinton case RANGE: 615783Slinton if (s == t_real) { 626085Slinton prtreal(pop(double)); 635783Slinton } else { 6411065Slinton printordinal(popsmall(s), rtype(s->type)); 655783Slinton } 665783Slinton break; 675529Slinton 685783Slinton case FILET: 6911065Slinton case PTR: 7011065Slinton a = pop(ADDRESS); 7111065Slinton if (a == 0) { 725783Slinton printf("nil"); 735783Slinton } else { 7411065Slinton printf("0%o", a); 755783Slinton } 765783Slinton break; 775529Slinton 785783Slinton case FIELD: 795783Slinton error("missing record specification"); 805783Slinton break; 815529Slinton 8211065Slinton case SCAL: 8311065Slinton printordinal(popsmall(s), s); 845783Slinton break; 855529Slinton 865783Slinton case FPROC: 875783Slinton case FFUNC: 885783Slinton a = fparamaddr(pop(long)); 895783Slinton t = whatblock(a); 905783Slinton if (t == NIL) { 915783Slinton printf("(proc %d)", a); 925783Slinton } else { 935783Slinton printf("%s", t->symbol); 945783Slinton } 955783Slinton break; 965529Slinton 975783Slinton default: 985783Slinton if (s->class < BADUSE || s->class > VARNT) { 995783Slinton panic("printval: bad class %d", s->class); 1005783Slinton } 1015783Slinton error("don't know how to print a %s", classname(s)); 1025783Slinton /* NOTREACHED */ 1035783Slinton } 1045529Slinton } 1055529Slinton 1065529Slinton /* 10711065Slinton * Print out an ordinal value (either an integer, character, or 10811065Slinton * an enumeration constant). 10911065Slinton */ 11011065Slinton 11111065Slinton printordinal(v, t) 11211065Slinton long v; 11311065Slinton SYM *t; 11411065Slinton { 11511065Slinton SYM *c; 11611065Slinton int iv; 11711065Slinton 11811065Slinton iv = v; 11911065Slinton if (t->class == SCAL) { 12011065Slinton c = t->chain; 12111065Slinton while (c != NIL && c->symvalue.iconval != iv) { 12211065Slinton c = c->chain; 12311065Slinton } 12411065Slinton if (c == NIL) { 12511065Slinton printf("(scalar = %d)", iv); 12611065Slinton } else { 12711065Slinton printf("%s", c->symbol); 12811065Slinton } 12911065Slinton } else if (t == t_char) { 13011065Slinton printf("'%c'", iv); 13111065Slinton } else if (t == t_boolean) { 13211065Slinton printf("%s", (iv == TRUE) ? "true" : "false"); 13311065Slinton } else { 13411065Slinton printf("%ld", v); 13511065Slinton } 13611065Slinton } 13711065Slinton 13811065Slinton /* 1395529Slinton * Print out the value of a record, field by field. 1405529Slinton */ 1415529Slinton 1425529Slinton LOCAL printrecord(s) 1435529Slinton SYM *s; 1445529Slinton { 1455783Slinton SYM *t; 1465529Slinton 1475783Slinton if ((t = s->chain) == NIL) { 1485783Slinton error("record has no fields"); 1495783Slinton } 1505783Slinton printf("("); 1515783Slinton sp -= size(s); 15230850Smckusick #ifdef tahoe 15330850Smckusick downalignstack(); 15430850Smckusick #endif 1555783Slinton printfield(t); 1565783Slinton printf(")"); 1575529Slinton } 1585529Slinton 1595529Slinton /* 1605529Slinton * Print out a field, first printing out other fields. 1615529Slinton * This is done because the fields are chained together backwards. 1625529Slinton */ 1635529Slinton 1645529Slinton LOCAL printfield(s) 1655529Slinton SYM *s; 1665529Slinton { 1675783Slinton STACK *savesp; 1685529Slinton 1695783Slinton if (s->chain != NIL) { 1705783Slinton printfield(s->chain); 1715783Slinton printf(", "); 1725783Slinton } 1735783Slinton printf("%s = ", s->symbol); 1745783Slinton savesp = sp; 1755783Slinton sp += (s->symvalue.offset + size(s->type)); 17630850Smckusick #ifdef tahoe 17730850Smckusick alignstack(); 17830850Smckusick #endif 1795783Slinton printval(s->type); 1805783Slinton sp = savesp; 1815529Slinton } 1825529Slinton 1835529Slinton /* 1845529Slinton * Print out the contents of an array. 1855529Slinton * Haven't quite figured out what the best format is. 1865529Slinton * 1875529Slinton * This is rather inefficient. 1885529Slinton * 1895529Slinton * The "2*elsize" is there since "printval" drops the stack by elsize. 1905529Slinton */ 1915529Slinton 19230850Smckusick #ifdef tahoe 1935529Slinton LOCAL printarray(a) 1945529Slinton SYM *a; 1955529Slinton { 1965783Slinton STACK *savesp, *newsp; 1975783Slinton SYM *eltype; 1985783Slinton long elsize; 1995529Slinton 20030850Smckusick savesp = (STACK *)(((int)sp + 3) & ~3); 20130850Smckusick eltype = a->type; 20230850Smckusick printf("("); 20330850Smckusick elsize = size(eltype); 20430850Smckusick if (eltype->class == ARRAY) 20530850Smckusick savesp += elsize; 20630850Smckusick if (elsize < sizeof(int)) { 20730850Smckusick register char *cp = sp - ((size(a) + 3) & ~3); 20830850Smckusick int psh; 20930850Smckusick register char *cp1, *end = cp + size(a); 21030850Smckusick register int savestack; 21130850Smckusick 21230850Smckusick while (cp < end) { 21330850Smckusick psh = 0; 21430850Smckusick cp1 = (char *)&psh + sizeof(int) - elsize; 21530850Smckusick while (cp1 < (char *)&psh + sizeof psh) 21630850Smckusick *cp1++ = *cp++; 21730850Smckusick if (end - size(a) != cp - elsize) { 21830850Smckusick printf(", "); 21930850Smckusick } 22030850Smckusick switch (elsize) { 22130850Smckusick case sizeof(char): 22230850Smckusick savestack = *(char *)sp; 22330850Smckusick push(char, psh); 22430850Smckusick printval(eltype); 22530850Smckusick *(char *)sp = savestack; 22630850Smckusick break; 22730850Smckusick case sizeof(short): 22830850Smckusick savestack = *(short *)sp; 22930850Smckusick push(short, psh); 23030850Smckusick printval(eltype); 23130850Smckusick *(short *)sp = savestack; 23230850Smckusick break; 23330850Smckusick default: 23430850Smckusick panic("bad size on runtime stack"); 23530850Smckusick } 23630850Smckusick } 23730850Smckusick } else { 23830850Smckusick sp -= size(a); 23930850Smckusick downalignstack(); 24030850Smckusick newsp = sp; 24130850Smckusick for (sp += elsize, alignstack(); sp <= savesp; sp += 2*elsize) { 24230850Smckusick if (sp - 2*elsize >= newsp) { 24330850Smckusick printf(", "); 24430850Smckusick } 24530850Smckusick printval(eltype); 24630850Smckusick if (eltype->class == ARRAY) { 24730850Smckusick sp -= elsize; 24830850Smckusick } 24930850Smckusick } 25030850Smckusick sp = newsp; 25130850Smckusick } 25230850Smckusick printf(")"); 25330850Smckusick } 25430850Smckusick #else 25530850Smckusick 25630850Smckusick LOCAL printarray(a) 25730850Smckusick SYM *a; 25830850Smckusick { 25930850Smckusick STACK *savesp, *newsp; 26030850Smckusick SYM *eltype; 26130850Smckusick long elsize; 26230850Smckusick 2635783Slinton savesp = sp; 26430850Smckusick eltype = a->type; 26530850Smckusick elsize = size(eltype); 2665783Slinton sp -= size(a); 2675783Slinton newsp = sp; 2685783Slinton printf("("); 2695783Slinton for (sp += elsize; sp <= savesp; sp += 2*elsize) { 2705783Slinton if (sp - elsize != newsp) { 2715783Slinton printf(", "); 2725529Slinton } 2735783Slinton printval(eltype); 2745783Slinton } 2755783Slinton sp = newsp; 2765783Slinton printf(")"); 2775529Slinton } 27830850Smckusick #endif tahoe 2795876Slinton 2805876Slinton /* 2815876Slinton * Print out the value of a real number. 2825876Slinton * Pascal notation is somewhat different that what one gets 2835876Slinton * from "%g" in printf. 2845876Slinton */ 2855876Slinton 2866085Slinton LOCAL prtreal(r) 2875876Slinton double r; 2885876Slinton { 2895876Slinton extern char *index(); 29030850Smckusick char buf[256]; 2915876Slinton 2925876Slinton sprintf(buf, "%g", r); 2935876Slinton if (buf[0] == '.') { 2945876Slinton printf("0%s", buf); 2955876Slinton } else if (buf[0] == '-' && buf[1] == '.') { 2965876Slinton printf("-0%s", &buf[1]); 2975876Slinton } else { 2985876Slinton printf("%s", buf); 2995876Slinton } 3005876Slinton if (index(buf, '.') == NIL) { 3015876Slinton printf(".0"); 3025876Slinton } 3035876Slinton } 304