122527Sdist /* 222527Sdist * Copyright (c) 1980 Regents of the University of California. 322527Sdist * All rights reserved. The Berkeley software License Agreement 422527Sdist * specifies the terms and conditions for redistribution. 522527Sdist */ 65529Slinton 722527Sdist #ifndef lint 8*30850Smckusick static char sccsid[] = "@(#)printval.c 5.2 (Berkeley) 04/07/87"; 922527Sdist #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; 41*30850Smckusick #ifdef tahoe 42*30850Smckusick downalignstack(); 43*30850Smckusick #endif 445783Slinton printf("'%.*s'", len, sp); 455783Slinton break; 465783Slinton } else { 475783Slinton printarray(s); 485783Slinton } 495783Slinton break; 505529Slinton 515783Slinton case RECORD: 525783Slinton printrecord(s); 535783Slinton break; 545529Slinton 555783Slinton case VARNT: 565783Slinton error("can't print out variant records"); 575783Slinton break; 585529Slinton 595783Slinton case RANGE: 605783Slinton if (s == t_real) { 616085Slinton prtreal(pop(double)); 625783Slinton } else { 6311065Slinton printordinal(popsmall(s), rtype(s->type)); 645783Slinton } 655783Slinton break; 665529Slinton 675783Slinton case FILET: 6811065Slinton case PTR: 6911065Slinton a = pop(ADDRESS); 7011065Slinton if (a == 0) { 715783Slinton printf("nil"); 725783Slinton } else { 7311065Slinton printf("0%o", a); 745783Slinton } 755783Slinton break; 765529Slinton 775783Slinton case FIELD: 785783Slinton error("missing record specification"); 795783Slinton break; 805529Slinton 8111065Slinton case SCAL: 8211065Slinton printordinal(popsmall(s), s); 835783Slinton break; 845529Slinton 855783Slinton case FPROC: 865783Slinton case FFUNC: 875783Slinton a = fparamaddr(pop(long)); 885783Slinton t = whatblock(a); 895783Slinton if (t == NIL) { 905783Slinton printf("(proc %d)", a); 915783Slinton } else { 925783Slinton printf("%s", t->symbol); 935783Slinton } 945783Slinton break; 955529Slinton 965783Slinton default: 975783Slinton if (s->class < BADUSE || s->class > VARNT) { 985783Slinton panic("printval: bad class %d", s->class); 995783Slinton } 1005783Slinton error("don't know how to print a %s", classname(s)); 1015783Slinton /* NOTREACHED */ 1025783Slinton } 1035529Slinton } 1045529Slinton 1055529Slinton /* 10611065Slinton * Print out an ordinal value (either an integer, character, or 10711065Slinton * an enumeration constant). 10811065Slinton */ 10911065Slinton 11011065Slinton printordinal(v, t) 11111065Slinton long v; 11211065Slinton SYM *t; 11311065Slinton { 11411065Slinton SYM *c; 11511065Slinton int iv; 11611065Slinton 11711065Slinton iv = v; 11811065Slinton if (t->class == SCAL) { 11911065Slinton c = t->chain; 12011065Slinton while (c != NIL && c->symvalue.iconval != iv) { 12111065Slinton c = c->chain; 12211065Slinton } 12311065Slinton if (c == NIL) { 12411065Slinton printf("(scalar = %d)", iv); 12511065Slinton } else { 12611065Slinton printf("%s", c->symbol); 12711065Slinton } 12811065Slinton } else if (t == t_char) { 12911065Slinton printf("'%c'", iv); 13011065Slinton } else if (t == t_boolean) { 13111065Slinton printf("%s", (iv == TRUE) ? "true" : "false"); 13211065Slinton } else { 13311065Slinton printf("%ld", v); 13411065Slinton } 13511065Slinton } 13611065Slinton 13711065Slinton /* 1385529Slinton * Print out the value of a record, field by field. 1395529Slinton */ 1405529Slinton 1415529Slinton LOCAL printrecord(s) 1425529Slinton SYM *s; 1435529Slinton { 1445783Slinton SYM *t; 1455529Slinton 1465783Slinton if ((t = s->chain) == NIL) { 1475783Slinton error("record has no fields"); 1485783Slinton } 1495783Slinton printf("("); 1505783Slinton sp -= size(s); 151*30850Smckusick #ifdef tahoe 152*30850Smckusick downalignstack(); 153*30850Smckusick #endif 1545783Slinton printfield(t); 1555783Slinton printf(")"); 1565529Slinton } 1575529Slinton 1585529Slinton /* 1595529Slinton * Print out a field, first printing out other fields. 1605529Slinton * This is done because the fields are chained together backwards. 1615529Slinton */ 1625529Slinton 1635529Slinton LOCAL printfield(s) 1645529Slinton SYM *s; 1655529Slinton { 1665783Slinton STACK *savesp; 1675529Slinton 1685783Slinton if (s->chain != NIL) { 1695783Slinton printfield(s->chain); 1705783Slinton printf(", "); 1715783Slinton } 1725783Slinton printf("%s = ", s->symbol); 1735783Slinton savesp = sp; 1745783Slinton sp += (s->symvalue.offset + size(s->type)); 175*30850Smckusick #ifdef tahoe 176*30850Smckusick alignstack(); 177*30850Smckusick #endif 1785783Slinton printval(s->type); 1795783Slinton sp = savesp; 1805529Slinton } 1815529Slinton 1825529Slinton /* 1835529Slinton * Print out the contents of an array. 1845529Slinton * Haven't quite figured out what the best format is. 1855529Slinton * 1865529Slinton * This is rather inefficient. 1875529Slinton * 1885529Slinton * The "2*elsize" is there since "printval" drops the stack by elsize. 1895529Slinton */ 1905529Slinton 191*30850Smckusick #ifdef tahoe 1925529Slinton LOCAL printarray(a) 1935529Slinton SYM *a; 1945529Slinton { 1955783Slinton STACK *savesp, *newsp; 1965783Slinton SYM *eltype; 1975783Slinton long elsize; 1985529Slinton 199*30850Smckusick savesp = (STACK *)(((int)sp + 3) & ~3); 200*30850Smckusick eltype = a->type; 201*30850Smckusick printf("("); 202*30850Smckusick elsize = size(eltype); 203*30850Smckusick if (eltype->class == ARRAY) 204*30850Smckusick savesp += elsize; 205*30850Smckusick if (elsize < sizeof(int)) { 206*30850Smckusick register char *cp = sp - ((size(a) + 3) & ~3); 207*30850Smckusick int psh; 208*30850Smckusick register char *cp1, *end = cp + size(a); 209*30850Smckusick register int savestack; 210*30850Smckusick 211*30850Smckusick while (cp < end) { 212*30850Smckusick psh = 0; 213*30850Smckusick cp1 = (char *)&psh + sizeof(int) - elsize; 214*30850Smckusick while (cp1 < (char *)&psh + sizeof psh) 215*30850Smckusick *cp1++ = *cp++; 216*30850Smckusick if (end - size(a) != cp - elsize) { 217*30850Smckusick printf(", "); 218*30850Smckusick } 219*30850Smckusick switch (elsize) { 220*30850Smckusick case sizeof(char): 221*30850Smckusick savestack = *(char *)sp; 222*30850Smckusick push(char, psh); 223*30850Smckusick printval(eltype); 224*30850Smckusick *(char *)sp = savestack; 225*30850Smckusick break; 226*30850Smckusick case sizeof(short): 227*30850Smckusick savestack = *(short *)sp; 228*30850Smckusick push(short, psh); 229*30850Smckusick printval(eltype); 230*30850Smckusick *(short *)sp = savestack; 231*30850Smckusick break; 232*30850Smckusick default: 233*30850Smckusick panic("bad size on runtime stack"); 234*30850Smckusick } 235*30850Smckusick } 236*30850Smckusick } else { 237*30850Smckusick sp -= size(a); 238*30850Smckusick downalignstack(); 239*30850Smckusick newsp = sp; 240*30850Smckusick for (sp += elsize, alignstack(); sp <= savesp; sp += 2*elsize) { 241*30850Smckusick if (sp - 2*elsize >= newsp) { 242*30850Smckusick printf(", "); 243*30850Smckusick } 244*30850Smckusick printval(eltype); 245*30850Smckusick if (eltype->class == ARRAY) { 246*30850Smckusick sp -= elsize; 247*30850Smckusick } 248*30850Smckusick } 249*30850Smckusick sp = newsp; 250*30850Smckusick } 251*30850Smckusick printf(")"); 252*30850Smckusick } 253*30850Smckusick #else 254*30850Smckusick 255*30850Smckusick LOCAL printarray(a) 256*30850Smckusick SYM *a; 257*30850Smckusick { 258*30850Smckusick STACK *savesp, *newsp; 259*30850Smckusick SYM *eltype; 260*30850Smckusick long elsize; 261*30850Smckusick 2625783Slinton savesp = sp; 263*30850Smckusick eltype = a->type; 264*30850Smckusick elsize = size(eltype); 2655783Slinton sp -= size(a); 2665783Slinton newsp = sp; 2675783Slinton printf("("); 2685783Slinton for (sp += elsize; sp <= savesp; sp += 2*elsize) { 2695783Slinton if (sp - elsize != newsp) { 2705783Slinton printf(", "); 2715529Slinton } 2725783Slinton printval(eltype); 2735783Slinton } 2745783Slinton sp = newsp; 2755783Slinton printf(")"); 2765529Slinton } 277*30850Smckusick #endif tahoe 2785876Slinton 2795876Slinton /* 2805876Slinton * Print out the value of a real number. 2815876Slinton * Pascal notation is somewhat different that what one gets 2825876Slinton * from "%g" in printf. 2835876Slinton */ 2845876Slinton 2856085Slinton LOCAL prtreal(r) 2865876Slinton double r; 2875876Slinton { 2885876Slinton extern char *index(); 289*30850Smckusick char buf[256]; 2905876Slinton 2915876Slinton sprintf(buf, "%g", r); 2925876Slinton if (buf[0] == '.') { 2935876Slinton printf("0%s", buf); 2945876Slinton } else if (buf[0] == '-' && buf[1] == '.') { 2955876Slinton printf("-0%s", &buf[1]); 2965876Slinton } else { 2975876Slinton printf("%s", buf); 2985876Slinton } 2995876Slinton if (index(buf, '.') == NIL) { 3005876Slinton printf(".0"); 3015876Slinton } 3025876Slinton } 303