date and time created 82/01/18 19:21:19 by linton
[unix-history] / usr / src / usr.bin / pascal / pdx / sym / printval.c
CommitLineData
204ed195
ML
1/* Copyright (c) 1982 Regents of the University of California */
2
3static char sccsid[] = "@(#)printval.c 1.1 %G%";
4
5/*
6 * Print out the value at the top of the stack using the given type.
7 */
8
9#include "defs.h"
10#include "sym.h"
11#include "btypes.h"
12#include "classes.h"
13#include "tree.h"
14#include "process.h"
15#include "mappings.h"
16#include "sym.rep"
17
18printval(s)
19SYM *s;
20{
21 SYM *t;
22 ADDRESS a;
23 int len;
24
25 if (s->class == REF) {
26 s = s->type;
27 }
28 switch(s->class) {
29 case ARRAY:
30 t = rtype(s->type);
31 if (t==t_char || (t->class==RANGE && t->type==t_char)) {
32 len = size(s);
33 sp -= len;
34 printf("'%s'", sp);
35 break;
36 } else {
37 printarray(s);
38 }
39 break;
40
41 case RECORD:
42 printrecord(s);
43 break;
44
45 case VARNT:
46 error("can't print out variant records");
47 break;
48
49 case RANGE:
50 if (s == t_real) {
51 printf("%g", pop(double));
52 } else if (s == t_char) {
53 printf("'%c'", pop(long));
54 } else if (s == t_boolean) {
55 printf(pop(BOOLEAN)==TRUE ? "true" : "false");
56 } else {
57 printf("%ld", pop(long));
58 }
59 break;
60
61 case FILET:
62 case PTR: {
63 ADDRESS addr;
64
65 addr = pop(ADDRESS);
66 if (addr == 0) {
67 printf("nil");
68 } else {
69 printf("0%o", addr);
70 }
71 break;
72 }
73
74 case FIELD:
75 error("missing record specification");
76 break;
77
78 case SCAL: {
79 int scalar;
80 BOOLEAN found;
81
82 scalar = pop(long);
83 found = FALSE;
84 for (t = s->chain; t != NIL; t = t->chain) {
85 if (t->symvalue.iconval == scalar) {
86 printf("%s", t->symbol);
87 found = TRUE;
88 break;
89 }
90 }
91 if (!found) {
92 printf("(scalar = %d)", scalar);
93 }
94 break;
95 }
96
97 case FPROC:
98 case FFUNC:
99 {
100 ADDRESS a;
101
102 a = fparamaddr(pop(long));
103 t = whatblock(a);
104 if (t == NIL) {
105 printf("(proc %d)", a);
106 } else {
107 printf("%s", t->symbol);
108 }
109 break;
110 }
111
112 default:
113 if (s->class < BADUSE || s->class > VARNT) {
114 panic("printval: bad class %d", s->class);
115 }
116 error("don't know how to print a %s", classname(s));
117 /* NOTREACHED */
118 }
119}
120
121/*
122 * Print out the value of a record, field by field.
123 */
124
125LOCAL printrecord(s)
126SYM *s;
127{
128 SYM *t;
129
130 if ((t = s->chain) == NIL) {
131 error("record has no fields");
132 }
133 printf("(");
134 sp -= size(s);
135 printfield(t);
136 printf(")");
137}
138
139/*
140 * Print out a field, first printing out other fields.
141 * This is done because the fields are chained together backwards.
142 */
143
144LOCAL printfield(s)
145SYM *s;
146{
147 STACK *savesp;
148
149 if (s->chain != NIL) {
150 printfield(s->chain);
151 printf(", ");
152 }
153 printf("%s = ", s->symbol);
154 savesp = sp;
155 sp += (s->symvalue.offset + size(s->type));
156 alignstack();
157 printval(s->type);
158 sp = savesp;
159}
160
161/*
162 * Print out the contents of an array.
163 * Haven't quite figured out what the best format is.
164 *
165 * This is rather inefficient.
166 *
167 * The "2*elsize" is there since "printval" drops the stack by elsize.
168 */
169
170LOCAL printarray(a)
171SYM *a;
172{
173 STACK *savesp, *newsp;
174 SYM *eltype;
175 long elsize;
176
177 savesp = sp;
178 sp -= size(a);
179 newsp = sp;
180 eltype = a->type;
181 elsize = size(eltype);
182 printf("(");
183 for (sp += elsize; sp <= savesp; sp += 2*elsize) {
184 if (sp - elsize != newsp) {
185 printf(", ");
186 }
187 printval(eltype);
188 }
189 sp = newsp;
190 printf(")");
191}