| Generating Code for Conditionals |
if conditional then stmt 1 else stmt 2Namely:
code to compute value of conditional
CMP #0, cond-result
BEQ ELSEPART2
code for stmt 1
BRA JOINUP2
ELSEPART2
code for stmt 2
JOINUP2
gen_if(node * ifstmt)
{ codelabel elselabel, joinlabel;
opdesc *condValue;
genlabel(&elselabel);
genlabel(&joinlabel);
condValue = genexpr(ifstmt->internal.child[0], FALSE);
output( "CMP", "#0", condValue );
outputBranch( "BEQ", &elselabel );
gen_stmt(ifstmt->internal.child[1]);
outputBranch( "JMP", &joinlabel );
place_label(&elselabel);
gen_stmt(ifstmt->internal.child[2]);
place_label(&joinlabel);
}
CMP X,#0
BGT SETTRUE
CLR D0
BRA JOINUP1
SETTRUE MOVE #1,DO
JOINUP1 ...
if ( x $>$ 0 ) {
stmt1
} else {
stmt2
}
yielding:
CMP X,#0
BGT SETTRUE
CLR D0
BRA JOINUP1
SETTRUE MOVE #1,DO
JOINUP1 CMP #0, D0
BEQ ELSEPART2
code for stmt1
BRA JOINUP2
ELSEPART2
code for stmt 2
JOINUP2
...
if x > 0 then stmt 1 else stmt 2
CMP X,#0
BLE ELSEPART
code for stmt 1
BRA JOINUP
ELSEPART
code for stmt 2
JOINUP ...
One generates code that leaves the value of the expression in a location described by the operand descriptor returned (genexpr). This is the routine we discussed last time. This routine will be called to process expressions used as parameters, in assignment statements, etc.
The other expression code generator will generate code to alter the flow of control based on the value of the expression (gen-cond-expr). This routine will be used to generate code for expressions used as conditions in loops and if statements.
gen_if(node * ifstmt)
{ codelabel elselabel, joinlabel;
genlabel(&elselabel);
genlabel(&joinlabel);
gen-cond-expr(ifstmt->internal.child[0],
FALSE,
&elselabel);
gen_stmt(ifstmt->internal.child[1]);
output( ``JMP'', &joinlabel );
place_label(&elselabel);
gen_stmt(ifstmt->internal.child[2]);
place_label(&joinlabel);
}
gencondexpr(node *expr, int sense, codelabel *target)
{
if ( expr's operator is an arithmetic one ) {
gencondarithmetic( expr, sense, target );
} else if ( expr's operator is a relational )
genrelational(expr,sense,target)
else
genlogical(expr,sense,target)
}
genrelational(node *expr, int sense, codelabel *target)
{ oprndesc *leftop, *rightop;
leftop = genexpr(expr->internal.child[0])
rightop = genexpr(expr->internal.child[1])
output "CMP leftop,rightop"
switch (expr->internal.type) {
case Neq:
if ( sense )
output "BEQ target"
else
output "BNE target"
break;
case Nne:
...
genlogical(node *expr, int sense, codelabel *target)
{
if (operator is 'and') {
genlabel( &fallthru );
if ( sense ) {
gencondexpr( left-sub-expr, FALSE , &fallthru);
} else
gencondexpr( left-sub-expr, FALSE , target );
gencondexpr( right-sub-expr, sense, target );
placelabel( &fallthru);
} else if ( operator is 'or' ) {
. . .
} else if ( operator is not ) {
. . .
gencondarithmetic(node *expr, int sense, codelabel *target)
{ oprndesc *valdesc;
valdesc = genexpr(expr)
output "CMP #0,valdesc"
if ( sense )
output "BNE target"
else
output "BEQ target"
}
| Generating Code for Conditionals |