xref: /csrg-svn/usr.bin/pascal/src/lval.c (revision 15967)
1758Speter /* Copyright (c) 1979 Regents of the University of California */
2758Speter 
315932Smckusick #ifndef lint
4*15967Smckusick static char sccsid[] = "@(#)lval.c 1.12 02/08/84";
515932Smckusick #endif
6758Speter 
7758Speter #include "whoami.h"
8758Speter #include "0.h"
9758Speter #include "tree.h"
10758Speter #include "opcode.h"
11758Speter #include "objfmt.h"
1215932Smckusick #include "tree_ty.h"
13758Speter #ifdef PC
14758Speter #   include	"pc.h"
15758Speter #   include	"pcops.h"
16758Speter #endif PC
17758Speter 
18758Speter extern	int flagwas;
19758Speter /*
20758Speter  * Lvalue computes the address
21758Speter  * of a qualified name and
22758Speter  * leaves it on the stack.
23758Speter  * for pc, it can be asked for either an lvalue or an rvalue.
24758Speter  * the semantics are the same, only the code is different.
25758Speter  */
2615932Smckusick /*ARGSUSED*/
27758Speter struct nl *
2815932Smckusick lvalue(var, modflag , required )
2915932Smckusick 	struct tnode *var;
3015932Smckusick 	int	modflag;
31758Speter 	int	required;
32758Speter {
3315932Smckusick #ifdef OBJ
34758Speter 	register struct nl *p;
35758Speter 	struct nl *firstp, *lastp;
3615932Smckusick 	register struct tnode *c, *co;
37*15967Smckusick 	int f, o, s;
38758Speter 	/*
39758Speter 	 * Note that the local optimizations
40758Speter 	 * done here for offsets would more
41758Speter 	 * appropriately be done in put.
42758Speter 	 */
4315932Smckusick 	struct tnode	tr;	/* T_FIELD */
4415932Smckusick 	struct tnode	*tr_ptr;
4515932Smckusick 	struct tnode	l_node;
4615932Smckusick #endif
47758Speter 
4815932Smckusick 	if (var == TR_NIL) {
4915932Smckusick 		return (NLNIL);
50758Speter 	}
5115932Smckusick 	if (nowexp(var)) {
5215932Smckusick 		return (NLNIL);
53758Speter 	}
5415932Smckusick 	if (var->tag != T_VAR) {
55758Speter 		error("Variable required");	/* Pass mesgs down from pt of call ? */
5615932Smckusick 		return (NLNIL);
57758Speter 	}
58758Speter #	ifdef PC
59758Speter 		/*
60758Speter 		 *	pc requires a whole different control flow
61758Speter 		 */
6215932Smckusick 	    return pclvalue( var , modflag , required );
63758Speter #	endif PC
642122Smckusic #	ifdef OBJ
652122Smckusic 		/*
662122Smckusic 		 *	pi uses the rest of the function
672122Smckusic 		 */
6815932Smckusick 	firstp = p = lookup(var->var_node.cptr);
6915932Smckusick 	if (p == NLNIL) {
7015932Smckusick 		return (NLNIL);
71758Speter 	}
7215932Smckusick 	c = var->var_node.qual;
73758Speter 	if ((modflag & NOUSE) && !lptr(c)) {
74758Speter 		p->nl_flags = flagwas;
75758Speter 	}
76758Speter 	if (modflag & MOD) {
77758Speter 		p->nl_flags |= NMOD;
78758Speter 	}
79758Speter 	/*
80758Speter 	 * Only possibilities for p->class here
81758Speter 	 * are the named classes, i.e. CONST, TYPE
82758Speter 	 * VAR, PROC, FUNC, REF, or a WITHPTR.
83758Speter 	 */
8415932Smckusick 	tr_ptr = &l_node;
85758Speter 	switch (p->class) {
86758Speter 		case WITHPTR:
87758Speter 			/*
88758Speter 			 * Construct the tree implied by
89758Speter 			 * the with statement
90758Speter 			 */
9115932Smckusick 			l_node.tag = T_LISTPP;
9215932Smckusick 
9315932Smckusick 			/* the cast has got to go but until the node is figured
9415932Smckusick 			   out it stays */
9515932Smckusick 
9615932Smckusick 			tr_ptr->list_node.list = (&tr);
9715932Smckusick 			tr_ptr->list_node.next = var->var_node.qual;
9815932Smckusick 			tr.tag = T_FIELD;
9915932Smckusick 			tr.field_node.id_ptr = var->var_node.cptr;
10015932Smckusick 			c = tr_ptr; /* c is a ptr to a tnode */
101758Speter #			ifdef PTREE
102758Speter 			    /*
10315932Smckusick 			     * mung var->fields to say which field this T_VAR is
104758Speter 			     * for VarCopy
105758Speter 			     */
10615932Smckusick 
10715932Smckusick 			    /* problem! reclook returns struct nl* */
10815932Smckusick 
10915932Smckusick 			    var->var_node.fields = reclook( p -> type ,
11015932Smckusick 					    var->var_node.line_no );
111758Speter #			endif
112758Speter 			/* and fall through */
113758Speter 		case REF:
114758Speter 			/*
115758Speter 			 * Obtain the indirect word
116758Speter 			 * of the WITHPTR or REF
117758Speter 			 * as the base of our lvalue
118758Speter 			 */
11915932Smckusick 			(void) put(2, PTR_RV | bn << 8+INDX , (int)p->value[0] );
120758Speter 			f = 0;		/* have an lv on stack */
121758Speter 			o = 0;
122758Speter 			break;
123758Speter 		case VAR:
124*15967Smckusick 			if (p->type->class != CRANGE) {
125*15967Smckusick 			    f = 1;		/* no lv on stack yet */
126*15967Smckusick 			    o = p->value[0];
127*15967Smckusick 			} else {
128*15967Smckusick 			    error("Conformant array bound %s found where variable required", p->symbol);
129*15967Smckusick 			    return(NLNIL);
130*15967Smckusick 			}
131758Speter 			break;
132758Speter 		default:
133758Speter 			error("%s %s found where variable required", classes[p->class], p->symbol);
13415932Smckusick 			return (NLNIL);
135758Speter 	}
136758Speter 	/*
137758Speter 	 * Loop and handle each
138758Speter 	 * qualification on the name
139758Speter 	 */
14015932Smckusick 	if (c == TR_NIL && (modflag&ASGN) && ( p->value[NL_FORV] & FORVAR ) ) {
141758Speter 		error("Can't modify the for variable %s in the range of the loop", p->symbol);
14215932Smckusick 		return (NLNIL);
143758Speter 	}
144*15967Smckusick 	s = 0;		/* subscripts seen */
14515932Smckusick 	for (; c != TR_NIL; c = c->list_node.next) {
14615932Smckusick 		co = c->list_node.list; /* co is a ptr to a tnode */
14715932Smckusick 		if (co == TR_NIL) {
14815932Smckusick 			return (NLNIL);
149758Speter 		}
150758Speter 		lastp = p;
151758Speter 		p = p->type;
15215932Smckusick 		if (p == NLNIL) {
15315932Smckusick 			return (NLNIL);
154758Speter 		}
155*15967Smckusick 		/*
156*15967Smckusick 		 * If we haven't seen enough subscripts, and the next
157*15967Smckusick 		 * qualification isn't array reference, then it's an error.
158*15967Smckusick 		 */
159*15967Smckusick 		if (s && co->tag != T_ARY) {
160*15967Smckusick 			error("Too few subscripts (%d given, %d required)",
161*15967Smckusick 				s, p->value[0]);
162*15967Smckusick 		}
16315932Smckusick 		switch (co->tag) {
164758Speter 			case T_PTR:
165758Speter 				/*
166758Speter 				 * Pointer qualification.
167758Speter 				 */
168758Speter 				lastp->nl_flags |= NUSED;
169758Speter 				if (p->class != PTR && p->class != FILET) {
170758Speter 					error("^ allowed only on files and pointers, not on %ss", nameof(p));
171758Speter 					goto bad;
172758Speter 				}
173758Speter 				if (f) {
1742071Smckusic 				    if (p->class == FILET && bn != 0)
17515932Smckusick 				        (void) put(2, O_LV | bn <<8+INDX , o );
1762071Smckusic 				    else
1772071Smckusic 					/*
1782071Smckusic 					 * this is the indirection from
1792071Smckusic 					 * the address of the pointer
1802071Smckusic 					 * to the pointer itself.
1812071Smckusic 					 * kirk sez:
1822071Smckusic 					 * fnil doesn't want this.
1832071Smckusic 					 * and does it itself for files
1842071Smckusic 					 * since only it knows where the
1852071Smckusic 					 * actual window is.
1862071Smckusic 					 * but i have to do this for
1872071Smckusic 					 * regular pointers.
1882071Smckusic 					 * This is further complicated by
1892071Smckusic 					 * the fact that global variables
1902071Smckusic 					 * are referenced through pointers
1912071Smckusic 					 * on the stack. Thus an RV on a
1922071Smckusic 					 * global variable is the same as
1932071Smckusic 					 * an LV of a non-global one ?!?
1942071Smckusic 					 */
19515932Smckusick 				        (void) put(2, PTR_RV | bn <<8+INDX , o );
196758Speter 				} else {
197758Speter 					if (o) {
19815932Smckusick 					    (void) put(2, O_OFF, o);
199758Speter 					}
2002104Smckusic 				        if (p->class != FILET || bn == 0)
20115932Smckusick 					    (void) put(1, PTR_IND);
202758Speter 				}
203758Speter 				/*
204758Speter 				 * Pointer cannot be
205758Speter 				 * nil and file cannot
206758Speter 				 * be at end-of-file.
207758Speter 				 */
20815932Smckusick 				(void) put(1, p->class == FILET ? O_FNIL : O_NIL);
209758Speter 				f = o = 0;
210758Speter 				continue;
211758Speter 			case T_ARGL:
212758Speter 				if (p->class != ARRAY) {
213758Speter 					if (lastp == firstp) {
21415932Smckusick 						error("%s is a %s, not a function", var->var_node.cptr, classes[firstp->class]);
215758Speter 					} else {
216758Speter 						error("Illegal function qualificiation");
217758Speter 					}
21815932Smckusick 					return (NLNIL);
219758Speter 				}
220758Speter 				recovered();
221758Speter 				error("Pascal uses [] for subscripting, not ()");
222758Speter 			case T_ARY:
223758Speter 				if (p->class != ARRAY) {
224758Speter 					error("Subscripting allowed only on arrays, not on %ss", nameof(p));
225758Speter 					goto bad;
226758Speter 				}
227758Speter 				if (f) {
2282071Smckusic 					if (bn == 0)
2292071Smckusic 						/*
2302071Smckusic 						 * global variables are
2312071Smckusic 						 * referenced through pointers
2322071Smckusic 						 * on the stack
2332071Smckusic 						 */
23415932Smckusick 						(void) put(2, PTR_RV | bn<<8+INDX, o);
2352071Smckusic 					else
23615932Smckusick 						(void) put(2, O_LV | bn<<8+INDX, o);
237758Speter 				} else {
238758Speter 					if (o) {
23915932Smckusick 					    (void) put(2, O_OFF, o);
240758Speter 					}
241758Speter 				}
242*15967Smckusick 				switch(s = arycod(p,co->ary_node.expr_list,s)) {
243*15967Smckusick 					/*
244*15967Smckusick 					 * This is the number of subscripts seen
245*15967Smckusick 					 */
246758Speter 					case 0:
24715932Smckusick 						return (NLNIL);
248758Speter 					case -1:
249758Speter 						goto bad;
250758Speter 				}
251*15967Smckusick 				if (s == p->value[0]) {
252*15967Smckusick 					s = 0;
253*15967Smckusick 				} else {
254*15967Smckusick 					p = lastp;
255*15967Smckusick 				}
256758Speter 				f = o = 0;
257758Speter 				continue;
258758Speter 			case T_FIELD:
259758Speter 				/*
260758Speter 				 * Field names are just
261758Speter 				 * an offset with some
262758Speter 				 * semantic checking.
263758Speter 				 */
264758Speter 				if (p->class != RECORD) {
265758Speter 					error(". allowed only on records, not on %ss", nameof(p));
266758Speter 					goto bad;
267758Speter 				}
26815932Smckusick 				/* must define the field node!! */
26915932Smckusick 				if (co->field_node.id_ptr == NIL) {
27015932Smckusick 					return (NLNIL);
271758Speter 				}
27215932Smckusick 				p = reclook(p, co->field_node.id_ptr);
27315932Smckusick 				if (p == NLNIL) {
27415932Smckusick 					error("%s is not a field in this record", co->field_node.id_ptr);
275758Speter 					goto bad;
276758Speter 				}
277758Speter #				ifdef PTREE
278758Speter 				    /*
279758Speter 				     * mung co[3] to indicate which field
280758Speter 				     * this is for SelCopy
281758Speter 				     */
28215932Smckusick 				    co->field_node.nl_entry = p;
283758Speter #				endif
284758Speter 				if (modflag & MOD) {
285758Speter 					p->nl_flags |= NMOD;
286758Speter 				}
28715932Smckusick 				if ((modflag & NOUSE) == 0 ||
28815932Smckusick 				    lptr(c->list_node.next)) {
28915932Smckusick 				/* figure out what kind of node c is !! */
290758Speter 					p->nl_flags |= NUSED;
291758Speter 				}
292758Speter 				o += p->value[0];
293758Speter 				continue;
294758Speter 			default:
295758Speter 				panic("lval2");
296758Speter 		}
297758Speter 	}
298*15967Smckusick 	if (s) {
299*15967Smckusick 		error("Too few subscripts (%d given, %d required)",
300*15967Smckusick 			s, p->type->value[0]);
301*15967Smckusick 	}
302758Speter 	if (f) {
3032071Smckusic 		if (bn == 0)
3042071Smckusic 			/*
3052071Smckusic 			 * global variables are referenced through
3062071Smckusic 			 * pointers on the stack
3072071Smckusic 			 */
30815932Smckusick 			(void) put(2, PTR_RV | bn<<8+INDX, o);
3092071Smckusic 		else
31015932Smckusick 			(void) put(2, O_LV | bn<<8+INDX, o);
311758Speter 	} else {
312758Speter 		if (o) {
31315932Smckusick 		    (void) put(2, O_OFF, o);
314758Speter 		}
315758Speter 	}
316758Speter 	return (p->type);
317758Speter bad:
31815932Smckusick 	cerror("Error occurred on qualification of %s", var->var_node.cptr);
31915932Smckusick 	return (NLNIL);
3202122Smckusic #	endif OBJ
321758Speter }
322758Speter 
32315932Smckusick int lptr(c)
32415932Smckusick 	register struct tnode *c;
325758Speter {
32615932Smckusick 	register struct tnode *co;
327758Speter 
32815932Smckusick 	for (; c != TR_NIL; c = c->list_node.next) {
32915932Smckusick 		co = c->list_node.list;
33015932Smckusick 		if (co == TR_NIL) {
331758Speter 			return (NIL);
332758Speter 		}
33315932Smckusick 		switch (co->tag) {
334758Speter 
335758Speter 		case T_PTR:
336758Speter 			return (1);
337758Speter 		case T_ARGL:
338758Speter 			return (0);
339758Speter 		case T_ARY:
340758Speter 		case T_FIELD:
341758Speter 			continue;
342758Speter 		default:
343758Speter 			panic("lptr");
344758Speter 		}
345758Speter 	}
346758Speter 	return (0);
347758Speter }
348758Speter 
349758Speter /*
350758Speter  * Arycod does the
351758Speter  * code generation
352758Speter  * for subscripting.
353*15967Smckusick  * n is the number of
354*15967Smckusick  * subscripts already seen
355*15967Smckusick  * (CLN 09/13/83)
356758Speter  */
357*15967Smckusick int arycod(np, el, n)
358758Speter 	struct nl *np;
35915932Smckusick 	struct tnode *el;
360*15967Smckusick 	int n;
361758Speter {
362758Speter 	register struct nl *p, *ap;
3633890Smckusic 	long sub;
3643890Smckusic 	bool constsub;
36515932Smckusick 	extern bool constval();
36615932Smckusick 	int i, d;  /* v, v1;  these aren't used */
367758Speter 	int w;
368758Speter 
369758Speter 	p = np;
37015932Smckusick 	if (el == TR_NIL) {
371758Speter 		return (0);
372758Speter 	}
373758Speter 	d = p->value[0];
374*15967Smckusick 	for (i = 1; i <= n; i++) {
375*15967Smckusick 		p = p->chain;
376*15967Smckusick 	}
377758Speter 	/*
378758Speter 	 * Check each subscript
379758Speter 	 */
380*15967Smckusick 	for (i = n+1; i <= d; i++) {
38115932Smckusick 		if (el == TR_NIL) {
382*15967Smckusick 			return (i-1);
383758Speter 		}
384758Speter 		p = p->chain;
385*15967Smckusick 		if ((p->class != CRANGE) &&
386*15967Smckusick 			(constsub = constval(el->list_node.list))) {
3873890Smckusic 		    ap = con.ctype;
3883890Smckusic 		    sub = con.crval;
3893890Smckusic 		    if (sub < p->range[0] || sub > p->range[1]) {
39015932Smckusick 			error("Subscript value of %D is out of range", (char *) sub);
391758Speter 			return (0);
3923890Smckusic 		    }
3933890Smckusic 		    sub -= p->range[0];
3943890Smckusic 		} else {
3953890Smckusic #		    ifdef PC
3963890Smckusic 			precheck( p , "_SUBSC" , "_SUBSCZ" );
3973890Smckusic #		    endif PC
39815932Smckusick 		    ap = rvalue(el->list_node.list, NLNIL , RREQ );
3993890Smckusic 		    if (ap == NIL) {
4003890Smckusic 			    return (0);
4013890Smckusic 		    }
4023890Smckusic #		    ifdef PC
40310361Smckusick 			postcheck(p, ap);
40410361Smckusick 			sconv(p2type(ap),P2INT);
4053890Smckusic #		    endif PC
406758Speter 		}
40715932Smckusick 		if (incompat(ap, p->type, el->list_node.list)) {
408758Speter 			cerror("Array index type incompatible with declared index type");
409758Speter 			if (d != 1) {
41015932Smckusick 				cerror("Error occurred on index number %d", (char *) i);
411758Speter 			}
412758Speter 			return (-1);
413758Speter 		}
414*15967Smckusick 		if (p->class == CRANGE) {
415*15967Smckusick 			constsub = 0;
416*15967Smckusick 		} else {
417*15967Smckusick 			w = aryconst(np, i);
418*15967Smckusick 		}
419758Speter #		ifdef OBJ
4203890Smckusic 		    if (constsub) {
4213890Smckusic 			sub *= w;
4223890Smckusic 			if (sub != 0) {
42315933Smckusick 			    w = bytes(sub, sub);
42415932Smckusick 			    (void) put(2, w <= 2 ? O_CON2 : O_CON4, sub);
42515932Smckusick 			    (void) gen(NIL, T_ADD, sizeof(char *), w);
4263890Smckusic 			}
42715932Smckusick 			el = el->list_node.next;
4283890Smckusic 			continue;
4293890Smckusic 		    }
430*15967Smckusick 		    if (p->class == CRANGE) {
431*15967Smckusick 			putcbnds(p, 0);
432*15967Smckusick 			putcbnds(p, 1);
433*15967Smckusick 			putcbnds(p, 2);
434*15967Smckusick 		    } else if (opt('t') == 0) {
435758Speter 			    switch (w) {
436758Speter 			    case 8:
437758Speter 				    w = 6;
438758Speter 			    case 4:
439758Speter 			    case 2:
440758Speter 			    case 1:
44115932Smckusick 				    (void) put(2, (width(ap) != 4 ? O_INX2P2 : O_INX4P2) | (w & ~1) << 7, ( short ) p->range[0]);
44215932Smckusick 				    el = el->list_node.next;
443758Speter 				    continue;
444758Speter 			    }
445758Speter 		    }
446*15967Smckusick 		    if (p->class == CRANGE) {
447*15967Smckusick 			if (width(p) == 4) {
448*15967Smckusick 			    put(1, width(ap) != 4 ? O_VINX42 : O_VINX4);
449*15967Smckusick 			} else {
450*15967Smckusick 			    put(1, width(ap) != 4 ? O_VINX2 : O_VINX24);
451*15967Smckusick 			}
452*15967Smckusick 		    } else {
453*15967Smckusick 			put(4, width(ap) != 4 ? O_INX2 : O_INX4, w,
454*15967Smckusick 			    (short)p->range[0], (short)(p->range[1]));
455*15967Smckusick 		    }
45615932Smckusick 		    el = el->list_node.next;
4573890Smckusic 		    continue;
458758Speter #		endif OBJ
459758Speter #		ifdef PC
460758Speter 			/*
461758Speter 			 *	subtract off the lower bound
462758Speter 			 */
4633890Smckusic 		    if (constsub) {
4643890Smckusic 			sub *= w;
4653890Smckusic 			if (sub != 0) {
46615932Smckusick 			    putleaf( P2ICON , (int) sub , 0 , P2INT , (char *) 0 );
4673890Smckusic 			    putop(P2PLUS, ADDTYPE(p2type(np->type), P2PTR));
4683890Smckusic 			}
46915932Smckusick 			el = el->list_node.next;
4703890Smckusic 			continue;
4713890Smckusic 		    }
472*15967Smckusick 		    if (p->class == CRANGE) {
473758Speter 			/*
474*15967Smckusick 			 *	if conformant array, subtract off lower bound
475758Speter 			 */
476*15967Smckusick 			ap = p->nptr[0];
477*15967Smckusick 			putRV(ap->symbol, (ap->nl_block & 037), ap->value[0],
478*15967Smckusick 				ap->extra_flags, p2type( ap ) );
479*15967Smckusick 			putop( P2MINUS, P2INT );
480*15967Smckusick 			/*
481*15967Smckusick 			 *	and multiply by the width of the elements
482*15967Smckusick 			 */
483*15967Smckusick 			ap = p->nptr[2];
484*15967Smckusick 			putRV( 0 , (ap->nl_block & 037), ap->value[0],
485*15967Smckusick 				ap->extra_flags, p2type( ap ) );
486758Speter 			putop( P2MUL , P2INT );
487*15967Smckusick 		    } else {
488*15967Smckusick 			if ( p -> range[ 0 ] != 0 ) {
489*15967Smckusick 			    putleaf( P2ICON , (int) p -> range[0] , 0 , P2INT , (char *) 0 );
490*15967Smckusick 			    putop( P2MINUS , P2INT );
491*15967Smckusick 			}
492*15967Smckusick 			    /*
493*15967Smckusick 			     *	multiply by the width of the elements
494*15967Smckusick 			     */
495*15967Smckusick 			if ( w != 1 ) {
496*15967Smckusick 			    putleaf( P2ICON , w , 0 , P2INT , (char *) 0 );
497*15967Smckusick 			    putop( P2MUL , P2INT );
498*15967Smckusick 			}
499758Speter 		    }
500758Speter 			/*
501758Speter 			 *	and add it to the base address
502758Speter 			 */
503758Speter 		    putop( P2PLUS , ADDTYPE( p2type( np -> type ) , P2PTR ) );
50415932Smckusick 		el = el->list_node.next;
505758Speter #		endif PC
506758Speter 	}
50715932Smckusick 	if (el != TR_NIL) {
508*15967Smckusick 	    if (np->type->class != ARRAY) {
509758Speter 		do {
51015932Smckusick 			el = el->list_node.next;
511758Speter 			i++;
51215932Smckusick 		} while (el != TR_NIL);
51315932Smckusick 		error("Too many subscripts (%d given, %d required)", (char *) (i-1), (char *) d);
514758Speter 		return (-1);
515*15967Smckusick 	    } else {
516*15967Smckusick 		return(arycod(np->type, el, d));
517*15967Smckusick 	    }
518758Speter 	}
519*15967Smckusick 	return (d);
520758Speter }
521*15967Smckusick 
522*15967Smckusick #ifdef OBJ
523*15967Smckusick /*
524*15967Smckusick  * Put out the conformant array bounds (lower bound, upper bound or width)
525*15967Smckusick  * for conformant array type ctype.
526*15967Smckusick  * The value of i determines which is being put
527*15967Smckusick  * i = 0: lower bound, i=1: upper bound, i=2: width
528*15967Smckusick  */
529*15967Smckusick putcbnds(ctype, i)
530*15967Smckusick struct nl *ctype;
531*15967Smckusick int i;
532*15967Smckusick {
533*15967Smckusick 	switch(width(ctype->type)) {
534*15967Smckusick 	    case 1:
535*15967Smckusick 		put(2, O_RV1 | (ctype->nl_block & 037) << 8+INDX,
536*15967Smckusick 			(int)ctype->nptr[i]->value[0]);
537*15967Smckusick 		break;
538*15967Smckusick 	    case 2:
539*15967Smckusick 		put(2, O_RV2 | (ctype->nl_block & 037) << 8+INDX,
540*15967Smckusick 			(int)ctype->nptr[i]->value[0]);
541*15967Smckusick 		break;
542*15967Smckusick 	    case 4:
543*15967Smckusick 	    default:
544*15967Smckusick 		put(2, O_RV4 | (ctype->nl_block & 037) << 8+INDX,
545*15967Smckusick 			(int)ctype->nptr[i]->value[0]);
546*15967Smckusick 	}
547*15967Smckusick }
548*15967Smckusick #endif OBJ
549