![]() | ![]() | ![]() | 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 |