Ejemplo n.º 1
0
/*
 *==============================================
 * Wrapper function for the traversing cGen 
 * function
 *==============================================
 */
int codeGen(TreeBranch *head, HashTable *parent)
{
  currentTable = parent;
  ff = fopen("Output/output.s", "w+");
  fprintf(ff, HEADER);  
  cGen(head);
  fprintf(ff, FOOTER);
  fclose(ff);
  return 0;
}
Ejemplo n.º 2
0
void codeGen(TreeNode *syntaxTree, const char *codefile)
{
	writeFileHeader();
	writeVarSection();
	cGen(syntaxTree);
	fillCodeSection();
	writeTempVarSection();
	writeVarRefSection();
	fillSection();
	writeTempVarRefSection();
	fillSection();
	updateFileHeader();
}
Ejemplo n.º 3
0
/* Procedure cGen recursively generates code by
 * tree traversal
 */
static void cGen( TreeNode * tree)
{ if (tree != NULL)
  { switch (tree->nodekind) {
      case StmtK:
        genStmt(tree);
        break;
      case ExpK:
        genExp(tree);
        break;
      default:
        break;
    }
    cGen(tree->sibling);
  }
}
Ejemplo n.º 4
0
/* Procedure codeGen generates code to a code
 * file by traversal of the syntax tree. The
 * second parameter (codefile) is the file name
 * of the code file, and is used to print the
 * file name as a comment in the code file
 */
