BSD 3 development
[unix-history] / usr / src / cmd / pi / var.c
CommitLineData
3e82dcf2
CH
1/* Copyright (c) 1979 Regents of the University of California */
2#
3/*
4 * pi - Pascal interpreter code translator
5 *
6 * Charles Haley, Bill Joy UCB
7 * Version 1.2 November 1978
8 */
9
10#include "whoami"
11#include "0.h"
12
13/*
14 * Declare variables of a var part. DPOFF1 is
15 * the local variable storage for all prog/proc/func
16 * modules aside from the block mark. The total size
17 * of all the local variables is entered into the
18 * size array.
19 */
20varbeg()
21{
22
23#ifndef PI1
24 if (parts & VPRT)
25 error("All variables must be declared in one var part");
26 parts |= VPRT;
27#endif
28#ifndef PI0
29 sizes[cbn].om_max = sizes[cbn].om_off = -DPOFF1;
30#endif
31 forechain = NIL;
32#ifdef PI0
33 send(REVVBEG);
34#endif
35}
36
37var(vline, vidl, vtype)
38#ifdef PI0
39 int vline, *vidl, *vtype;
40{
41 register struct nl *np;
42 register int *vl;
43
44 np = gtype(vtype);
45 line = vline;
46 for (vl = vidl; vl != NIL; vl = vl[2])
47 enter(defnl(vl[1], VAR, np, 0));
48 send(REVVAR, vline, vidl, vtype);
49}
50#else
51 int vline;
52 register int *vidl;
53 int *vtype;
54{
55 register struct nl *np;
56 register struct om *op;
57 long w;
58 int o2;
59 int *ovidl = vidl;
60
61 np = gtype(vtype);
62 line = vline;
63 w = (lwidth(np) + 1) &~ 1;
64 op = &sizes[cbn];
65 for (; vidl != NIL; vidl = vidl[2]) {
66 op->om_off -= w;
67 o2 = op->om_off;
68 enter(defnl(vidl[1], VAR, np, o2));
69 }
70# ifdef PTREE
71 {
72 pPointer *Vars;
73 pPointer Var = VarDecl( ovidl , vtype );
74
75 pSeize( PorFHeader[ nesting ] );
76 Vars = &( pDEF( PorFHeader[ nesting ] ).PorFVars );
77 *Vars = ListAppend( *Vars , Var );
78 pRelease( PorFHeader[ nesting ] );
79 }
80# endif
81}
82#endif
83
84varend()
85{
86
87 foredecl();
88#ifndef PI0
89 sizes[cbn].om_max = sizes[cbn].om_off;
90#else
91 send(REVVEND);
92#endif
93}
94
95/*
96 * Evening
97 */
98even(w)
99 register int w;
100{
101 if (w < 0)
102 return (w & ~1);
103 return ((w+1) & ~1);
104}
105
106/*
107 * Find the width of a type in bytes.
108 */
109width(np)
110 struct nl *np;
111{
112
113 return (lwidth(np));
114}
115
116long lwidth(np)
117 struct nl *np;
118{
119 register struct nl *p;
120 long w;
121
122 p = np;
123 if (p == NIL)
124 return (0);
125loop:
126 switch (p->class) {
127 case TYPE:
128 switch (nloff(p)) {
129 case TNIL:
130 return (2);
131 case TSTR:
132 case TSET:
133 panic("width");
134 default:
135 p = p->type;
136 goto loop;
137 }
138 case ARRAY:
139 return (aryconst(p, 0));
140 case PTR:
141 case FILET:
142 return ( sizeof ( int * ) );
143 case RANGE:
144 if (p->type == nl+TDOUBLE)
145#ifdef DEBUG
146 return (hp21mx ? 4 : 8);
147#else
148 return (8);
149#endif
150 case SCAL:
151 return (bytes(p->range[0], p->range[1]));
152 case SET:
153 setran(p->type);
154 return ( (set.uprbp>>3) + 1);
155 case STR:
156 case RECORD:
157 return ( p->value[NL_OFFS] );
158 default:
159 panic("wclass");
160 }
161}
162
163/*
164 * Return the width of an element
165 * of a n time subscripted np.
166 */
167long aryconst(np, n)
168 struct nl *np;
169 int n;
170{
171 register struct nl *p;
172 long s, d;
173
174 if ((p = np) == NIL)
175 return (NIL);
176 if (p->class != ARRAY)
177 panic("ary");
178 s = width(p->type);
179 /*
180 * Arrays of anything but characters are word aligned.
181 */
182 if (s & 1)
183 if (s != 1)
184 s++;
185 /*
186 * Skip the first n subscripts
187 */
188 while (n >= 0) {
189 p = p->chain;
190 n--;
191 }
192 /*
193 * Sum across remaining subscripts.
194 */
195 while (p != NIL) {
196 if (p->class != RANGE && p->class != SCAL)
197 panic("aryran");
198 d = p->range[1] - p->range[0] + 1;
199 s *= d;
200 p = p->chain;
201 }
202 return (s);
203}
204
205/*
206 * Find the lower bound of a set, and also its size in bits.
207 */
208setran(q)
209 struct nl *q;
210{
211 register lb, ub;
212 register struct nl *p;
213
214 p = q;
215 if (p == NIL)
216 return (NIL);
217 lb = p->range[0];
218 ub = p->range[1];
219 if (p->class != RANGE && p->class != SCAL)
220 panic("setran");
221 set.lwrb = lb;
222 /* set.(upperbound prime) = number of bits - 1; */
223 set.uprbp = ub-lb;
224}
225
226/*
227 * Return the number of bytes required to hold an arithmetic quantity
228 */
229bytes(lb, ub)
230 long lb, ub;
231{
232
233#ifndef DEBUG
234 if (lb < -32768 || ub > 32767)
235 return (4);
236 else if (lb < -128 || ub > 127)
237 return (2);
238#else
239 if (!hp21mx && (lb < -32768 || ub > 32767))
240 return (4);
241 if (lb < -128 || ub > 127)
242 return (2);
243#endif
244 else
245 return (1);
246}