|  |  |  | 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 |