15529Slinton /* Copyright (c) 1982 Regents of the University of California */
25529Slinton 
3*5783Slinton static char sccsid[] = "@(#)printval.c 1.3 02/13/82";
45529Slinton 
55529Slinton /*
65529Slinton  * Print out the value at the top of the stack using the given type.
75529Slinton  */
85529Slinton 
95529Slinton #include "defs.h"
105529Slinton #include "sym.h"
115529Slinton #include "btypes.h"
125529Slinton #include "classes.h"
135529Slinton #include "tree.h"
145529Slinton #include "process.h"
155529Slinton #include "mappings.h"
165529Slinton #include "sym.rep"
175529Slinton 
185529Slinton printval(s)
195529Slinton SYM *s;
205529Slinton {
21*5783Slinton     SYM *t;
22*5783Slinton     ADDRESS a;
23*5783Slinton     int len;
245529Slinton 
25*5783Slinton     if (s->class == REF) {
26*5783Slinton 	s = s->type;
27*5783Slinton     }
28*5783Slinton     switch(s->class) {
29*5783Slinton 	case ARRAY:
30*5783Slinton 	    t = rtype(s->type);
31*5783Slinton 	    if (t==t_char || (t->class==RANGE && t->type==t_char)) {
32*5783Slinton 		len = size(s);
33*5783Slinton 		sp -= len;
34*5783Slinton 		printf("'%.*s'", len, sp);
35*5783Slinton 		break;
36*5783Slinton 	    } else {
37*5783Slinton 		printarray(s);
38*5783Slinton 	    }
39*5783Slinton 	    break;
405529Slinton 
41*5783Slinton 	case RECORD:
42*5783Slinton 	    printrecord(s);
43*5783Slinton 	    break;
445529Slinton 
45*5783Slinton 	case VARNT:
46*5783Slinton 	    error("can't print out variant records");
47*5783Slinton 	    break;
485529Slinton 
49*5783Slinton 	case RANGE:
50*5783Slinton 	    if (s == t_real) {
51*5783Slinton 		printf("%g", pop(double));
52*5783Slinton 	    } else if (s == t_char) {
53*5783Slinton 		printf("'%c'", pop(char));
54*5783Slinton 	    } else if (s == t_boolean) {
55*5783Slinton 		printf(pop(BOOLEAN)==TRUE ? "true" : "false");
56*5783Slinton 	    } else {
57*5783Slinton 		printf("%ld", popsmall(s));
58*5783Slinton 	    }
59*5783Slinton 	    break;
605529Slinton 
61*5783Slinton 	case FILET:
62*5783Slinton 	case PTR: {
63*5783Slinton 	    ADDRESS addr;
645529Slinton 
65*5783Slinton 	    addr = pop(ADDRESS);
66*5783Slinton 	    if (addr == 0) {
67*5783Slinton 		printf("nil");
68*5783Slinton 	    } else {
69*5783Slinton 		printf("0%o", addr);
70*5783Slinton 	    }
71*5783Slinton 	    break;
72*5783Slinton 	}
735529Slinton 
74*5783Slinton 	case FIELD:
75*5783Slinton 	    error("missing record specification");
76*5783Slinton 	    break;
775529Slinton 
78*5783Slinton 	case SCAL: {
79*5783Slinton 	    int scalar;
80*5783Slinton 	    BOOLEAN found;
815529Slinton 
82*5783Slinton 	    scalar = popsmall(s);
83*5783Slinton 	    found = FALSE;
84*5783Slinton 	    for (t = s->chain; t != NIL; t = t->chain) {
85*5783Slinton 		if (t->symvalue.iconval == scalar) {
86*5783Slinton 		    printf("%s", t->symbol);
87*5783Slinton 		    found = TRUE;
88*5783Slinton 		    break;
895529Slinton 		}
90*5783Slinton 	    }
91*5783Slinton 	    if (!found) {
92*5783Slinton 		printf("(scalar = %d)", scalar);
93*5783Slinton 	    }
94*5783Slinton 	    break;
95*5783Slinton 	}
965529Slinton 
97*5783Slinton 	case FPROC:
98*5783Slinton 	case FFUNC:
99*5783Slinton 	{
100*5783Slinton 	    ADDRESS a;
1015529Slinton 
102*5783Slinton 	    a = fparamaddr(pop(long));
103*5783Slinton 	    t = whatblock(a);
104*5783Slinton 	    if (t == NIL) {
105*5783Slinton 		printf("(proc %d)", a);
106*5783Slinton 	    } else {
107*5783Slinton 		printf("%s", t->symbol);
108*5783Slinton 	    }
109*5783Slinton 	    break;
110*5783Slinton 	}
1115529Slinton 
112*5783Slinton 	default:
113*5783Slinton 	    if (s->class < BADUSE || s->class > VARNT) {
114*5783Slinton 		panic("printval: bad class %d", s->class);
115*5783Slinton 	    }
116*5783Slinton 	    error("don't know how to print a %s", classname(s));
117*5783Slinton 	    /* NOTREACHED */
118*5783Slinton     }
1195529Slinton }
1205529Slinton 
1215529Slinton /*
1225529Slinton  * Print out the value of a record, field by field.
1235529Slinton  */
1245529Slinton 
1255529Slinton LOCAL printrecord(s)
1265529Slinton SYM *s;
1275529Slinton {
128*5783Slinton     SYM *t;
1295529Slinton 
130*5783Slinton     if ((t = s->chain) == NIL) {
131*5783Slinton 	error("record has no fields");
132*5783Slinton     }
133*5783Slinton     printf("(");
134*5783Slinton     sp -= size(s);
135*5783Slinton     printfield(t);
136*5783Slinton     printf(")");
1375529Slinton }
1385529Slinton 
1395529Slinton /*
1405529Slinton  * Print out a field, first printing out other fields.
1415529Slinton  * This is done because the fields are chained together backwards.
1425529Slinton  */
1435529Slinton 
1445529Slinton LOCAL printfield(s)
1455529Slinton SYM *s;
1465529Slinton {
147*5783Slinton     STACK *savesp;
1485529Slinton 
149*5783Slinton     if (s->chain != NIL) {
150*5783Slinton 	printfield(s->chain);
151*5783Slinton 	printf(", ");
152*5783Slinton     }
153*5783Slinton     printf("%s = ", s->symbol);
154*5783Slinton     savesp = sp;
155*5783Slinton     sp += (s->symvalue.offset + size(s->type));
156*5783Slinton     printval(s->type);
157*5783Slinton     sp = savesp;
1585529Slinton }
1595529Slinton 
1605529Slinton /*
1615529Slinton  * Print out the contents of an array.
1625529Slinton  * Haven't quite figured out what the best format is.
1635529Slinton  *
1645529Slinton  * This is rather inefficient.
1655529Slinton  *
1665529Slinton  * The "2*elsize" is there since "printval" drops the stack by elsize.
1675529Slinton  */
1685529Slinton 
1695529Slinton LOCAL printarray(a)
1705529Slinton SYM *a;
1715529Slinton {
172*5783Slinton     STACK *savesp, *newsp;
173*5783Slinton     SYM *eltype;
174*5783Slinton     long elsize;
1755529Slinton 
176*5783Slinton     savesp = sp;
177*5783Slinton     sp -= size(a);
178*5783Slinton     newsp = sp;
179*5783Slinton     eltype = a->type;
180*5783Slinton     elsize = size(eltype);
181*5783Slinton     printf("(");
182*5783Slinton     for (sp += elsize; sp <= savesp; sp += 2*elsize) {
183*5783Slinton 	if (sp - elsize != newsp) {
184*5783Slinton 	    printf(", ");
1855529Slinton 	}
186*5783Slinton 	printval(eltype);
187*5783Slinton     }
188*5783Slinton     sp = newsp;
189*5783Slinton     printf(")");
1905529Slinton }
191