1*22527Sdist /*
2*22527Sdist  * Copyright (c) 1980 Regents of the University of California.
3*22527Sdist  * All rights reserved.  The Berkeley software License Agreement
4*22527Sdist  * specifies the terms and conditions for redistribution.
5*22527Sdist  */
65529Slinton 
7*22527Sdist #ifndef lint
8*22527Sdist static char sccsid[] = "@(#)printval.c	5.1 (Berkeley) 06/06/85";
9*22527Sdist #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;
415783Slinton 		printf("'%.*s'", len, sp);
425783Slinton 		break;
435783Slinton 	    } else {
445783Slinton 		printarray(s);
455783Slinton 	    }
465783Slinton 	    break;
475529Slinton 
485783Slinton 	case RECORD:
495783Slinton 	    printrecord(s);
505783Slinton 	    break;
515529Slinton 
525783Slinton 	case VARNT:
535783Slinton 	    error("can't print out variant records");
545783Slinton 	    break;
555529Slinton 
565783Slinton 	case RANGE:
575783Slinton 	    if (s == t_real) {
586085Slinton 		prtreal(pop(double));
595783Slinton 	    } else {
6011065Slinton 		printordinal(popsmall(s), rtype(s->type));
615783Slinton 	    }
625783Slinton 	    break;
635529Slinton 
645783Slinton 	case FILET:
6511065Slinton 	case PTR:
6611065Slinton 	    a = pop(ADDRESS);
6711065Slinton 	    if (a == 0) {
685783Slinton 		printf("nil");
695783Slinton 	    } else {
7011065Slinton 		printf("0%o", a);
715783Slinton 	    }
725783Slinton 	    break;
735529Slinton 
745783Slinton 	case FIELD:
755783Slinton 	    error("missing record specification");
765783Slinton 	    break;
775529Slinton 
7811065Slinton 	case SCAL:
7911065Slinton 	    printordinal(popsmall(s), s);
805783Slinton 	    break;
815529Slinton 
825783Slinton 	case FPROC:
835783Slinton 	case FFUNC:
845783Slinton 	    a = fparamaddr(pop(long));
855783Slinton 	    t = whatblock(a);
865783Slinton 	    if (t == NIL) {
875783Slinton 		printf("(proc %d)", a);
885783Slinton 	    } else {
895783Slinton 		printf("%s", t->symbol);
905783Slinton 	    }
915783Slinton 	    break;
925529Slinton 
935783Slinton 	default:
945783Slinton 	    if (s->class < BADUSE || s->class > VARNT) {
955783Slinton 		panic("printval: bad class %d", s->class);
965783Slinton 	    }
975783Slinton 	    error("don't know how to print a %s", classname(s));
985783Slinton 	    /* NOTREACHED */
995783Slinton     }
1005529Slinton }
1015529Slinton 
1025529Slinton /*
10311065Slinton  * Print out an ordinal value (either an integer, character, or
10411065Slinton  * an enumeration constant).
10511065Slinton  */
10611065Slinton 
10711065Slinton printordinal(v, t)
10811065Slinton long v;
10911065Slinton SYM *t;
11011065Slinton {
11111065Slinton     BOOLEAN found;
11211065Slinton     SYM *c;
11311065Slinton     int iv;
11411065Slinton 
11511065Slinton     iv = v;
11611065Slinton     if (t->class == SCAL) {
11711065Slinton 	c = t->chain;
11811065Slinton 	while (c != NIL && c->symvalue.iconval != iv) {
11911065Slinton 	    c = c->chain;
12011065Slinton 	}
12111065Slinton 	if (c == NIL) {
12211065Slinton 	    printf("(scalar = %d)", iv);
12311065Slinton 	} else {
12411065Slinton 	    printf("%s", c->symbol);
12511065Slinton 	}
12611065Slinton     } else if (t == t_char) {
12711065Slinton 	printf("'%c'", iv);
12811065Slinton     } else if (t == t_boolean) {
12911065Slinton 	printf("%s", (iv == TRUE) ? "true" : "false");
13011065Slinton     } else {
13111065Slinton 	printf("%ld", v);
13211065Slinton     }
13311065Slinton }
13411065Slinton 
13511065Slinton /*
1365529Slinton  * Print out the value of a record, field by field.
1375529Slinton  */
1385529Slinton 
1395529Slinton LOCAL printrecord(s)
1405529Slinton SYM *s;
1415529Slinton {
1425783Slinton     SYM *t;
1435529Slinton 
1445783Slinton     if ((t = s->chain) == NIL) {
1455783Slinton 	error("record has no fields");
1465783Slinton     }
1475783Slinton     printf("(");
1485783Slinton     sp -= size(s);
1495783Slinton     printfield(t);
1505783Slinton     printf(")");
1515529Slinton }
1525529Slinton 
1535529Slinton /*
1545529Slinton  * Print out a field, first printing out other fields.
1555529Slinton  * This is done because the fields are chained together backwards.
1565529Slinton  */
1575529Slinton 
1585529Slinton LOCAL printfield(s)
1595529Slinton SYM *s;
1605529Slinton {
1615783Slinton     STACK *savesp;
1625529Slinton 
1635783Slinton     if (s->chain != NIL) {
1645783Slinton 	printfield(s->chain);
1655783Slinton 	printf(", ");
1665783Slinton     }
1675783Slinton     printf("%s = ", s->symbol);
1685783Slinton     savesp = sp;
1695783Slinton     sp += (s->symvalue.offset + size(s->type));
1705783Slinton     printval(s->type);
1715783Slinton     sp = savesp;
1725529Slinton }
1735529Slinton 
1745529Slinton /*
1755529Slinton  * Print out the contents of an array.
1765529Slinton  * Haven't quite figured out what the best format is.
1775529Slinton  *
1785529Slinton  * This is rather inefficient.
1795529Slinton  *
1805529Slinton  * The "2*elsize" is there since "printval" drops the stack by elsize.
1815529Slinton  */
1825529Slinton 
1835529Slinton LOCAL printarray(a)
1845529Slinton SYM *a;
1855529Slinton {
1865783Slinton     STACK *savesp, *newsp;
1875783Slinton     SYM *eltype;
1885783Slinton     long elsize;
1895529Slinton 
1905783Slinton     savesp = sp;
1915783Slinton     sp -= size(a);
1925783Slinton     newsp = sp;
1935783Slinton     eltype = a->type;
1945783Slinton     elsize = size(eltype);
1955783Slinton     printf("(");
1965783Slinton     for (sp += elsize; sp <= savesp; sp += 2*elsize) {
1975783Slinton 	if (sp - elsize != newsp) {
1985783Slinton 	    printf(", ");
1995529Slinton 	}
2005783Slinton 	printval(eltype);
2015783Slinton     }
2025783Slinton     sp = newsp;
2035783Slinton     printf(")");
2045529Slinton }
2055876Slinton 
2065876Slinton /*
2075876Slinton  * Print out the value of a real number.
2085876Slinton  * Pascal notation is somewhat different that what one gets
2095876Slinton  * from "%g" in printf.
2105876Slinton  */
2115876Slinton 
2126085Slinton LOCAL prtreal(r)
2135876Slinton double r;
2145876Slinton {
2155876Slinton     extern char *index();
2165876Slinton     char *p, buf[256];
2175876Slinton 
2185876Slinton     sprintf(buf, "%g", r);
2195876Slinton     if (buf[0] == '.') {
2205876Slinton 	printf("0%s", buf);
2215876Slinton     } else if (buf[0] == '-' && buf[1] == '.') {
2225876Slinton 	printf("-0%s", &buf[1]);
2235876Slinton     } else {
2245876Slinton 	printf("%s", buf);
2255876Slinton     }
2265876Slinton     if (index(buf, '.') == NIL) {
2275876Slinton 	printf(".0");
2285876Slinton     }
2295876Slinton }
230