Ejemplo n.º 1
0
/*-----------------------------------------------
 | expr_to_ir
 +---------------------------------------------*/
struct irinfo *expr_to_ir(struct ast *subtree)
{
    struct irinfo *left;
    struct irinfo *right;

    /* vars for dealing with loops */
    struct flow *tflow;
    struct ast *cond;
    struct ast *thendo;
    struct ast *elsedo;
    struct ast *forinit;
    struct ast *forupdate;

    char elselabel[25]= "else";
    char thenlabel[25]= "then";
    char endlabel[25]= "end";
    char testcondlabel[25]= "test";

    struct ast *dstat;
    struct decostat_list *dlist;
    int i;
    int tmpreg;

    struct irinfo *tcresult=  emalloc(sizeof(struct irinfo));



    if(subtree == NULL)
    {   printf("received a null subtree...\n");
        return NULL;
    }
    else
    {   printf("DEBUG: expr_to_ir: ENTERED with NON NULL subtree...\n");
    }


    /* figure out what type of node i'm looking at */
    printf("\texpr_to_ir called with expr type: %d\n", subtree->nodetype);



    switch(subtree->nodetype)
    {
        case DECL:
	   break;


        case DECOSTAT_LIST:
	   printf("found a decostat_list...\n\n\n");
	   i=0;
	   dlist= (struct decostat_list *)subtree;
	   do
	   {   dstat= dlist->decostat;
	       printf("calling expr_to_ir from expr_to_ir\n");
	       left= expr_to_ir(dstat);
	       printf("dstat_list_element_%d\n", ++i);
	   }while( (dlist= dlist->next) != NULL);

	   tcresult->nodetype= left->nodetype;
	   tcresult->regnum= left->regnum;

	   return tcresult;
	   break;


        case PARENTHESIZED_EXPR:
	   printf("found parenthsized expr... type of subtree->l: %d\n\n\n", subtree->l->nodetype);

	   left= expr_to_ir(subtree->l);

	   tcresult->nodetype= left->nodetype;
	   tcresult->regnum= left->regnum;

	   printf("DEBUG: PARENTHESIZED_EXPR returning tcresult nodetype %d and regnum %d\n",
	          tcresult->nodetype,
		  tcresult->regnum
                 );

	   return tcresult;
	   break;


        case INTEGER_CONSTANT:
           tcresult->nodetype= RVALUE;
           tcresult->regnum= ++regnum;

           irlist= irlist_front;
           while(irlist->next != NULL)
           {   irlist= irlist->next;
           }
           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= LOADCONSTANT;
           irlist->oprnd1= tcresult->regnum;

	   printf("DEBUG: loading constant: %d\n", (int)(long)((struct constant *)subtree)->value);
	   irlist->oprnd2= (int)(long)((struct constant *)subtree)->value;

           return tcresult;
	   break;




        case SIMPLE_DECLARATOR:
           tcresult->nodetype= LVALUE;
           tcresult->regnum= ++regnum;

	   printf("DEBUG: dealing with simple declarator, context clue is: %d\n", context_clue);

           irlist= irlist_front;
           while(irlist->next != NULL)
           {   irlist= irlist->next;
           }
           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;

	   if(context_clue != 0)
	   {   irlist->ircode= LOADWORD;
	       printf("DEBUG: since context clue is %d, doing loadword...\n", context_clue);
	   }
	   else
	   {   irlist->ircode= LOADADDRESS;
	       printf("DEBUG: since context clue is %d, doing loadaddress...\n", context_clue);
	   }
           irlist->oprnd1= tcresult->regnum;
           irlist->symptr= (struct declarator *)subtree;

           return tcresult;
           break;




        case OP_ASSIGNMENT:
	   printf("DEBUG: found an OP_ASSIGNMENT...\n\n\n");
	   left= expr_to_ir(subtree->l);
	   right= expr_to_ir(subtree->r);


	   if((left->nodetype == LVALUE) && (right->nodetype == RVALUE))
	   {   irlist= irlist_front;
               while(irlist->next != NULL)
               {   irlist= irlist->next;
               }

	       /* add node for storewordindirect */
               irlist->next= emalloc(sizeof(struct irnode));
	       irlist->next->prev= irlist;
               irlist= irlist->next;
               irlist->sid= ++irnodenum;
               irlist->ircode= STOREWORDINDIRECT;
               irlist->oprnd1= right->regnum;
	       irlist->oprnd2= left->regnum;
           }
	   else if((left->nodetype == LVALUE) && (right->nodetype == LVALUE))
	   {   irlist= irlist_front;
               while(irlist->next != NULL)
               {   irlist= irlist->next;
               }


	       /* add nodes for load/storewordindirect */
               irlist->next= emalloc(sizeof(struct irnode));
	       irlist->next->prev= irlist;
               irlist= irlist->next;
               irlist->sid= ++irnodenum;
               irlist->ircode= LOADWORDINDIRECT;
               irlist->oprnd1= ++regnum;
	       irlist->oprnd2= right->regnum;

               irlist->next= emalloc(sizeof(struct irnode));
	       irlist->next->prev= irlist;
               irlist= irlist->next;
               irlist->sid= ++irnodenum;
               irlist->ircode= STOREWORDINDIRECT;
               irlist->oprnd1=  regnum;
	       irlist->oprnd2=  left->regnum;

           }

	   break;



        case PLUS_SIGN:
	   context_clue= PLUS_SIGN;
	   printf("DEBUG: found an PLUS_SIGN...\n\n\n");
	   left= expr_to_ir(subtree->l);
	   right= expr_to_ir(subtree->r);

	   {   irlist= irlist_front;
               while(irlist->next != NULL)
               {   irlist= irlist->next;
               }

               irlist->next= emalloc(sizeof(struct irnode));
	       irlist->next->prev= irlist;
               irlist= irlist->next;
               irlist->sid= ++irnodenum;
               irlist->ircode= ADD;
               irlist->oprnd1= ++regnum;
	       irlist->oprnd2= left->regnum;
               irlist->oprnd3= right->regnum;

               tcresult->nodetype= RVALUE;
               tcresult->regnum= irlist->oprnd1;

           }
	   context_clue= 0;
	   return tcresult;
           break;





        case MINUS_SIGN:
           context_clue= MINUS_SIGN;
           printf("DEBUG: found a MINUS_SIGN...\n\n\n");
           left= expr_to_ir(subtree->l);
           right= expr_to_ir(subtree->r);

           {   irlist= irlist_front;
               while(irlist->next != NULL)
               {   irlist= irlist->next;
               }

               irlist->next= emalloc(sizeof(struct irnode));
               irlist->next->prev= irlist;
               irlist= irlist->next;
               irlist->sid= ++irnodenum;
               irlist->ircode= SUBTRACT;
               irlist->oprnd1= ++regnum;
               irlist->oprnd2= left->regnum;
               irlist->oprnd3= right->regnum;

               tcresult->nodetype= RVALUE;
               tcresult->regnum= irlist->oprnd1;

           }
           context_clue= 0;
           return tcresult;
           break;




        case OP_REMAINDER:
	   context_clue= OP_REMAINDER;
	   printf("DEBUG: found an OP_REMAINDER...\n\n\n");
	   left= expr_to_ir(subtree->l);
	   right= expr_to_ir(subtree->r);

	   {   irlist= irlist_front;
               while(irlist->next != NULL)
               {   irlist= irlist->next;
               }

               irlist->next= emalloc(sizeof(struct irnode));
	       irlist->next->prev= irlist;
               irlist= irlist->next;
               irlist->sid= ++irnodenum;
               irlist->ircode= REMAINDER;
               irlist->oprnd1= ++regnum;
	       irlist->oprnd2= left->regnum;
               irlist->oprnd3= right->regnum;

               tcresult->nodetype= RVALUE;
               tcresult->regnum= irlist->oprnd1;

           }
	   context_clue= 0;
	   return tcresult;
           break;




        case POSTINCREMENT_EXPR:
	   context_clue= POSTINCREMENT_EXPR;
	   printf("DEBUG: found a POSTINCREMENT_EXPR...\n\n\n");
	   printf("\tDEBUG: subtree->l type: %d\n", subtree->l->nodetype);
	   left= expr_to_ir(subtree->l);

	   {   irlist= irlist_front;
               while(irlist->next != NULL)
               {   irlist= irlist->next;
               }

               irlist->next= emalloc(sizeof(struct irnode));
	       irlist->next->prev= irlist;
               irlist= irlist->next;
               irlist->sid= ++irnodenum;
               irlist->ircode= ADD1;
	       tmpreg= ++regnum;
               irlist->oprnd1= tmpreg;
	       irlist->oprnd2= left->regnum;

               tcresult->nodetype= RVALUE;
               tcresult->regnum= irlist->oprnd1;
	       context_clue= 0;


               /* store result */
	       left= expr_to_ir(subtree->l);
               irlist->next= emalloc(sizeof(struct irnode));
	       irlist->next->prev= irlist;
               irlist= irlist->next;
               irlist->sid= ++irnodenum;
               irlist->ircode= STOREWORDINDIRECT;
               irlist->oprnd1= tmpreg;
	       irlist->oprnd2= left->regnum;

           }
	   return tcresult;
           break;





        case POSTDECREMENT_EXPR:
	   context_clue= POSTDECREMENT_EXPR;
	   printf("DEBUG: found a POSTDECREMENT_EXPR...\n\n\n");
	   printf("\tDEBUG: subtree->l type: %d\n", subtree->l->nodetype);
	   left= expr_to_ir(subtree->l);

	   {   irlist= irlist_front;
               while(irlist->next != NULL)
               {   irlist= irlist->next;
               }

               irlist->next= emalloc(sizeof(struct irnode));
	       irlist->next->prev= irlist;
               irlist= irlist->next;
               irlist->sid= ++irnodenum;
               irlist->ircode= SUB1;
	       tmpreg= ++regnum;
               irlist->oprnd1= tmpreg;
	       irlist->oprnd2= left->regnum;

               tcresult->nodetype= RVALUE;
               tcresult->regnum= irlist->oprnd1;
	       context_clue= 0;


               /* store result */
	       left= expr_to_ir(subtree->l);
               irlist->next= emalloc(sizeof(struct irnode));
	       irlist->next->prev= irlist;
               irlist= irlist->next;
               irlist->sid= ++irnodenum;
               irlist->ircode= STOREWORDINDIRECT;
               irlist->oprnd1= tmpreg;
	       irlist->oprnd2= left->regnum;

           }
	   return tcresult;
           break;





        case IF_STATEMENT:
           irlist= irlist_front;
           while(irlist->next != NULL)
           {   irlist= irlist->next;
           }

           /* retrieve if statement components
	   +-----------------------------------*/
           tflow= (struct flow *)subtree;
           cond= tflow->cond;
           thendo= tflow->thendo;

	  
	    /* print C code to IR file.
	    +---------------------------*/
	    printf("DEBUG: cond type: %d\n", cond->nodetype);
	    printf("DEBUG: thendo type: %d\n", thendo->nodetype);
	    clearstr(tmpstr);
	    sprintf(tmpstr,"#");
	    indent(tmpstr);
	    sprintf(&tmpstr[strlen(tmpstr)], "if(");
	    print_expr(cond->l,tmpstr);
	    sprintf(&tmpstr[strlen(tmpstr)], ")\n");
	    fprintf(irout,tmpstr); clearstr(tmpstr);


           /* Generate necessary labels
	   +----------------------------*/
	   sprintf(&elselabel[strlen(elselabel)], "%d", ++labelnum);
	   sprintf(&endlabel[strlen(endlabel)], "%d", ++labelnum);


           printf("\t\tDEBUG: type of condition: %d\n", cond->l->nodetype);
           printf("\t\tDEBUG: type of thendo: %d\n", thendo->nodetype);



	   /* create node for conditional statement
	   +-----------------------------------------*/
	   expr_to_ir(cond->l);
	   sprintf(&thenlabel[strlen(thenlabel)], "%d", labelnum);


	   /* create node for empty else block
	   +-----------------------------------------*/
           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= MIPSLABEL;
           strcpy(irlist->label, elselabel);

           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= JUMP;
           strcpy(irlist->label, endlabel);



           /* create nodes for then block */
           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= MIPSLABEL;
           strcpy(irlist->label, thenlabel);
	   expr_to_ir(thendo);



           /* create node for end block
	   +-----------------------------*/
           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= MIPSLABEL;
           strcpy(irlist->label, endlabel);


           break;









        case IF_ELSE_STATEMENT:
           irlist= irlist_front;
           while(irlist->next != NULL)
           {   irlist= irlist->next;
           }

           /* retrieve if statement components
	   +-----------------------------------*/
           tflow= (struct flow *)subtree;
           cond= tflow->cond;
           thendo= tflow->thendo;
	   elsedo= tflow->elsedo;


           /* Generate necessary labels
	   +----------------------------*/
	   sprintf(&elselabel[strlen(elselabel)], "%d", ++labelnum);
	   sprintf(&endlabel[strlen(endlabel)], "%d", ++labelnum);


           printf("\t\tDEBUG: type of condition: %d\n", cond->l->nodetype);
           printf("\t\tDEBUG: type of thendo: %d\n", thendo->nodetype);


	   /* create node for conditional statement
	   +-----------------------------------------*/
	   expr_to_ir(cond->l);
	   sprintf(&thenlabel[strlen(thenlabel)], "%d", labelnum);


	   /* create nodes for else block
	   +------------------------------*/
           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= MIPSLABEL;
           strcpy(irlist->label, elselabel);

	   expr_to_ir(elsedo);

           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= JUMP;
           strcpy(irlist->label, endlabel);



           /* create nodes for then block */
           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= MIPSLABEL;
           strcpy(irlist->label, thenlabel);
	   expr_to_ir(thendo);



           /* create node for end block
	   +-----------------------------*/
           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= MIPSLABEL;
           strcpy(irlist->label, endlabel);


           break;






        case FOR_STATEMENT:
           irlist= irlist_front;
           while(irlist->next != NULL)
           {   irlist= irlist->next;
           }

           /* retrieve for statement components
	   +-----------------------------------*/
           tflow     = (struct flow *)subtree;
	   forinit   = tflow->forinit;
           cond      = tflow->cond;
	   forupdate = tflow->forupdate;
           thendo    = tflow->thendo;


           /* Generate necessary labels
	   +----------------------------*/
	   sprintf(elselabel, "forelse%d", ++labelnum);
	   sprintf(&thenlabel[strlen(thenlabel)], "%d", ++labelnum);
	   sprintf(&endlabel[strlen(endlabel)], "%d", ++labelnum);
	   sprintf(&testcondlabel[strlen(testcondlabel)], "%d", ++labelnum);

           /*
           printf("\t\tDEBUG: type of forinit: %d\n", forinit->l->nodetype);
           printf("\t\tDEBUG: type of condition: %d\n", cond->l->nodetype);
           printf("\t\tDEBUG: type of thendo: %d\n", thendo->nodetype);
           printf("\t\tDEBUG: type of forupdate: %d\n", forupdate->l->nodetype);
	   */


	   /* create nodes for init statement
	   +-----------------------------------------*/
               irlist->next= emalloc(sizeof(struct irnode));
	       irlist->next->prev= irlist;
               irlist= irlist->next;
               irlist->sid= ++irnodenum;
               irlist->ircode= COMMENT;
               strncpy(irlist->label, "For Loop Initialization",49);

	       if(forinit != NULL)
	       {   expr_to_ir(forinit->l);
	       }



	   /* create nodes for conditional statement
	   +-----------------------------------------*/
           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= COMMENT;
           strncpy(irlist->label, "For Loop Test Condition",49);


           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= MIPSLABEL;
           strcpy(irlist->label, testcondlabel);

           forjump= atoi(&thenlabel[strlen(thenlabel)-1]);
	   if(cond != NULL)
	   {   expr_to_ir(cond->l);
	   }
	   forjump= 0;



	   /* create node for empty else block
	   +-----------------------------------------*/
           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= MIPSLABEL;
           strcpy(irlist->label, elselabel);

           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= JUMP;
           strcpy(irlist->label, endlabel);



           /* create nodes for then block
	   +--------------------------------*/
           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= MIPSLABEL;
           strcpy(irlist->label, thenlabel);
	   if(thendo != NULL)
	   {   expr_to_ir(thendo);
	   }



           /* create nodes for for loop update
	   +-----------------------------------*/
           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= COMMENT;
           strncpy(irlist->label, "For Loop Update Statement",49);

           if(forupdate != NULL)
	   {   expr_to_ir(forupdate->l);
	   }



           /* jump back to test condition
	   +-------------------------------*/
           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= JUMP;
           strcpy(irlist->label, testcondlabel);



           /* create node for end block
	   +-----------------------------*/
           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= MIPSLABEL;
           strcpy(irlist->label, endlabel);

           break;






        case WHILE_STATEMENT:
           irlist= irlist_front;
           while(irlist->next != NULL)
           {   irlist= irlist->next;
           }

           /* retrieve for statement components
	   +-----------------------------------*/
           tflow     = (struct flow *)subtree;
           cond      = tflow->cond;
           thendo    = tflow->thendo;



           /* Generate necessary labels
	   +----------------------------*/
	   sprintf(elselabel, "whileelse%d", ++labelnum);
	   sprintf(&thenlabel[strlen(thenlabel)], "%d", ++labelnum);
	   sprintf(&endlabel[strlen(endlabel)], "%d", ++labelnum);
	   sprintf(&testcondlabel[strlen(testcondlabel)], "%d", ++labelnum);



	   /* create nodes for conditional statement
	   +-----------------------------------------*/
           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= COMMENT;
           strncpy(irlist->label, "WHILE Loop Test Condition",49);


           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= MIPSLABEL;
           strcpy(irlist->label, testcondlabel);

           forjump= atoi(&thenlabel[strlen(thenlabel)-1]);
	   if(cond != NULL)
	   {   expr_to_ir(cond->l);
	   }
	   forjump= 0;



	   /* create node for empty else block
	   +-----------------------------------------*/
           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= MIPSLABEL;
           strcpy(irlist->label, elselabel);

           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= JUMP;
           strcpy(irlist->label, endlabel);



           /* create nodes for then block
	   +--------------------------------*/
           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= MIPSLABEL;
           strcpy(irlist->label, thenlabel);
	   if(thendo != NULL)
	   {   expr_to_ir(thendo);
	   }



           /* jump back to test condition
	   +-------------------------------*/
           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= JUMP;
           strcpy(irlist->label, testcondlabel);



           /* create node for end block
	   +-----------------------------*/
           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= MIPSLABEL;
           strcpy(irlist->label, endlabel);

           break;






        case RW_BREAK:
           printf("DEBUG: found a RW_BREAK...\n\n\n");
           ;
           char tlabel[50];

           {   irlist= irlist_front;
               while(irlist->next != NULL)
               {   irlist= irlist->next;
               }

               while( (strstr(irlist->label,"forelse")) == NULL  &&   (irlist != NULL))
               {   irlist=irlist->prev;
                   printf("rewinding from irnode %d\n", irlist->sid);
               }
               if(irlist != NULL)
               {   strcpy(tlabel,irlist->label);
                   printf("tlabel set to: %s\n", tlabel);
               }




               irlist= irlist_front;
               while(irlist->next != NULL)
               {   irlist= irlist->next;
               }

               irlist->next= emalloc(sizeof(struct irnode));
               irlist->next->prev= irlist;
               irlist= irlist->next;
               irlist->sid= ++irnodenum;
               irlist->ircode= JUMP;
               strcpy(irlist->label,tlabel);
          }
          break;






        case OP_EQUALITY:
           printf("DEBUG: found a OP_EQUALITY...\n\n\n");
	   context_clue= OP_EQUALITY;
           irlist= irlist_front;
           while(irlist->next != NULL)
           {   irlist= irlist->next;
           }

	   left   = expr_to_ir(subtree->l);
	   right  = expr_to_ir(subtree->r);

	   printf("DEBUG: expr_to_ir(): left regnum: %d\n", left->regnum);
	   printf("DEBUG: expr_to_ir(): right regnum: %d\n", right->regnum);

           char eqthenlabel[25]= "then";
	   sprintf(&eqthenlabel[strlen(eqthenlabel)], "%d", ++labelnum);


           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= BRANCH_EQ;
           irlist->oprnd1= left->regnum;
           irlist->oprnd2= right->regnum;
           strcpy(irlist->label, eqthenlabel);
	   context_clue= 0;

           tcresult->nodetype= RVALUE;
           tcresult->regnum= irlist->oprnd1;

	   return tcresult;
	   break;





        case GREATER_THAN_SYMBOL:
	   context_clue= CONDITIONAL_STATEMENT;
           irlist= irlist_front;
           while(irlist->next != NULL)
           {   irlist= irlist->next;
           }

	   printf("DEBUG: expr_to_ir(): received a greater than symbol....\n");
	   left   = expr_to_ir(subtree->l);
	   right  = expr_to_ir(subtree->r);

           char gtthenlabel[25]= "then";
	   sprintf(&gtthenlabel[strlen(gtthenlabel)], "%d", (forjump > 0)? forjump : ++labelnum);


           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= BRANCH_GT;
           irlist->oprnd1= left->regnum;
           irlist->oprnd2= right->regnum;
           strcpy(irlist->label, gtthenlabel);
	   context_clue= 0;
	   break;






        case OP_RELATIONAL_GTE:
	   context_clue= CONDITIONAL_STATEMENT;
           irlist= irlist_front;
           while(irlist->next != NULL)
           {   irlist= irlist->next;
           }

	   printf("DEBUG: expr_to_ir(): received a greater than symbol....\n");
	   left   = expr_to_ir(subtree->l);
	   right  = expr_to_ir(subtree->r);

           char gtethenlabel[25]= "then";
	   sprintf(&gtethenlabel[strlen(gtethenlabel)], "%d", (forjump > 0)? forjump : ++labelnum);


           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= BRANCH_GTE;
           irlist->oprnd1= left->regnum;
           irlist->oprnd2= right->regnum;
           strcpy(irlist->label, gtethenlabel);
	   context_clue= 0;
	   break;






        case OP_RELATIONAL_LT:
	   context_clue= OP_RELATIONAL_LT;
           irlist= irlist_front;
           while(irlist->next != NULL)
           {   irlist= irlist->next;
           }

	   printf("DEBUG: expr_to_ir(): received a greater than symbol....\n");
	   left   = expr_to_ir(subtree->l);
	   right  = expr_to_ir(subtree->r);

           char ltthenlabel[25]= "then";
	   sprintf(&ltthenlabel[strlen(ltthenlabel)], "%d", (forjump > 0)? forjump : ++labelnum);


           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= BRANCH_LT;
           irlist->oprnd1= left->regnum;
           irlist->oprnd2= right->regnum;
           strcpy(irlist->label, ltthenlabel);
	   context_clue= 0;
	   break;








        case OP_RELATIONAL_LTE:
	   context_clue= OP_RELATIONAL_LTE;
           irlist= irlist_front;
           while(irlist->next != NULL)
           {   irlist= irlist->next;
           }

	   printf("DEBUG: expr_to_ir(): received a greater than symbol....\n");
	   left   = expr_to_ir(subtree->l);
	   right  = expr_to_ir(subtree->r);

           char ltethenlabel[25]= "then";
	   sprintf(&ltethenlabel[strlen(ltethenlabel)], "%d", (forjump > 0)? forjump : ++labelnum);


           irlist->next= emalloc(sizeof(struct irnode));
	   irlist->next->prev= irlist;
           irlist= irlist->next;
           irlist->sid= ++irnodenum;
           irlist->ircode= BRANCH_LTE;
           irlist->oprnd1= left->regnum;
           irlist->oprnd2= right->regnum;
           strcpy(irlist->label, ltethenlabel);
	   context_clue= 0;
	   break;





        case COMPOUND_STATEMENT:
	   printf("DEBUG: expr_to_ir() called with compound statement  ...\n");
	   printf("\tDEBUG: subtree type: %d\n", subtree->nodetype);
	   compound_to_ir(subtree);
	   break;





        case FUNCTION_CALL:
	   ;
	   char funcname[40];
	   struct declarator *d= (struct declarator *)subtree->l;
	   struct parameter_list *plist;
	   plist=d->plist;
           if(d->nodetype == SIMPLE_DECLARATOR)
           {   strcpy(funcname,d->id);
           }
           else
           {   strcpy(funcname,d->adeclarator->id);
           }
	   printf("DEBUG: expr_to_ir FUNCTION CALL: %s\n", funcname);


	   /* If this is a built-in function...
	   +-----------------------------------------*/
	   if( (!strcmp(funcname,"printint"))      ||
               (!strcmp(funcname,"printstring"))   ||
               (!strcmp(funcname,"readint"))
	     )
	   {
	       /* printint function...
	       +-------------------------*/
	       if(! strcmp(funcname,"printint"))
	       {   printf("printint invoked...\n");
	           irlist= irlist_front;
                   while(irlist->next != NULL)
                   {   irlist= irlist->next;
                   }

	           /* add nodes for printint */
                   irlist->next= emalloc(sizeof(struct irnode));
	           irlist->next->prev= irlist;
                   irlist= irlist->next;
                   irlist->sid= ++irnodenum;
                   irlist->ircode= PRINTINT;

                   irlist->next= emalloc(sizeof(struct irnode));
	           irlist->next->prev= irlist;
                   irlist= irlist->next;
                   irlist->sid= ++irnodenum;
                   irlist->ircode= LOADWORD;
                   irlist->oprnd1= SYSCALL_ARG_REG;
	           irlist->symptr= (struct declarator *)subtree->r->l;

                   irlist->next= emalloc(sizeof(struct irnode));
	           irlist->next->prev= irlist;
                   irlist= irlist->next;
                   irlist->sid= ++irnodenum;
                   irlist->ircode= SYSCALL;
	       }


	       /* printstring function...
	       +--------------------------*/
	       if(! strcmp(funcname,"printstring"))
	       {
	           /* Retrieve parameter
		   +----------------------*/
		   struct constant *k= (struct constant *)subtree->r->l;
		   char *param= k->value;
		   printf("param: %s (%ld)\n", param, param);

	           irlist= irlist_front;
                   while(irlist->next != NULL)
                   {   irlist= irlist->next;
                   }


	           /* add nodes for printstring */
                   irlist->next= emalloc(sizeof(struct irnode));
	           irlist->next->prev= irlist;
                   irlist= irlist->next;
                   irlist->sid= ++irnodenum;
                   irlist->ircode= PRINTSTRING;
		   irlist->oprnd1= ++regnum;


                   irlist->next= emalloc(sizeof(struct irnode));
	           irlist->next->prev= irlist;
                   irlist= irlist->next;
                   irlist->sid= ++irnodenum;
                   irlist->ircode= CREATE_STRINGVAR;
		   irlist->symptr= (struct declarator *)param;
		   sprintf(irlist->label,"stringvar%d", ++stringvarnum);


                   irlist->next= emalloc(sizeof(struct irnode));
	           irlist->next->prev= irlist;
                   irlist= irlist->next;
                   irlist->sid= ++irnodenum;
                   irlist->ircode= SYSCALL;

               }





	       /* readint function...
	       +--------------------------*/
	       if(! strcmp(funcname,"readint"))
	       {

	           irlist= irlist_front;
                   while(irlist->next != NULL)
                   {   irlist= irlist->next;
                   }

	           /* add nodes for readint */
                   irlist->next= emalloc(sizeof(struct irnode));
	           irlist->next->prev= irlist;
                   irlist= irlist->next;
                   irlist->sid= ++irnodenum;
                   irlist->ircode= READINT;

                   irlist->next= emalloc(sizeof(struct irnode));
	           irlist->next->prev= irlist;
                   irlist= irlist->next;
                   irlist->sid= ++irnodenum;
                   irlist->ircode= SYSCALL;

	           /* add nodes for result storage */
                   irlist->next= emalloc(sizeof(struct irnode));
	           irlist->next->prev= irlist;
                   irlist= irlist->next;
                   irlist->sid= ++irnodenum;
                   irlist->ircode= LOADADDRESS;
                   irlist->oprnd1= ++regnum;
	           irlist->symptr= (struct declarator *)subtree->r->l;

                   irlist->next= emalloc(sizeof(struct irnode));
	           irlist->next->prev= irlist;
                   irlist= irlist->next;
                   irlist->sid= ++irnodenum;
                   irlist->ircode= STOREWORDINDIRECT;
                   irlist->oprnd1= SYSCALL_REG;
                   irlist->oprnd2= regnum;
	           irlist->symptr= (struct declarator *)subtree->r->l;

               }
	   }




	   /* If it's not a builtin function
	   +---------------------------------*/
	   else
	   {   printf("function '%s' has been called...\n",funcname);
	       irlist= irlist_front;
               while(irlist->next != NULL)
               {   irlist= irlist->next;
               }

	       /* add nodes for printint */
               irlist->next= emalloc(sizeof(struct irnode));
	       irlist->next->prev= irlist;
               irlist= irlist->next;
               irlist->sid= ++irnodenum;
               irlist->ircode= FUNCTIONCALL;
	       strcpy(irlist->label,"_VAR_");
	       strcat(irlist->label,funcname);
	       irlist->symptr= d;

           }

           break;






        default:
	   printf("DEBUG: expr_to_ir: NOT SURE WHAT TO DO WITH TYPE: %d\n", subtree->nodetype);
	   break;
    }


