/* @(#)var.c 2.2 SCCS id keyword */ /* Copyright (c) 1979 Regents of the University of California */ # /* * pi - Pascal interpreter code translator * * Charles Haley, Bill Joy UCB * Version 1.2 November 1978 */ #include "whoami" #include "0.h" #include "tree.h" #include "opcode.h" /* * Declare variables of a var part. DPOFF1 is * the local variable storage for all prog/proc/func * modules aside from the block mark. The total size * of all the local variables is entered into the * size array. */ varbeg() { #ifndef PI1 if (parts & VPRT) error("All variables must be declared in one var part"); parts |= VPRT; #endif #ifndef PI0 sizes[cbn].om_max = sizes[cbn].om_off = -DPOFF1; #endif forechain = NIL; #ifdef PI0 send(REVVBEG); #endif } var(vline, vidl, vtype) #ifdef PI0 int vline, *vidl, *vtype; { register struct nl *np; register int *vl; np = gtype(vtype); line = vline; for (vl = vidl; vl != NIL; vl = vl[2]) enter(defnl(vl[1], VAR, np, 0)); send(REVVAR, vline, vidl, vtype); #else int vline; register int *vidl; int *vtype; { register struct nl *np; register struct om *op; long w; int o2; np = gtype(vtype); line = vline; w = (lwidth(np) + 1) &~ 1; op = &sizes[cbn]; for (; vidl != NIL; vidl = vidl[2]) { op->om_off -= w; o2 = op->om_off; enter(defnl(vidl[1], VAR, np, o2)); } #endif } varend() { foredecl(); #ifndef PI0 sizes[cbn].om_max = sizes[cbn].om_off; #else send(REVVEND); #endif } /* * Evening */ even(w) register int w; { if (w < 0) return (w & ~1); return ((w+1) & ~1); } /* * Find the width of a type in bytes. */ width(np) struct nl *np; { return (lwidth(np)); } long lwidth(np) struct nl *np; { register struct nl *p; long w; p = np; if (p == NIL) return (0); loop: switch (p->class) { case TYPE: switch (nloff(p)) { case TNIL: return (2); case TSTR: case TSET: panic("width"); default: p = p->type; goto loop; } case ARRAY: return (aryconst(p, 0)); case PTR: case FILET: return ( sizeof ( int * ) ); case RANGE: if (p->type == nl+TDOUBLE) #ifdef DEBUG return (hp21mx ? 4 : 8); #else return (8); #endif case SCAL: return (bytes(p->range[0], p->range[1])); case SET: setran(p->type); return ( (set.uprbp>>3) + 1); case STR: case RECORD: return ( p->value[NL_OFFS] ); default: panic("wclass"); } } /* * Return the width of an element * of a n time subscripted np. */ long aryconst(np, n) struct nl *np; int n; { register struct nl *p; long s, d; if ((p = np) == NIL) return (NIL); if (p->class != ARRAY) panic("ary"); s = width(p->type); /* * Arrays of anything but characters are word aligned. */ if (s & 1) if (s != 1) s++; /* * Skip the first n subscripts */ while (n >= 0) { p = p->chain; n--; } /* * Sum across remaining subscripts. */ while (p != NIL) { if (p->class != RANGE && p->class != SCAL) panic("aryran"); d = p->range[1] - p->range[0] + 1; s *= d; p = p->chain; } return (s); } /* * Find the lower bound of a set, and also its size in bits. */ setran(q) struct nl *q; { register lb, ub; register struct nl *p; p = q; if (p == NIL) return (NIL); lb = p->range[0]; ub = p->range[1]; if (p->class != RANGE && p->class != SCAL) panic("setran"); set.lwrb = lb; /* set.(upperbound prime) = number of bits - 1; */ set.uprbp = ub-lb; } /* * Return the number of bytes required to hold an arithmetic quantity */ bytes(lb, ub) long lb, ub; { #ifndef DEBUG if (lb < -32768 || ub > 32767) return (4); else if (lb < -128 || ub > 127) return (2); #else if (!hp21mx && (lb < -32768 || ub > 32767)) return (4); if (lb < -128 || ub > 127) return (2); #endif else return (1); }