void codeGen(TreeNode * syntaxTree, char * codefile)
{  char * s = (char *) malloc(strlen(codefile)+7);
   strcpy(s,"File: ");
   strcat(s,codefile);
   emitComment("TINY Compilation to TM Code");
   emitComment(s);
   /* generate standard prelude */
   emitComment("Standard prelude:");
   emitRM("LD",mp,0,ac,"load maxaddress from location 0");
   emitRM("ST",ac,0,ac,"clear location 0");
   emitComment("End of standard prelude.");
   /* generate code for TINY program */
   cGen(syntaxTree);
   /* finish */
   emitComment("End of execution.");
   emitRO("HALT",0,0,0,"");
}
Ejemplo n.º 5
0
/* Procedure genExp generates code at an expression node */
static void genExp( TreeNode * tree)
{ int loc;
  TreeNode * p1, * p2;
  switch (tree->kind.exp) {

    case ConstK :
      if (TraceCode) emitComment("-> Const") ;
      /* gen code to load integer constant using LDC */
      emitRM("LDC",ac,tree->attr.val,0,"load const");
      if (TraceCode)  emitComment("<- Const") ;
      break; /* ConstK */
    
    case IdK :
      if (TraceCode) emitComment("-> Id") ;
      loc = st_lookup(tree->attr.name);
      emitRM("LD",ac,loc,gp,"load id value");
      if (TraceCode)  emitComment("<- Id") ;
      break; /* IdK */

    case OpK :
         if (TraceCode) emitComment("-> Op") ;
         p1 = tree->child[0];
         p2 = tree->child[1];
         /* gen code for ac = left arg */
         cGen(p1);
         /* gen code to push left operand */
         emitRM("ST",ac,tmpOffset--,mp,"op: push left");
         /* gen code for ac = right operand */
         cGen(p2);
         /* now load left operand */
         emitRM("LD",ac1,++tmpOffset,mp,"op: load left");
         switch (tree->attr.op) {
            case PLUS :
               emitRO("ADD",ac,ac1,ac,"op +");
               break;
            case MINUS :
               emitRO("SUB",ac,ac1,ac,"op -");
               break;
            case TIMES :
               emitRO("MUL",ac,ac1,ac,"op *");
               break;
            case OVER :
               emitRO("DIV",ac,ac1,ac,"op /");
               break;
            case LT :
               emitRO("SUB",ac,ac1,ac,"op <") ;
               emitRM("JLT",ac,2,pc,"br if true") ;
               emitRM("LDC",ac,0,ac,"false case") ;
               emitRM("LDA",pc,1,pc,"unconditional jmp") ;
               emitRM("LDC",ac,1,ac,"true case") ;
               break;
            case EQ :
               emitRO("SUB",ac,ac1,ac,"op ==") ;
               emitRM("JEQ",ac,2,pc,"br if true");
               emitRM("LDC",ac,0,ac,"false case") ;
               emitRM("LDA",pc,1,pc,"unconditional jmp") ;
               emitRM("LDC",ac,1,ac,"true case") ;
               break;
            default:
               emitComment("BUG: Unknown operator");
               break;
         } /* case op */
         if (TraceCode)  emitComment("<- Op") ;
         break; /* OpK */

    default:
      break;
  }
} /* genExp */
Ejemplo n.º 6
0
/* Procedure genStmt generates code at a statement node */
static void genStmt( TreeNode * tree)
{ TreeNode * p1, * p2, * p3;
  int savedLoc1,savedLoc2,currentLoc;
  int loc;
  switch (tree->kind.stmt) {

      case IfK :
         if (TraceCode) emitComment("-> if") ;
         p1 = tree->child[0] ;
         p2 = tree->child[1] ;
         p3 = tree->child[2] ;
         /* generate code for test expression */
         cGen(p1);
         savedLoc1 = emitSkip(1) ;
         emitComment("if: jump to else belongs here");
         /* recurse on then part */
         cGen(p2);
         savedLoc2 = emitSkip(1) ;
         emitComment("if: jump to end belongs here");
         currentLoc = emitSkip(0) ;
         emitBackup(savedLoc1) ;
         emitRM_Abs("JEQ",ac,currentLoc,"if: jmp to else");
         emitRestore() ;
         /* recurse on else part */
         cGen(p3);
         currentLoc = emitSkip(0) ;
         emitBackup(savedLoc2) ;
         emitRM_Abs("LDA",pc,currentLoc,"jmp to end") ;
         emitRestore() ;
         if (TraceCode)  emitComment("<- if") ;
         break; /* if_k */

      case RepeatK:
         if (TraceCode) emitComment("-> repeat") ;
         p1 = tree->child[0] ;
         p2 = tree->child[1] ;
         savedLoc1 = emitSkip(0);
         emitComment("repeat: jump after body comes back here");
         /* generate code for body */
         cGen(p1);
         /* generate code for test */
         cGen(p2);
         emitRM_Abs("JEQ",ac,savedLoc1,"repeat: jmp back to body");
         if (TraceCode)  emitComment("<- repeat") ;
         break; /* repeat */

      case AssignK:
         if (TraceCode) emitComment("-> assign") ;
         /* generate code for rhs */
         cGen(tree->child[0]);
         /* now store value */
         loc = st_lookup(tree->attr.name);
         emitRM("ST",ac,loc,gp,"assign: store value");
         if (TraceCode)  emitComment("<- assign") ;
         break; /* assign_k */

      case ReadK:
         emitRO("IN",ac,0,0,"read integer value");
         loc = st_lookup(tree->attr.name);
         emitRM("ST",ac,loc,gp,"read: store value");
         break;
      case WriteK:
         /* generate code for expression to write */
         cGen(tree->child[0]);
         /* now output it */
         emitRO("OUT",ac,0,0,"write ac");
         break;
      default:
         break;
    }
} /* genStmt */
Ejemplo n.º 7
0
static void genStmt(TreeNode *tree)
{
	TreeNode *p1, *p2, *p3;
	
	switch (tree->kind.stmt)
	{
	case IfK:
		p1 = tree->child[0];
		p2 = tree->child[1];
		p3 = tree->child[2];

		cGen(p1);

		break;

	case RepeatK:
		break;

	case AssignK:
		p1 = tree->child[0];

		cGen(p1);

		switch (p1->nodekind)
		{
		int loc;
		case StmtK:
			switch(p1->kind.stmt)
			{
			case AssignK:

				break;
			}
			break;

		case ExpK:
			switch(p1->kind.exp)
			{
			case ConstK:

				break;
			case IdK:

				break;
			case OpK:
				loc = st_lookup(tree->attr.token.stype);
				emitMov_N(REG_EAX, loc);
				break;
			}
			break;
		}

		break;

	case ReadK:
		break;

	case WriteK:
		break;
	default : break;
	}
}
Ejemplo n.º 8
0
/*
 *=============================================
 * recursive traversing function that generates
 * assembly code
 *=============================================
 */
