/* Copyright (c) 1979 Regents of the University of California */
static char sccsid
[] = "@(#)lval.c 1.1 8/27/80";
* Lvalue computes the address
* of a qualified name and
* leaves it on the stack.
* for pc, it can be asked for either an lvalue or an rvalue.
* the semantics are the same, only the code is different.
lvalue(r
, modflag
, required
)
struct nl
*firstp
, *lastp
;
* Note that the local optimizations
* done here for offsets would more
* appropriately be done in put.
error("Variable required"); /* Pass mesgs down from pt of call ? */
* pc requires a whole different control flow
return pclvalue( r
, modflag
, required
);
firstp
= p
= lookup(r
[2]);
if ((modflag
& NOUSE
) && !lptr(c
)) {
* Only possibilities for p->class here
* are the named classes, i.e. CONST, TYPE
* VAR, PROC, FUNC, REF, or a WITHPTR.
* Construct the tree implied by
* mung r[4] to say which field this T_VAR is
r
[4] = reclook( p
-> type
, r
[2] );
* Obtain the indirect word
* as the base of our lvalue
put(2, PTR_RV
| bn
<< 8+INDX
, p
->value
[0] );
f
= 0; /* have an lv on stack */
f
= 1; /* no lv on stack yet */
error("%s %s found where variable required", classes
[p
->class], p
->symbol
);
* qualification on the name
if (c
== NIL
&& (modflag
&ASGN
) && p
->value
[NL_FORV
]) {
error("Can't modify the for variable %s in the range of the loop", p
->symbol
);
for (; c
!= NIL
; c
= c
[2]) {
lastp
->nl_flags
|= NUSED
;
if (p
->class != PTR
&& p
->class != FILET
) {
error("^ allowed only on files and pointers, not on %ss", nameof(p
));
put(2, PTR_RV
| bn
<<8+INDX
, o
);
put1(p
->class == FILET
? O_FNIL
: O_NIL
);
error("%s is a %s, not a function", r
[2], classes
[firstp
->class]);
error("Illegal function qualificiation");
error("Pascal uses [] for subscripting, not ()");
error("Subscripting allowed only on arrays, not on %ss", nameof(p
));
put2(O_LV
| bn
<<8+INDX
, o
);
switch (arycod(p
, co
[1])) {
if (p
->class != RECORD
) {
error(". allowed only on records, not on %ss", nameof(p
));
error("%s is not a field in this record", co
[1]);
* mung co[3] to indicate which field
if ((modflag
& NOUSE
) == 0 || lptr(c
[2])) {
put2(O_LV
| bn
<<8+INDX
, o
);
cerror("Error occurred on qualification of %s", r
[2]);
for (; c
!= NIL
; c
= c
[2]) {
register struct nl
*p
, *ap
;
for (i
= 1; i
<= d
; i
++) {
error("Too few subscripts (%d given, %d required)", i
-1, d
);
precheck( p
, "_SUBSC" , "_SUBSCZ" );
ap
= rvalue(el
[1], NLNIL
, RREQ
);
if (incompat(ap
, p
->type
, el
[1])) {
cerror("Array index type incompatible with declared index type");
cerror("Error occurred on index number %d", i
);
put2((width(ap
) != 4 ? O_INX2P2
: O_INX4P2
) | (w
& ~1) << 7, ( short ) p
->range
[0]);
put(4, width(ap
) != 4 ? O_INX2
: O_INX4
,w
,( short ) p
->range
[0],
( short ) ( p
->range
[1] - p
->range
[0] ) );
* subtract off the lower bound
if ( p
-> range
[ 0 ] != 0 ) {
putleaf( P2ICON
, p
-> range
[0] , 0 , P2INT
, 0 );
putop( P2MINUS
, P2INT
);
* multiply by the width of the elements
putleaf( P2ICON
, w
, 0 , P2INT
, 0 );
* and add it to the base address
putop( P2PLUS
, ADDTYPE( p2type( np
-> type
) , P2PTR
) );
error("Too many subscripts (%d given, %d required)", i
-1, d
);