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