int cGen(TreeBranch *cur)
{
  int skip1 = 0;
  int skip2 = 0;
  int skip3 = 0;
  int skipSib = 0;
  
  /*=====================================================================================
   *   Block Statements
   *
   *=====================================================================================
   */  
  if(cur->nodeT == new_blk)
  {
    /*first block*/
    if(tableflag == 0)
    {
      tableflag = 1;
      currentTable->MaxOffset = curOffset;
       if(cur->child1 != NULL)
        cGen(cur->child1);
       if(cur->child2 != NULL)
        cGen(cur->child2);
       if(cur->child3 != NULL)
        cGen(cur->child3);
       skip1 = 1;
       skip2 = 1;
       skip3 = 1;
       skipSib = 1;  
    }
    /*other blocks*/
    else
    {
      currentTable->MaxOffset = curOffset;
      currentTable = currentTable->next;
      fprintf(ff, ";;; entering new stack frame\n");
      if(cur->child1 != NULL)
        cGen(cur->child1);
      if(cur->child2 != NULL)
        cGen(cur->child2);
      if(cur->child3 != NULL)
        cGen(cur->child3);
      
      currentTable = currentTable->parent;
      if(currentTable->next != NULL)
      { 
        if (currentTable->next->next != NULL)
        {
          currentTable->next = currentTable->next->next;
        }
      }  
      fprintf(ff, "\tadd esp, %d ;reset stack pointer\n", curOffset-currentTable->MaxOffset);
      curOffset = currentTable->MaxOffset;  
      if(cur->sibling != NULL)
        cGen(cur->sibling);
        
      skip1 = 1;
      skip2 = 1;
      skip3 = 1;
      skipSib = 1;  
    }
  }
  /*================================================================================
   *        Constant Declarations
   *================================================================================
   */
   else if(cur->nodeT == const_decl)
    {
	  HashElement *tmp = lookUpId(cur->child1->attribute, currentTable);
	  tmp->val = cur->child2->num;
	  /*fprintf(ff, "\tsub esp, %d\n", 4);
	  fprintf(ff, "\tmov dword [ebp - %d], %d\t;cons %s\n", tmp->offset, tmp->val, tmp->identifier);*/
    }
  /*================================================================================
   *          Variable Declarations
   *================================================================================
   */
   else if(cur->nodeT == var_decl)
    {
      if(cur->child2->nodeT == sing_decl)
      {
       /*================================================================================
	    *       Non-Array Declarations
	    *================================================================================
	    */
	    HashElement *tmp = lookUpId(cur->child1->attribute, currentTable);
	    tmp->offset = curOffset;
	    curOffset += 4;
	    /*initialize all variables to zero, seems easier that way*/
	    fprintf(ff, "\tsub esp, 4\t;variable %s\n", tmp->identifier);
	    //fprintf(ff, "\tmov dword [ebp - %d], %d\t;var %s\n", tmp->offset, 0, tmp->identifier);
	    TreeBranch *ptr = cur->child1->sibling;
	    while(ptr != NULL)
	    {
	      tmp = lookUpId(ptr->attribute, currentTable);
	      tmp->offset = curOffset;
	      curOffset +=4;
	      /*initialize all variables to zero, seems easier that way*/
	      fprintf(ff, "\tsub esp, 4\t;variable %s\n", tmp->identifier);
	      //fprintf(ff, "\tmov dword [ebp - %d], %d\t;var %s\n", tmp->offset, 0, tmp->identifier);
	      ptr = ptr->sibling;
	    }
	  }
	  /*================================================================================
	   *       Array Declarations
	   *================================================================================
	   */
	  if(cur->child2->nodeT == arr_decl)
	  {
	    HashElement *tmp = lookUpId(cur->child1->attribute, currentTable);
	    tmp->offset = curOffset;
	    if(tmp->indices == 0)
	    {
	      HashElement *tmp2 = lookUpId(cur->child2->child1->attribute, currentTable);
	      tmp->indices = tmp2->val;
	    }
	    curOffset += (4*tmp->indices);
	    fprintf(ff, "\tsub esp, %d\t;array %s\n", (4*tmp->indices), tmp->identifier);
	    TreeBranch *ptr = cur->child1->sibling;
	    while(ptr != NULL)
	    {
	      if(tmp->indices == 0)
	      {
	        HashElement *tmp2 = lookUpId(cur->child2->child1->attribute, currentTable);
	        tmp->indices = tmp2->val;
	      }
	      tmp = lookUpId(cur->child1->attribute, currentTable);
	      tmp->offset = curOffset;
	      curOffset += (4*tmp->indices);
	      fprintf(ff, "\tsub esp, %d\t;array %s\n", (4*tmp->indices), tmp->identifier);
	      ptr = ptr->sibling;
	    }
	  }
    }
  /*=====================================================================================
   *     Assignment statements
   *
   *=====================================================================================
   */
   if(cur->nodeT == assign)
   { 
     int prevOffset = curOffset;
     fprintf(ff, "\t;; Assignment Statement\n");
     HashElement *tmp = lookUpId(cur->child1->attribute, currentTable);
     generateExpression(cur->child2);
     fprintf(ff, "\tmov [ebp - %d], eax\t;assigning\n", tmp->offset);
     fprintf(ff, "\tadd esp, %d\t;end of assignment\n", curOffset-prevOffset);
     curOffset = prevOffset;
   }
  /*=====================================================================================
   *    Write statements
   *
   *=====================================================================================
   */
    if(cur->nodeT == write_stmt)
    {
      int wrcount = 0;
      TreeBranch *ptr = cur->child1;
      fprintf(ff, "\t;; Write Statement\n");
      while(ptr != NULL)
      {
        generateExpression(ptr);
        fprintf(ff, "\tsub esp, 4\n");
        fprintf(ff, "\tmov [ebp - %d], eax\n", curOffset);
        curOffset += 4;
        wrcount++;
        ptr = ptr->sibling;
      } 
      fprintf(ff, "\tsub esp, 4\n");
      fprintf(ff, "\tmov dword [ebp - %d], %d\n", curOffset, wrcount);
      fprintf(ff, "\tcall write\n");
      fprintf(ff, "\tadd esp, %d\n", (wrcount*4 + 4));
      curOffset -= (wrcount*4);
      skip1 = 1;
      skip2 = 1;
      skip3 = 1;
    }
   
   /*=====================================================================================
   *     Read Statements
   *
   *=====================================================================================
   */
   if(cur->nodeT == read_stmt)
    {
      int rdcount = 0;
      TreeBranch *ptr = cur->child1;
      fprintf(ff, "\t;; Write Statement\n");
      while(ptr != NULL)
      {
        generateExpression(ptr);
        fprintf(ff, "\tsub esp, 4\n");
        fprintf(ff, "\tmov [ebp - %d], eax\n", curOffset);
        curOffset += 4;
        rdcount++;
        ptr = ptr->sibling;
      } 
      fprintf(ff, "\tsub esp, 4\n");
      fprintf(ff, "\tmov dword [ebp - %d], %d\n", curOffset, rdcount);
      fprintf(ff, "\tcall read\n");
      fprintf(ff, "\tadd esp, %d\n", (rdcount*4 + 4));
      curOffset -= (rdcount*4);
      skip1 = 1;
      skip2 = 1;
      skip3 = 1;
    }
   
   /*=====================================================================================
   *      While statements
   *
   *=====================================================================================
   */
    if(cur->nodeT == while_stmt)
    {
      
        fprintf(ff, "\t;; While Statement\n");
        int prevOffset = curOffset;
        generateExpression(cur->child1);
        int iterlabel = labelnum;
        labelnum++;
        int endlabel = labelnum;
        labelnum++;
      
        fprintf(ff, "L%d:\n", iterlabel);
        generateExpression(cur->child1);   
        /*generate the necessary jump after the comparison*/
        if(strcmp(cur->child1->attribute, "=")==0)
        {
            fprintf(ff, "\tje L%d\n", endlabel);
        }
        if(strcmp(cur->child1->attribute, ">")==0)
        {
            fprintf(ff, "\tjg L%d\n", endlabel);
        }
        if(strcmp(cur->child1->attribute, "<")==0)
        {
            fprintf(ff, "\tjl L%d\n", endlabel);
        }
        if(strcmp(cur->child1->attribute, ">=")==0)
        {
            fprintf(ff, "\tjge L%d\n", endlabel);
        }
        if(strcmp(cur->child1->attribute, "<=")==0)
        {
            fprintf(ff, "\tjle L%d\n", endlabel);
        }
        cGen(cur->child2);
        fprintf(ff, "\tjmp L%d\t;iterate\n", iterlabel);
        fprintf(ff, "L%d:\n", endlabel);
        fprintf(ff, "\tadd esp, %d\n;;;end of while statement\n", curOffset-prevOffset);
        curOffset = prevOffset;    
    }
   
   /*=====================================================================================
   *     if statements
   *
   *=====================================================================================
   */
    if((cur->nodeT == if_stmt) || (cur->nodeT == ifelse_stmt))
    {
        int prevOffset = curOffset;
        fprintf(ff, "\t;; If Statement\n");
        int iflabel = labelnum;
        labelnum++;
        generateExpression(cur->child1);   
        /*generate the necessary jump after the comparison*/
        if(strcmp(cur->child1->attribute, "=")==0)
        {
            fprintf(ff, "\tjne L%d\n", iflabel);
        }
        if(strcmp(cur->child1->attribute, ">")==0)
        {
            fprintf(ff, "\tjng L%d\n", iflabel);
        }
        if(strcmp(cur->child1->attribute, "<")==0)
        {
            fprintf(ff, "\tjnl L%d\n", iflabel);
        }
        if(strcmp(cur->child1->attribute, ">=")==0)
        {
            fprintf(ff, "\tjnge L%d\n", iflabel);
        }
        if(strcmp(cur->child1->attribute, "<=")==0)
        {
            fprintf(ff, "\tjnle L%d\n", iflabel);
        }
        cGen(cur->child2);
        skip2 = 1;
        /*
         *if there is no else, simply skip to the end
         */
        if(cur->nodeT == if_stmt)
        {
            fprintf(ff, "L%d:\n", iflabel);
        }
        /* disclaimer: this is really hard to not sound confusing
         * 
         * if the (if statement) has an (else statenment) then the (if statement)
         * will need to have a jump to miss the (else statement), otherwise the
         * jump from the (if statement) should jump to the beginning of the (else
         * statement)
         */
        if(cur->nodeT == ifelse_stmt)
        {
            int elselabel = labelnum;
            labelnum++;
            fprintf(ff, "\tjmp L%d\t;skip else\n", elselabel);
            
            fprintf(ff, "L%d:;skip to else clause\n", iflabel);
            cGen(cur->child3);
            skip3 = 1;
            fprintf(ff, "L%d:\n", elselabel);
        }
            
        fprintf(ff, "\tadd esp, %d\n;;;end of if statement\n", curOffset-prevOffset);
        curOffset = prevOffset;    
    }
      
  if(cur->child1 != NULL && skip1 == 0)
    cGen(cur->child1);
  if(cur->child2 != NULL && skip2 == 0)
    cGen(cur->child2);
  if(cur->child3 != NULL && skip3 == 0)
    cGen(cur->child3);
  if(cur->sibling != NULL && skipSib == 0)
    cGen(cur->sibling);
  
  return 0;
}