148093Sbostic /*-
2*62149Sbostic * Copyright (c) 1980, 1993
3*62149Sbostic * The Regents of the University of California. All rights reserved.
448093Sbostic *
548093Sbostic * %sccs.include.redist.c%
622527Sdist */
75529Slinton
822527Sdist #ifndef lint
9*62149Sbostic static char sccsid[] = "@(#)printval.c 8.1 (Berkeley) 06/06/93";
1048093Sbostic #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
printval(s)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
printordinal(v,t)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
printrecord(s)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
printfield(s)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
printarray(a)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
printarray(a)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
prtreal(r)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