Notes for week 11

Day 1.

More Three Address Code

  1. Consider the code generation for the assignment statement - S->ident := E.
    void AssignGen::generate(IdTable &idents,ThreeAddressCode &codeGen,
                              Array<StackNode*> &s,int &num)
    // S->ident := E 
    {
       StoreNode *left;
       StoreNode *right;
    
       left = (StoreNode*)(s[2]);  //left side of the assignment 
       right = (StoreNode*)(s[0]); //right side of the assignment 
       //	Here we check to see if the left side is defined.
       //	Right side already checked 
       String leftName = left->seeName();
       String rightName = right->seeName();
       delete  left;  //got the names no longer need nodes 
       delete  right;
       if  (idents.member(leftName)==-1)
       {
          cerr<<leftName.c_str();
          throw  " Idenifier not defined ";
       }
       String leftType = idents.getType(leftName);
       String rightType = idents.getType(rightName);
    
       if (leftType != rightType)
          adjustTypes(leftType,rightName,codeGen,idents);
       
       codeGen.gen(leftName + String(" := ") + rightName);
       num = 1;
       s[0] = new  StackNode(0);
    }
  2. Creating jumps the while loop statement S1-> "while" Mark C CondGoToMark "do" S1, you will need to generate a go to the point before C (marked by Mark) when you reduce. You will also have to fill in a conditional jump from before do (or at CondGoToMark). Before you reduce the while loop, Mark, C, CondGoToMark and the last S1 have been parsed than their nodes are in the stack. Recall that the item s[0] in array s of StackNode* is used to generate the new top of the stack. The generate functions for Mark->epsilon and CondGoToMark->epsilon which are called when Mark and CondGoToMark are pushed into the stack create jump nodes with addresses for the appropriate operation. At the time that Mark is processed, the location that the condition starts at is the next item.This is the address that will be filled in when the jump at the end of the loop is generated so it is stored in the JumpNode generated by the Mark handler. In the case of a conditional, you generate the code for the jump, but hold onto this location for backfill of the address later
    // Create a backfill mark
    // Mark -> epsilon 
    
    void BackFillGen::generate(IdTable &,ThreeAddressCode &codeGen,
                        Array<StackNode*> &s,int &num)
    {
       s[0] = new  JumpNode(0,codeGen.location()+1);
       num = 1;
    }
    
    //Generate a conditional go to after test of condition mark backfill location
    // CondGoToMark -> epsilon 
    void CondGotoGen::generate(IdTable &,ThreeAddressCode &codeGen,
                        Array<StackNode*> &s,int &num)
    {
       // Generate a goto on condition Stack top has the location holding
       // the condition. Jump if condition fails 
       StoreNode* temp = (StoreNode*)(s[0]);
       codeGen.gen(String("if not ")+temp->seeName()+String(" then goto "));
       //Record the location of this jump in the PStack for backfill later
       // s[0] used to send a pointer to the top of the stack do not delete. 
       s[0]=new  JumpNode(0,codeGen.location());
       num = 1;
    }
  3. You now know that the stack node corresponding to Mark contains the address of that you must jump back to. This is the code generated by this reduction. Remember the top of the stack was at the S1, so s[0] represents S1, s[1] represents do, s[2] represents CondGoToMark, s[3] represents c and s[4] represents Mark. This means the address you need for the goto is in s[4], and the address that has to be backfilled with the current code address is at s[2]. The rest of the code is boilerplate.
     
    // Generates one backfill and one GoTo the location at beginning of conditional
    // S1 ->"while" Mark C CondGoToMark "do" S1 
    void WhileGen::generate(IdTable &,ThreeAddressCode &codeGen,
                    Array<StackNode*> &s,int &num)
    {
       // Fill in the goto the beginning of the loop
       // Must reserve space before backfilling earlier
       // goto. Will fill in address when fifth thing is popped 
       JumpNode *mark =(JumpNode*)(s[4]);
       codeGen.gen(String("GoTo ")+mark->addressAsText());
       //s[0] S1, s[1] "do" 
       mark = (JumpNode*)(s[2]);//The backfill location is contained in Condmark 
       codeGen.backfill(mark->seeAddress(),codeGen.nextStep());
    
       // clear out the array 
       for (int i =0; i<num;i++)
          delete  s[i];
       s[0] = new  StackNode(0);
       num = 1;
    }