/* Copyright (c) 1979 Regents of the University of California */
static char sccsid
[] = "@(#)stat.c 1.8 %G%";
for (sl
=r
; sl
!= NIL
; sl
=sl
[2])
register struct nl
*snlp
;
soffset
= sizes
[cbn
].curtmps
;
error("Unreachable statement");
* Free the temporary name list entries defined in
* expressions, e.g. STRs, and WITHPTRs from withs.
* free any temporaries allocated for this statement
* these come from strings and sets.
for (p
= gotos
[cbn
]; p
!= NIL
; p
= p
->chain
)
if ((p
->nl_flags
& NFORWD
) != 0) {
if (p
->value
[NL_GOLEV
] != NOTYET
)
if (p
->value
[NL_GOLEV
] > level
)
p
->value
[NL_GOLEV
] = level
;
if (p
->value
[NL_GOLEV
] != DEAD
)
if (p
->value
[NL_GOLEV
] > level
)
p
->value
[NL_GOLEV
] = DEAD
;
put(2, O_COUNT
, counter
);
putRV( PCPCOUNT
, 0 , counter
* sizeof (long) , NGLOBAL
, P2INT
);
putleaf( P2ICON
, 1 , 0 , P2INT
, 0 );
putop( P2ASG P2PLUS
, P2INT
);
putdot( filename
, line
);
* put out line number information for pdx
if ( line
!= lastline
) {
putleaf( P2ICON
, 0 , 0 , ADDTYPE( P2FTN
| P2INT
, P2PTR
)
putop( P2UNARY P2CALL
, P2INT
);
putdot( filename
, line
);
putRV( STMTCOUNT
, 0 , 0 , NGLOBAL
, P2INT
);
putleaf( P2ICON
, 1 , 0 , P2INT
, 0 );
putop( P2ASG P2PLUS
, P2INT
);
putdot( filename
, line
);
* With statement requires an extra word
* in automatic storage for each level of withing.
* These indirect pointers are initialized here, and
* the scoping effect of the with statement occurs
* because lookup examines the field names of the records
* associated with the WITHPTRs on the withlist.
for (p
= s
[2]; p
!= NIL
; p
= p
[2]) {
tempnlp
= tmpalloc(sizeof(int *), INT_TYP
, REGOK
);
put(2, O_LV
| cbn
<<8+INDX
, tempnlp
-> value
[ NL_OFFS
] );
putRV( 0 , cbn
, tempnlp
-> value
[ NL_OFFS
] ,
tempnlp
-> extra_flags
, P2PTR
|P2STRTY
);
r
= lvalue(p
[1], MOD
, LREQ
);
if (r
->class != RECORD
) {
error("Variable in with statement refers to %s, not to a record", nameof(r
));
r
= defnl(0, WITHPTR
, r
, tempnlp
-> value
[ NL_OFFS
] );
r
-> extra_flags
|= tempnlp
-> extra_flags
;
putop( P2ASSIGN
, P2PTR
|P2STRTY
);
putdot( filename
, line
);
* Asgnop's only function is
* to handle function variable
* assignments. All other assignment
* stuff is handled by asgnop1.
* the if below checks for unqualified lefthandside:
if (av
!= NIL
&& av
[0] == T_VAR
&& av
[3] == NIL
) {
if (p
!= NIL
&& p
->class == FVAR
) {
p
->nl_flags
|= NUSED
|NMOD
;
rvalue(r
[3], NIL
, RREQ
);
put(2, O_LV
| bn
<< 8+INDX
, (int)p
->value
[NL_OFFS
]);
if (isa(p
->type
, "i") && width(p
->type
) == 1)
* this should be the lvalue of the fvar,
* but since the second pass knows to use
* the address of the left operand of an
* assignment, what i want here is an rvalue.
* see note in funchdr about fvar allocation.
putRV( p
-> symbol
, bn
, p
-> value
[ NL_OFFS
] ,
p
-> extra_flags
, p2type( p
-> type
) );
asgnop1( r
, p
-> type
);
* Asgnop1 handles all assignments.
* If p is not nil then we are assigning
* to a function variable, otherwise
* we look the variable up ourselves.
p
= lvalue(r
[2], MOD
|ASGN
|NOUSE
, LREQ
);
* since the second pass knows that it should reference
* the lefthandside of asignments, what i need here is
p
= lvalue( r
[2] , MOD
|ASGN
|NOUSE
, RREQ
);
rvalue( r
[3] , NIL
, RREQ
);
* assigning to the return value, which is at least
* of width two since it resides on the stack
p1
= rvalue(r
[3], p
, RREQ
);
* if this is a scalar assignment,
* then i want to rvalue the righthandside.
* if this is a structure assignment,
* then i want an lvalue to the righthandside.
* that's what the intermediate form sez.
switch ( classify( p
) ) {
precheck( p
, "_RANG4" , "_RSNG4" );
p1
= rvalue( r
[3] , p
, RREQ
);
p1
= rvalue( r
[3] , p
, LREQ
);
if (incompat(p1
, p
, r
[3])) {
cerror("Type of expression clashed with type of variable in assignment");
gen(O_AS2
, O_AS2
, w
, width(p1
));
gen(O_AS2
, O_AS2
, w
, width(p1
));
putop( P2ASSIGN
, p2type( p
) );
putdot( filename
, line
);
putop( P2ASSIGN
, p2type( p
) );
putdot( filename
, line
);
putop( P2SCONV
, P2DOUBLE
);
putop( P2ASSIGN
, p2type( p
) );
putdot( filename
, line
);
putstrop( P2STASG
, p2type( p
)
, lwidth( p
) , align( p
) );
putdot( filename
, line
);
return (p
); /* Used by for statement */
* if expr then stat [ else stat ]
register l1
, l2
; /* l1 is start of else, l2 is end of else */
p
= rvalue(r
[2], NIL
, RREQ
);
error("Type of expression in if statement must be Boolean, not %s", nameof(p
));
l1
= put(2, O_IF
, getlab());
putleaf( P2ICON
, l1
, 0 , P2INT
, 0 );
putop( P2CBRANCH
, P2INT
);
putdot( filename
, line
);
l2
= put(2, O_TRA
, getlab());
noreach
= (noreach
&& nr
);
p
= rvalue(r
[2], NIL
, RREQ
);
error("Type of expression in while statement must be Boolean, not %s", nameof(p
));
putleaf( P2ICON
, l2
, 0 , P2INT
, 0 );
putop( P2CBRANCH
, P2INT
);
putdot( filename
, line
);
* repeat stat* until expr
p
= rvalue(r
[3], NIL
, RREQ
);
error("Until expression type must be Boolean, not %s, in repeat statement", nameof(p
));
putleaf( P2ICON
, l
, 0 , P2INT
, 0 );
putop( P2CBRANCH
, P2INT
);
putdot( filename
, line
);