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