    return tcresult;
}
Ejemplo n.º 2
0
Instruction *expr_to_ir(Env *env, ExpNode *expr, char **result_sym) {
    if (!expr)
        return NULL;
    //printf("NODE TYPE : %d\n", expr->node_type);
    switch (expr->node_type) {
        case CONSTANT_EXPNODE: { // leaf
            //printf("CONST EXPR!\n");
            Instruction *inst;
            if (expr->return_type == TYPE_INT)
                inst = load_int_instruction_new(expr->int_val);
            else
                inst = load_float_instruction_new(expr->float_val);

            char **ret_sym = &((LoadIntInstruction *) inst->value)->return_symbol;
            *ret_sym = next_tmp_symbol(env);
            if (result_sym)
                *result_sym = *ret_sym;
            //printf("Printing const expnode\n");
            //print_ir_list(inst);
            return inst;
            break;
        } case BOOLEAN_EXPNODE: {
            //printf("Entering boolean expnode\n");
            // truth_val = 0
            // evaluate shit, jump to true if true
            // goto end
            // true:
            //   truth_val = 1
            // end:

            char *truth_var = next_tmp_symbol(env);

            Instruction *init = load_int_instruction_new(0);
            ((LoadIntInstruction *) init->value)->return_symbol = truth_var;

            Instruction *true_label = label_instruction_new(next_tmp_symbol(env));
            Instruction *end_label = label_instruction_new(next_tmp_symbol(env));

            char *lhs_sym, *rhs_sym;
            Instruction *lhs = expr_to_ir(env, expr->lhs, &lhs_sym); 
            Instruction *rhs = NULL;
            if (expr->rhs)
                rhs = expr_to_ir(env, expr->rhs, &rhs_sym); 

            Instruction *evaluate;
            //printf("Before evaluate\n");
            if (!strcmp(expr->op, "||")) {
                // do first
                // if first, jump to true
                // do second
                // if second, jump to true
                Instruction *jump1 = cond_jump_instruction_new(lhs_sym, true_label);
                Instruction *jump2 = cond_jump_instruction_new(rhs_sym, true_label);
                evaluate = concat_inst(4, lhs, jump1, rhs, jump2);
            } else if (!strcmp(expr->op, "&&")) {
                // do first
                // if first, jump to maybe
                // goto end

                // maybe:
                // do second
                // if second, jump to true
                // (goto end)
                Instruction *maybe_label = label_instruction_new(next_tmp_symbol(env));
                Instruction *jump_to_maybe = cond_jump_instruction_new(lhs_sym, maybe_label);
                Instruction *jump_to_end = uncond_jump_instruction_new(end_label);
                Instruction *jump_to_true = cond_jump_instruction_new(rhs_sym, true_label);

                evaluate = concat_inst(6, lhs, jump_to_maybe, jump_to_end, 
                    maybe_label, rhs, jump_to_true);
            } else {
                //printf("NEGATION\n");
                // (boolean negation)
                // do first
                // if first, jump to end
                // jump to true
                Instruction *jump_to_end = cond_jump_instruction_new(lhs_sym, end_label);
                Instruction *jump_to_true = uncond_jump_instruction_new(true_label);
                //printf("CONCAT %p %p %p\n", lhs, jump_to_end, jump_to_true);
                evaluate = concat_inst(3, lhs, jump_to_end, jump_to_true);
            }
            //printf("After evaluate\n");

            Instruction *goto_end = uncond_jump_instruction_new(end_label);

            char *load_one_var = next_tmp_symbol(env);
            Instruction *load_one = load_int_instruction_new(1);
            ((LoadIntInstruction *) load_one->value)->return_symbol = load_one_var;
            Instruction *set_true = copy_instruction_new(truth_var, load_one_var, NULL);

            if (result_sym)
                *result_sym = truth_var;
            // init
            // evaluate
            // goto end
            // true:
            // set_to_1
            // end:

            //printf("Entering boolean expnode\n");
            return concat_inst(
                7,
                init,
                evaluate,
                goto_end,
                true_label,
                load_one,
                set_true,
                end_label
            );
            break;    
        } case COMP_EXPNODE: {
            // return value should be 0 or 1
            //printf("Entering comp expnode\n");
            //assert(0);
            char *truth_var = next_tmp_symbol(env);

            Instruction *init = load_int_instruction_new(0);
            ((LoadIntInstruction *) init->value)->return_symbol = truth_var;

            Instruction *true_label = label_instruction_new(next_tmp_symbol(env));
            Instruction *end_label = label_instruction_new(next_tmp_symbol(env));

            char *return_symbol = next_tmp_symbol(env);
            if (result_sym)
                *result_sym = return_symbol;

            char *lhs_sym, *rhs_sym;
            Instruction *lhs = expr_to_ir(env, expr->lhs, &lhs_sym);
            Instruction *rhs = expr_to_ir(env, expr->rhs, &rhs_sym);

            Instruction *jump_to_end = uncond_jump_instruction_new(end_label);

            Instruction *jump_to_true = cond_comp_jump_instruction_new(
                expr->op, lhs_sym, rhs_sym, true_label);

            char *load_one_var = next_tmp_symbol(env);
            Instruction *load_one = load_int_instruction_new(1);
            ((LoadIntInstruction *) load_one->value)->return_symbol = load_one_var;
            Instruction *set_true = copy_instruction_new(truth_var, load_one_var, NULL);

            if (result_sym)
                *result_sym = truth_var;

            //printf("Exiting comp expnode\n");
            return concat_inst(9, lhs, rhs, init, jump_to_true, 
                jump_to_end, true_label, load_one, set_true, end_label);
            break;
        } case ARITHMETIC_EXPNODE: {
            //printf("Entering math expnode\n");

            char *lhs_sym, *rhs_sym;
            rhs_sym = NULL;
            Instruction *lhs = expr_to_ir(env, expr->lhs, &lhs_sym);
            Instruction *rhs = NULL;
            if (expr->rhs)
                rhs = expr_to_ir(env, expr->rhs, &rhs_sym);

            char *return_sym = next_tmp_symbol(env);
            Instruction *inst_cont = arithmetic_instruction_new(expr->op, lhs_sym, rhs_sym, return_sym);

            if (result_sym)
                *result_sym = return_sym;
            // prepend lhs and rhs and inst_cont
            //printf("%p %p %p\n", lhs, rhs, inst_cont);
            Instruction *result = concat_inst(3, lhs, rhs, inst_cont);
            //print_ir_list(result);
            //printf("Exiting math expnode\n");
            return result;
            break;
        } case INVOCATION_EXPNODE: {
            Array *sym_list = array_new(0, sizeof(char **));
            Instruction *param_eval = NULL;
            int i;
            //printf("count: %d\n", expr->expns->length);
            for (i = 0; i < expr->expns->length; i++) {
                char *sym_name;
                ExpNode *exp = *((ExpNode **) array_get(expr->expns, i));
                param_eval = concat_inst(2, param_eval, expr_to_ir(env, exp, &sym_name));
                //printf("INVOC: %s\n", sym_name);
                array_append(sym_list, &sym_name);
            }

            char *return_symbol = NULL;
            if (result_sym) {
                return_symbol = next_tmp_symbol(env);
                *result_sym = return_symbol;
            }
            Instruction *invocation = invocation_instruction_new(return_symbol, expr->op, sym_list);

            return concat_inst(2, param_eval, invocation);
            break;
        } case ID_EXPNODE: // leaf
            //printf("ID_EXPNODE: %s\n", expr->op);
            if (expr->index == NULL) {
                if (result_sym)
                    *result_sym = expr->op;
            } else {
                char *return_symbol = next_tmp_symbol(env);
                if (result_sym)
                    *result_sym = return_symbol; 

                char *index_sym = NULL;
                Instruction *index_code = expr_to_ir(env, expr->index, &index_sym);
                return concat_inst(2,
                    index_code,
                    array_element_instruction_new(expr->op, index_sym, return_symbol)
                );
            }
            return NULL;
            break;
        case ASSIGNMENT_EXPNODE: {
            //printf("Entering assignment expnode\n");
            char *lhs_sym, *rhs_sym, *index_sym;
            lhs_sym = rhs_sym = index_sym = NULL;

            assert(expr->lhs->node_type == ID_EXPNODE);
            Instruction *index_inst = NULL;
            if (expr->lhs->index != NULL)
                index_inst = expr_to_ir(env, expr->lhs->index, &index_sym);
            lhs_sym = expr->lhs->op;

            Instruction *rhs = expr_to_ir(env, expr->rhs, &rhs_sym);
            //printf("LHS: %p, RHS: %p\n", lhs_sym, rhs_sym);
            Instruction *cpy_inst = copy_instruction_new(lhs_sym, rhs_sym, index_sym);
            Instruction *result = concat_inst(3, index_inst, rhs, cpy_inst);
            return result;
            break;
        } default:
            break;
    }
    return NULL;
}
Ejemplo n.º 3
0
/*-----------------------------------------------
 | compound_to_ir
 +---------------------------------------------*/
void compound_to_ir(struct ast *cstmt)
{   char genstr[TMPSTRSZ];
    struct ast *decostat;
    struct decostat_list *dlist= (struct decostat_list *) cstmt->l;
    struct flow *tflow;
    struct ast *cond;
    struct ast *thendo;



    printf("DEBUG: compound_to_ir called with nodetype: %d\n", cstmt->nodetype);

    sprintf(&genstr[strlen(genstr)],"#");
    indent(genstr);
    sprintf(&genstr[strlen(genstr)],"{\n");
    fprintf(irout,"%s",genstr); clearstr(genstr);

    ++indent_count;
    do
    {   decostat= dlist->decostat;


        /* Generate IR node
        +--------------------*/
	regnum=0;   /* reset register count to 0 */
	printf("c2ir calling e2ir...\n");
        expr_to_ir(decostat);


        /* write C statement to file
	+----------------------------*/
        clearstr(genstr);
        sprintf(genstr,"#");
        indent(genstr);


	if(decostat->nodetype == COMPOUND_STATEMENT)
	{   clearstr(genstr);
	    compound_to_ir(decostat);
	}


	else
        {   print_expr(dlist->decostat,genstr);
	}

        /* no semicolons after compound statements */
        if(   (dlist->decostat->nodetype == COMPOUND_STATEMENT)      ||
              ( (dlist->decostat->nodetype == LABELED_STATEMENT)     &&
                (dlist->decostat->r->nodetype == COMPOUND_STATEMENT)
              )
          )
        {   fprintf(irout,"\n\n");
        }
        else
        {   fprintf(irout,"%s;\n",genstr); clearstr(genstr);
        }
        fprintf(irout,"%s",genstr); clearstr(genstr);




        /* write IR nodes to file
	+----------------------------*/
	statement_end_sid= irnodenum;
	print_irnode_sids(statement_begin_sid,statement_end_sid);
	statement_begin_sid= ++statement_end_sid;
	fprintf(irout,"\n\n\n");


    } while( (dlist= dlist->next) != NULL);
    --indent_count;


    sprintf(&genstr[strlen(genstr)],"#");
    indent(genstr);
    sprintf(&genstr[strlen(genstr)],"}\n\n\n");
    fprintf(irout,"%s",genstr); clearstr(genstr);
}