Esempio n. 1
0
void emitEnd()
{
    TreeNode *temp = (TreeNode*)tab->lookup((char*)"main");
    //if(temp == NULL)
    //{
    //    printf("ERROR(LINKER): Procedure main is not defined\n");
    //}
    
    if(temp != NULL)
    {
        backPatchJumpToHere(0, (char*)"Jump to init [backpatch]");
        emitComment((char*)"BEGIN Init");
        emitRM((char*)"LD", GP, 0, GP, (char*)"Set the global pointer");
        emitComment((char*)"BEGIN init of globals");
        //start
        int gloads = goff2;
        SymTabEntry* intable = (SymTabEntry*)tab->firstSymTabEntry();
        intable = (SymTabEntry*)tab->nextSymTabEntry(intable);
        //skip null
        //intable = (SymTabEntry*)tab->nextSymTabEntry(intable);
        TreeNode* tmp = (TreeNode*)tab->lookup(intable->name);
        while(tmp != NULL)
        {        
            if(tmp->kind.decl == varK)
            {
                if(!tmp->isArray)
                {
                    params = 1;
                    codeGen(tmp);
                }
                else
                {
                   emitRM2((char*)"LDC", AC, tmp->size - 1, AC3, (char*)"load size of array", tmp->attr.name);
                   emitRM2((char*)"ST", AC, tmp->location + 1, 0, (char*)"save size of array", tmp->attr.name); 
                }
            }
            tmp=tmp->sibling;
        }

        emitComment((char*)"END init of globals");
        emitRM((char*)"LDA", FP, goff, GP, (char*)"set first frame at end of globals");
        emitRM((char*)"ST", FP, 0, FP, (char*)"store old fp (point to self)");
        emitRM((char*)"LDA", AC, 1, PC, (char*)"Return address in ac");
        emitRM((char*)"LDA", PC, temp->location - emitSkip(0) - 1, PC, (char*)"Jump to main");
        emitRO((char*)"HALT", 0, 0, 0, (char*)"DONE!");
        emitComment((char*)"END Init");
    }
}
Esempio n. 2
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,"");
}
Esempio n. 3
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 */
Esempio n. 4
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 */
Esempio n. 5
0
void montador(FILE *out, tipoInstr tipo, int valor, int reg){
 	static int memOffset = 0;

	switch(tipo){
		case INSTR_INICIO:
			emitComment(out, "INICIO" );
			emitRM(out, "LD",mp,0,ac,"load maxaddress from location 0");
			emitRM(out, "ST",ac,0,ac,"clear location 0");
		break;

		case INSTR_FIM:
			emitComment(out, "FIM" );
			emitRO(out, "HALT",0,0,0,"");
		break;

		case INSTR_STORE_MEMORIA:
			emitComment(out, "STORE" );
			emitRM(out, "ST",reg,valor,gp,"carrega endereco de memoria valor de gp em reg");
		break;

		case INSTR_STORE_MEMORIA_TEMP:
			emitComment(out, "STORE TEMPORARIO" );
			emitRM(out, "ST",reg,memOffset,mp,"carrega endereco de memoria valor de mp em reg");
			memOffset--;
		break;

		case INSTR_LOAD_MEMORIA:
			emitComment(out, "LOAD" );
			emitRM(out, "LD",reg,valor,gp,"carrega para reg o que tem no endereco de memoria valor que esta no gp");
		break;

		case INSTR_LOAD_CTE:
			emitComment(out, "LOAD CONSTANTE" );
			emitRM(out, "LDC",reg,valor,0,"carrega NUM em reg");
		break;

		case INSTR_LOAD_MEMORIA_TEMP:
			emitComment(out, "LOAD O QUE ESTA NO TOPO DA PILHA DOS TEMPORARIOS" );
			memOffset++;
			emitRM(out, "LD",reg,memOffset,mp,"carrega para reg o que tem no endereco de memoria valor que esta no mp");
		break;

		case INSTR_WRITE:
			emitComment(out, "WRITE");
			emitRO(out, "OUT",ac,0,0,"write ac");
		break;

		case INSTR_TEMP_ACS:
			emitComment(out, "PASSA VALOR PARA AC0 E AC1");

			memOffset++;
			emitRM(out, "LD",ac,memOffset,mp,"carrega em ac o que tem no endereco de memoria valor de mp");
			memOffset++;
			emitRM(out, "LD",ac1,memOffset,mp,"carrega em ac1 o que tem no endereco de memoria valor de mp");
		break;
		
		case INSTR_READ:
			emitComment(out, "READ");
			emitRO(out, "IN", reg, 0, 0, "le valor para o registrador");
			emitRM(out, "ST", reg, valor, gp, "armazena valor de reg para endereco de memoria valor de gp");
		break;

		case INSTR_ADD:
			emitComment(out, "ADICAO");
			emitRO(out, "ADD",ac,ac1,ac,"ac = ac1 + ac");
			emitRM(out, "ST",ac,memOffset,mp,"armazena valor da soma na memoria mp");
			memOffset--;
		break;

		case INSTR_SUB:
			emitComment(out, "SUBTRACAO");
			emitRO(out, "SUB",ac,ac1,ac,"ac = ac1 - ac");
			emitRM(out, "ST",ac,memOffset,mp,"armazena valor da subtracao na memoria mp");
			memOffset--;
		break;

		case INSTR_MULT:
			emitComment(out, "MULTIPLICACAO");
			emitRO(out, "MUL",ac,ac1,ac,"ac = ac1 * ac");
			emitRM(out, "ST",ac,memOffset,mp,"armazena valor da multiplicacao na memoria mp");
			memOffset--;
		break;

		case INSTR_DIV:
			emitComment(out, "DIVISAO");
			emitRO(out, "DIV",ac,ac1,ac,"ac = ac1 / ac");
			emitRM(out, "ST",ac,memOffset,mp,"armazena valor da divisao na memoria mp");
			memOffset--;
		break;

		case INSTR_REL_MENOR:
			emitComment(out, "RELACAO: MENOR");
			emitRO(out, "SUB",ac,ac1,ac,"");
			emitRM(out, "JLT",ac,4,pc,"a - b < 0 ? Se sim, pule para armazenar true");
		break;
		
		case INSTR_REL_MENOR_IGUAL:
			emitComment(out, "RELACAO: MENOR IGUAL");
			emitRO(out, "SUB",ac,ac1,ac,"op - entre ac e ac1");
			emitRM(out, "JLE",ac,4,pc,"a - b <= 0 ? Se sim, pule para armazenar true");
		break;

		case INSTR_REL_MAIOR:
			emitComment(out, "RELACAO: MAIOR");
			emitRO(out, "SUB",ac,ac1,ac,"");
			emitRM(out, "JGT",ac,4,pc,"a - b > 0 ? Se sim, pule para armazenar true");
		break;
		
		case INSTR_REL_MAIOR_IGUAL:
			emitComment(out, "RELACAO: MAIOR IGUAL");
			emitRO(out, "SUB", ac, ac1, ac, "op - entre ac e ac1");
			emitRM(out, "JGE", ac, 4, pc, "a-b>=0 ? Se sim, pula para armazenar true");
		break;

		case INSTR_REL_IGUAL:
			emitComment(out, "RELACAO: IGUAL");
			emitRO(out, "SUB",ac,ac1,ac,"");
			emitRM(out, "JEQ",ac,4,pc,"a - b == 0 ? Se sim, pule para armazenar true");
		break;

		case INSTR_REL_DIF:
			emitComment(out, "RELACAO: DIFERENTE");
			emitRO(out, "SUB",ac,ac1,ac,"op - entre ac e ac1");
			emitRM(out, "JNE",ac,4,pc,"a - b != 0 ? Se sim, pule para armazenar true");
		break;

		case INSTR_REL_AND:
			emitComment(out, "OPERACAO LOGICA: AND");
			emitRM(out, "JEQ", ac, 3, pc, "ac == 0? Se sim, avalia como falso");
			emitRM(out, "JEQ", ac1, 2, pc, "ac1 == 0? Se sim, avalia como falso");
			emitRM(out, "LDC",ac,0,0,"");
			emitRM(out, "JEQ",ac,4,pc,"Se nenhum dos dois é falso, avalia como verdadeiro");
			
		break;
		
		case INSTR_REL_OR:
			emitComment(out, "OPERACAO LOGICA: OR");
			emitRM(out, "JNE", ac, 5, pc, "ac != 0? Se sim, avalia como true");
			emitRM(out, "JNE", ac1, 4, pc, "ac1 != 0? Se sim, avalia como true");
			emitComment(out, "se nenhum dos dois e verdadeiro, avalia como falso, nao pula");
			
		break;
		
		case INSTR_STORE_REL:
			emitComment(out, "STORE RESULTADO DA RELACAO");

			emitRM(out, "LDC",ac,0,0,"false");
			emitRM(out, "ST",ac,memOffset,mp,"armazena false no topo");
			emitRM(out, "LDC",ac,0,0,"");
			emitRM(out, "JEQ",ac,2,pc,"Pula para o if");


			emitRM(out, "LDC",ac,1,0,"true");
			emitRM(out, "ST",ac,memOffset,mp,"armazena true no topo");
			memOffset--;
		break;

		case INSTR_JUMP_REL_FALSE:
			emitComment(out, "JUMP se o valor da relacao for false");

			memOffset++;
			emitRM(out, "LD",ac,memOffset,mp,"");
			emitRM(out, "JEQ",ac,valor,pc,"Pula para o else");
		break;

		case INSTR_JUMP:
			emitComment(out, "JUMP");
			emitRM(out, "LDC",ac,0,0,"");
			emitRM(out, "JEQ",ac,valor,pc,"Pula incondicionalmente para pc+valor");
		break;

		default:
			emitComment(out, "ERRO" );
		break;
	}
}
Esempio n. 6
0
void codeGen(TreeNode* currnode)
{
    bool texp = false;
    while(currnode != NULL)
    {
        if(currnode->nodekind==DeclK)
        {
            switch(currnode->kind.decl)
            {
                case varK:
                    codeGen(currnode->child[0]);
                    t2 = (TreeNode*)tab->lookup(currnode->attr.name);
                    if(t2 == NULL && currnode->isArray)
                    {
                        emitRM2((char*)"LDC", AC, currnode->size - 1, AC3, (char*)"load size of array", currnode->attr.name);
                        emitRM2((char*)"ST", AC, currnode->location + 1, FP, (char*)"save size of array", currnode->attr.name);
                    }
                    if(t2 == NULL && currnode->child[0] != NULL)
                        emitRM2((char*)"ST", AC, currnode->location, FP, (char*)"Store variable", currnode->attr.name);
                    if(t2 != NULL && currnode->child[0] != NULL)
                        codeGen(currnode->child[0]);
                    break;
                case paramK:
                    
                    break;
                case funcK:                   
                    //printf("test\n");
                    t1 = (TreeNode*)tab->lookup(currnode->attr.name);
                    t1->location = emitSkip(0);
                    currnode->location = t1->location;
                    toff = 0;
                    framesize = currnode->size;
                    //toff = 0 - t1->size;
                    emitComment2((char*)"BEGIN function", currnode->attr.name);
                    if(currnode->isPre)
                        emitRM((char*)"ST", AC, -1, FP, (char*)"Store return address");
                    else
                        emitRM((char*)"ST", AC, -1, FP, (char*)"Store return address.");
                    codeGen(currnode->child[0]);
                    codeGen(currnode->child[1]);
                    if(currnode->isPre)
                    {
                        switch(currnode->pnum)
                        {
                            case 0://input
                                emitRO((char*)"IN", RT, RT, RT, (char*)"Grab int input");
                                emitRM((char*)"LD", AC, -1, FP, (char*)"Load return address");
                                emitRM((char*)"LD", FP, 0, FP, (char*)"Adjust fp");
                                emitRM((char*)"LDA", PC, 0, AC, (char*)"Return");
                                break;
                            case 1://output
                                emitRM((char*)"LD", AC, -2, FP, (char*)"Load parameter");
                                emitRO((char*)"OUT", AC, AC, AC, (char*)"Output integer");
                                emitRM((char*)"LDC", RT, 0, AC3, (char*)"Set return to 0");
                                emitRM((char*)"LD", AC, -1, FP, (char*)"Load return address");
                                emitRM((char*)"LD", FP, 0, FP, (char*)"Adjust fp");
                                emitRM((char*)"LDA", PC, 0, AC, (char*)"Return");
                                break;
                            case 2://inputb
                                emitRO((char*)"INB", RT, RT, RT, (char*)"Grab bool input");
                                emitRM((char*)"LD", AC, -1, FP, (char*)"Load return address");
                                emitRM((char*)"LD", FP, 0, FP, (char*)"Adjust fp");
                                emitRM((char*)"LDA", PC, 0, AC, (char*)"Return");
                                break;
                            case 3://ouptutb
                                emitRM((char*)"LD", AC, -2, FP, (char*)"Load parameter");
                                emitRO((char*)"OUTB", AC, AC, AC, (char*)"Output bool");
                                emitRM((char*)"LDC", RT, 0, AC3, (char*)"Set return to 0");
                                emitRM((char*)"LD", AC, -1, FP, (char*)"Load return address");
                                emitRM((char*)"LD", FP, 0, FP, (char*)"Adjust fp");
                                emitRM((char*)"LDA", PC, 0, AC, (char*)"Return");
                                break;
                            case 4://inputc
                                emitRO((char*)"INC", RT, RT, RT, (char*)"Grab char input");
                                emitRM((char*)"LD", AC, -1, FP, (char*)"Load return address");
                                emitRM((char*)"LD", FP, 0, FP, (char*)"Adjust fp");
                                emitRM((char*)"LDA", PC, 0, AC, (char*)"Return");
                                break;
                            case 5://outputc
                                emitRM((char*)"LD", AC, -2, FP, (char*)"Load parameter");
                                emitRO((char*)"OUTC", AC, AC, AC, (char*)"Output char");
                                emitRM((char*)"LDC", RT, 0, AC3, (char*)"Set return to 0");
                                emitRM((char*)"LD", AC, -1, FP, (char*)"Load return address");
                                emitRM((char*)"LD", FP, 0, FP, (char*)"Adjust fp");
                                emitRM((char*)"LDA", PC, 0, AC, (char*)"Return");
                                break;
                            case 6://outnl
                                emitRO((char*)"OUTNL", AC, AC, AC, (char*)"Output a newline");
                                emitRM((char*)"LD", AC, -1, FP, (char*)"Load return address");
                                emitRM((char*)"LD", FP, 0, FP, (char*)"Adjust fp");
                                emitRM((char*)"LDA", PC, 0, AC, (char*)"Return");
                                
                        }
                    }
                    if(!currnode->isPre)
                    {
                        emitComment((char*)"Add standard closing in case there is no return statement");
                        emitRM((char*)"LDC", RT, 0, AC3, (char*)"Set return value to 0");
                        emitRM((char*)"LD", AC, -1, FP, (char*)"Load return address");
                        emitRM((char*)"LD", FP, 0, FP, (char*)"Adjust fp");
                        emitRM((char*)"LDA", PC, 0, AC, (char*)"Return");
                        
                    }
                    emitComment2((char*)"END of function", currnode->attr.name);
                    toff = 0;
                    break;
            }
            //in_exp = false;
        }
        else if(currnode->nodekind==StmtK)
            switch(currnode->kind.stmt)
            {
                case ifK:
                    int breakk;
                    int breakk2;
                    emitComment((char*)"IF");
                    currloc2 = emitSkip(0);
                    ifexp = true;
                    codeGen(currnode->child[0]);
                    ifexp = false;
                    emitRM((char*)"JGT", AC, 1, PC, (char*)"Jump to then part");
                    emitComment((char*)"THEN");
                    
                    skiploc2 = breakk2;
                    breakk2 = emitSkip(1);
                    
                    codeGen(currnode->child[1]);
                    if(currnode->child[2] != NULL)
                    {
                        emitComment((char*)"ELSE");
                        breakk = emitSkip(1);
                        backPatchJumpToHere(breakk2, (char*)"Jump around the THEN [backpatch]");
                        codeGen(currnode->child[2]);
                        backPatchJumpToHere(breakk, (char*)"Jump around the ELSE [backpatch]");
                    }
                    else
                        backPatchJumpToHere(breakloc, (char*)"Jump around the THEN [backpatch]");
                    
                    emitComment((char*)"ENDIF");
                    break;
                case returnK:
                    emitComment((char*)"RETURN");
                    if (currnode->child[0] != NULL) 
                    {
                        codeGen(currnode->child[0]);                  // generate any return value 
                        //t2 = (TreeNode*)tab->lookup(currnode->attr.name);
                        if(currnode->child[0] != NULL)
                        {
                            if(currnode->child[0]->scopeT == local || currnode->child[0]->scopeT == param)
                                offReg = 1;
                            else
                                offReg = 0;
                        }
                        if(currnode->child[0]->isArray)
                        {
                            if(currnode->scopeT == param)
                                emitRM2((char*)"LD", AC1, currnode->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name);
                            else
                                emitRM2((char*)"LDA", AC, currnode->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name);
                            
                            emitRM2((char*)"SUB", AC, AC1, AC, (char*)"Compute offset for", currnode->attr.name);
                            emitRM2((char*)"LD", AC, 0, AC, (char*)"load the value", currnode->attr.name);
                        }
                        emitRM((char*)"LDA", RT, 0, AC, (char*)"Copy result to rt register");  // save in return register
                    }

                    // emit return sequence
                    emitRM((char*)"LD", AC, OFPOFF, FP, (char*)"Load return address"); 
                    emitRM((char*)"LD", FP, RETURN_OFFSET, FP, (char*)"Adjust fp");
                    emitRM((char*)"LDA", PC, 0, AC, (char*)"Return");
                    break;
                case compoundK:
                    emitComment((char*)"BEGIN compound statement");
                    codeGen(currnode->child[0]);
                    codeGen(currnode->child[1]);
                    emitComment((char*)"END compound statement");
                    break;
                case breakK:
                    emitComment((char*)"BREAK");
                    emitRM((char*)"LDA", PC, breakloc - emitSkip(0) - 1, PC, (char*)"break");
                    break;
                case foreachK:
                    break;
                case whileK:
                    int currloc;
                    int skiploc;
                    emitComment((char*)"WHILE");
                    currloc = emitSkip(0);                    // save location to return to
                    codeGen(currnode->child[0]);   // generate code for test

                    emitRM((char*)"JGT", AC, 1, PC, (char*)"Jump to while part");  // test and jump
                    emitComment((char*)"DO");

                    skiploc = breakloc;                // save the old break statement return point
                    breakloc = emitSkip(1);            // addr of instr that jumps to end of loop
                                           // this is also the backpatch point
                    
                    codeGen(currnode->child[1]);  // generate body of loop

                    emitRMAbs((char*)"LDA", PC, currloc, (char*)"go to beginning of loop");   // jump to top of loop
                    backPatchJumpToHere(breakloc, (char*)"No more loop [backpatch]");              // backpatch jump to end of loop at breakloc

                    breakloc = skiploc;              // restore for break statement

                    emitComment((char*)"ENDWHILE");    
                    break;
                  
            }
        else if(currnode->nodekind==ExpK)
        {
            int offReg = 1;
            if(!in_exp)
            {
                emitComment((char*)"EXPRESSION STMT");
                in_exp = true;
                
            }
                switch(currnode->kind.exp)
                {
                    codeGen(currnode->child[0]);
                    case opK:
                        texp = inexp;
                        inexp = currnode->expType == Bool;
                        
                        opexp = true;
                        //tempparam = params;
                        //params = 1;
                        codeGen(currnode->child[0]);
                        opexp = false;
                        //params = tempparam;
                        if(currnode->child[1] != NULL)
                        {
                            emitRM((char*)"ST", AC, toff-- - framesize, FP, (char*)"Save left side");
                            if(!currnode->child[1]->isArray)
                                codeGen(currnode->child[1]);
                            else
                            {
                                codeGen(currnode->child[1]->child[0]);
                                t2 = (TreeNode*)tab->lookup(currnode->child[1]->attr.name);
                                if(t2 != NULL)
                                {
                                    if(t2->scopeT == local || t2->scopeT == param)
                                        offReg = 1;
                                    else
                                        offReg = 0;
                                }
                                if(currnode->child[1]->scopeT == param)
                                {
                                    if(currnode->child[1]->child[0] != NULL)
                                        emitRM2((char*)"LD", AC1, currnode->child[1]->location, offReg, (char*)"Load address of base of array", currnode->child[1]->attr.name);
                                    else
                                        emitRM2((char*)"LD", AC, currnode->child[1]->location, offReg, (char*)"Load address of base of array", currnode->child[1]->attr.name);
                                }
                                else
                                {
                                    if(currnode->child[0] != NULL)
                                    {
                                        emitRO((char*)"SUB", AC, AC1, AC, (char*)"Computer offset of value");
                                        emitRM((char*)"LD", AC, 0, AC, (char*)"Load the value");
                                    }
                                }
                            }
                            emitRM((char*)"LD", AC1, ++toff - framesize, FP, (char*)"Load left into ac1");
                        }
                        switch(currnode->attr.op)
                        {
                            case ltK:
                                emitRO((char*)"SUB", AC1, AC1, AC, (char*)"Op <");
                                emitRM((char*)"LDC", AC, 1, AC3, (char*)"True case");
                                emitRM((char*)"JLT", AC1, 1, PC, (char*)"Jump if true");
                                emitRM((char*)"LDC", AC, 0, AC3, (char*)"False case");
                                break;
                            case gtK:
                                emitRO((char*)"SUB", AC1, AC1, AC, (char*)"Op <");
                                emitRM((char*)"LDC", AC, 1, AC3, (char*)"True case");
                                emitRM((char*)"JGT", AC1, 1, PC, (char*)"Jump if true");
                                emitRM((char*)"LDC", AC, 0, AC3, (char*)"False case");
                                break;
                            case equivK:
                                emitRO((char*)"SUB", AC1, AC1, AC, (char*)"Op ==");
                                emitRM((char*)"LDC", AC, 1, AC3, (char*)"True case");
                                emitRM((char*)"JEQ", AC1, 1, PC, (char*)"Jump if true");
                                emitRM((char*)"LDC", AC, 0, AC3, (char*)"False case");
                                break;
                            case neqK:
                                emitRO((char*)"SUB", AC, AC1, AC, (char*)"Op !=");
                                emitRM((char*)"JEQ", AC, 1, PC, (char*)"Jump if true");
                                emitRM((char*)"LDC", AC, 1, AC3, (char*)"True case");
                                break;
                            case modK:
                                emitRO((char*)"DIV", AC2, AC1, AC, (char*)"Op %");
                                emitRO((char*)"MUL", AC2, AC2, AC, (char*)"");
                                emitRO((char*)"SUB", AC, AC1, AC2, (char*)"");
                                break;
                            case UminusK:
                                emitRM((char*)"LDC", AC1, 0, AC3, (char*)"Load 0");
                                emitRO((char*)"SUB", AC, AC1, AC, (char*)"Op unary -");
                                break;
                            case UmultiK:
                                emitRO((char*)"MUL", AC, currnode->size + 1, AC, (char*)"Load array size");
                                break;
                            case minusK:
                                emitRO((char*)"SUB", AC, AC1, AC, (char*)"Op -");
                                break;
                            case plusK:
                                emitRO((char*)"ADD", AC, AC1, AC, (char*)"Op +");
                                break;
                            case multiK:
                                emitRO((char*)"MUL", AC, AC1, AC, (char*)"Op *");
                                break;
                            case divideK:
                                emitRO((char*)"DIV", AC, AC1, AC, (char*)"Op /");
                                break;
                            case lteqK:
                                emitRO((char*)"SUB", AC1, AC1, AC, (char*)"Op <=");
                                emitRM((char*)"LDC", AC, 1, AC3, (char*)"True case");
                                emitRM((char*)"JLE", AC1, 1, PC, (char*)"Jump if true");
                                emitRM((char*)"LDC", AC, 0, AC3, (char*)"False case");
                                break;
                            case gteqK:
                                emitRO((char*)"SUB", AC1, AC1, AC, (char*)"Op >=");
                                emitRM((char*)"LDC", AC, 1, AC3, (char*)"True case");
                                emitRM((char*)"JGE", AC1, 1, PC, (char*)"Jump if true");
                                emitRM((char*)"LDC", AC, 0, AC3, (char*)"False case");
                                break;
                            case notK:
                                emitRM((char*)"LDA", AC, 1, AC2, (char*)"Not load address");
                                emitRO((char*)"SUB", AC, AC1, AC, (char*)"Op Not");
                                break;
                            case andK:
                                emitRM((char*)"JEQ", AC, 1, PC, (char*)"Op AND");
                                emitRM((char*)"LDA", AC, 0, AC2, (char*)"");
                                break;
                            case orK:
                                emitRM((char*)"JEQ", AC, 1, PC, (char*)"Op OR");
                                emitRM((char*)"LDA", AC, 0, AC2, (char*)"");
                                break;
                        }
                        inexp = texp;
                        break;
                                
                    case constK:
                        if(currnode->expType == Int)
                            emitRM((char*)"LDC", AC, currnode->attr.val, AC3, (char*)"Load constant");
                        if(currnode->expType == Bool)
                        {
                            if(currnode->attr.bval)
                                emitRM((char*)"LDC", AC, 1, AC3, (char*)"Load constant");
                            else
                                emitRM((char*)"LDC", AC, 0, AC3, (char*)"Load constant");
                        }
                        if(currnode->expType == Char)
                            emitRM((char*)"LDC",AC, currnode->attr.string[1], AC3, (char*)"Load constant");
                        break;
                    case idK:
                        codeGen(currnode->child[0]);
                        t2 = (TreeNode*)tab->lookup(currnode->attr.name);
                        if(t2 != NULL)
                        {
                            if(currnode->scopeT == local || currnode->scopeT == param)
                                offReg = 1;
                            else
                                offReg = 0;
                        }
                        if(currnode->isArray)
                        {
                            if((params != 0 && !inexp) || opexp || ifexp)
                            {
                                if(currnode->scopeT == param)
                                {
                                    //emitRM2((char*)"LD", AC1, currnode->location, FP, (char*)"Load address of base of array", currnode->attr.name);
                                    if(currnode->child[0] != NULL)
                                        emitRM2((char*)"LD", AC1, currnode->location, offReg, (char*)"Load address of base of array", currnode->attr.name);
                                    else
                                        emitRM2((char*)"LD", AC, currnode->location, offReg, (char*)"Load address of base of array", currnode->attr.name);
                                }
                                else
                                {
                                    if(currnode->child[0] != NULL)
                                        emitRM2((char*)"LDA", AC1, currnode->location, offReg, (char*)"Load address of base of array", currnode->attr.name);
                                    else
                                        emitRM2((char*)"LDA", AC, currnode->location, offReg, (char*)"Load address of base of array", currnode->attr.name);
                                }
                                if(currnode->child[0] != NULL)
                                {
                                    emitRO((char*)"SUB", AC, AC1, AC, (char*)"Compute offset of value");
                                    emitRM((char*)"LD", AC, 0, AC, (char*)"load the value");
                                }
                            }
                            //in = true;
                        }
                        else if(currnode->scopeT != param && currnode->scopeT != local)
                            emitRM2((char*)"LD", AC, currnode->location, offReg, (char*)"Load variable", currnode->attr.name);
                        else
                            emitRM2((char*)"LD", AC, currnode->location, offReg, (char*)"Load variable", currnode->attr.name);
                        break;
                    case assignK:
                        texp = inexp;
                        inexp = true;
                        switch(currnode->attr.op)
                        {
                            case peqK:
                                if(currnode->child[0]->isArray)
                                {
                                    codeGen(currnode->child[0]);
                                    emitRM((char*)"ST", AC, toff-- - framesize, FP, (char*)"Save index");
                                }
                                codeGen(currnode->child[1]);
                                t2 = (TreeNode*)tab->lookup(currnode->child[0]->attr.name);
                                if(t2 != NULL)
                                {
                                    if(t2->scopeT == local || t2->scopeT == param)
                                        offReg = 1;
                                    else
                                        offReg = 0;
                                }
                                if(currnode->child[1]->isArray)
                                {
                                    if(currnode->child[1]->scopeT == param)
                                        emitRM2((char*)"LD", AC1, currnode->child[1]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name);
                                    else
                                        emitRM2((char*)"LDA", AC1, currnode->child[1]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name);
                                    emitRO((char*)"SUB", AC, AC1, AC, (char*)"Compute offset of value");
                                    emitRM((char*)"LD", AC, 0, AC2, (char*)"Load the value"); 
                                }
                                if(currnode->child[0]->isArray)
                                {
                                    emitRM((char*)"LD", AC1, ++toff - framesize, FP, (char*)"Restore index");
                                    if(currnode->child[0]->scopeT == param)
                                        emitRM2((char*)"LD", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name);
                                    else
                                        emitRM2((char*)"LDA", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name);
                                    emitRO((char*)"SUB", AC2, AC2, AC1, (char*)"Compute offset of value");
                                    emitRM2((char*)"LD", AC1, 0, AC2, (char*)"loah lhs variable", currnode->child[0]->attr.name);
                                    emitRO((char*)"ADD", AC, AC1, AC, (char*)"op +=");                                          // decrement
                                    emitRM2((char*)"ST", AC, 0, AC2, (char*)"Store variable", currnode->child[0]->attr.name);        
                                }
                                else
                                {
                                    emitRM2((char*)"LD", AC1, currnode->child[0]->location, offReg, (char*)"load lhs variable", currnode->child[0]->attr.name);  // load mutable
                                    emitRO((char*)"ADD", AC, AC1, AC, (char*)"op +=");                                          // decrement
                                    emitRM2((char*)"ST", AC, currnode->child[0]->location, offReg, (char*)"Store variable", currnode->child[0]->attr.name);     // store mutable
                                }
                                break;
                            case meqK:
                                if(currnode->child[0]->isArray)
                                {
                                    codeGen(currnode->child[0]);
                                    emitRM((char*)"ST", AC, toff-- - framesize, FP, (char*)"Save index");
                                }
                                codeGen(currnode->child[1]);
                                t2 = (TreeNode*)tab->lookup(currnode->child[0]->attr.name);
                                if(t2 != NULL)
                                {
                                    if(t2->scopeT == local || t2->scopeT == param)
                                        offReg = 1;
                                    else
                                        offReg = 0;
                                }
                                if(currnode->child[1]->isArray)
                                {
                                    if(currnode->child[1]->scopeT == param)
                                        emitRM2((char*)"LD", AC1, currnode->child[1]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name);
                                    else
                                        emitRM2((char*)"LDA", AC1, currnode->child[1]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name);
                                    emitRO((char*)"SUB", AC, AC1, AC, (char*)"Compute offset of value");
                                    emitRM((char*)"LD", AC, 0, AC2, (char*)"Load the value"); 
                                }
                                if(currnode->child[0]->isArray)
                                {
                                    emitRM((char*)"LD", AC1, ++toff - framesize, FP, (char*)"Restore index");
                                    if(currnode->child[0]->scopeT == param)
                                        emitRM2((char*)"LD", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name);
                                    else
                                        emitRM2((char*)"LDA", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name);
                                    emitRO((char*)"SUB", AC2, AC2, AC1, (char*)"Compute offset of value");
                                    emitRM2((char*)"LD", AC1, 0, AC2, (char*)"loah lhs variable", currnode->child[0]->attr.name);
                                    emitRO((char*)"SUB", AC, AC1, AC, (char*)"op -=");                                          // decrement
                                    emitRM2((char*)"ST", AC, 0, AC2, (char*)"Store variable", currnode->child[0]->attr.name);        
                                }
                                else
                                {
                                    emitRM2((char*)"LD", AC1, currnode->child[0]->location, offReg, (char*)"load lhs variable", currnode->child[0]->attr.name);  // load mutable
                                    emitRO((char*)"SUB", AC, AC1, AC, (char*)"op -=");                                          // decrement
                                    emitRM2((char*)"ST", AC, currnode->child[0]->location, offReg, (char*)"Store variable", currnode->child[0]->attr.name);     // store mutable
                                }
                                break;
                            case eqK:
                                if(currnode->child[0]->isArray)
                                {
                                    codeGen(currnode->child[0]);
                                    emitRM((char*)"ST", AC, toff-- - framesize, FP, (char*)"Save index");
                                }
                                codeGen(currnode->child[1]);
                                t2 = (TreeNode*)tab->lookup(currnode->child[0]->attr.name);
                                if(t2 != NULL)
                                {
                                    if(t2->scopeT == local || t2->scopeT == param)
                                        offReg = 1;
                                    else
                                        offReg = 0;
                                }
                                if(currnode->child[1]->isArray)
                                {
                                    if(currnode->child[1]->scopeT == param)
                                        emitRM2((char*)"LD", AC1, currnode->child[1]->location, offReg, (char*)"Load address of base of array", currnode->child[1]->attr.name);
                                    else
                                        emitRM2((char*)"LDA", AC1, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name);
                                    emitRO((char*)"SUB", AC, AC1, AC, (char*)"Compute offset of value");
                                    emitRM((char*)"LD", AC, 0, AC, (char*)"Load the value");
                                }
                                if(currnode->child[0]->isArray)
                                {
                                    emitRM((char*)"LD", AC1, ++toff - framesize, FP, (char*)"Restore index");
                                    if(currnode->child[0]->scopeT == param)
                                        emitRM2((char*)"LD", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name);
                                    else
                                        emitRM2((char*)"LDA", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name);
                                    emitRO((char*)"SUB", AC2, AC2, AC1, (char*)"Compute offset of value");
                                    emitRM2((char*)"ST", AC, 0, AC2, (char*)"Store variable", currnode->child[0]->attr.name);        
                                }
                                else
                                    emitRM2((char*)"ST", AC, currnode->child[0]->location, offReg, (char*)"Store variable", currnode->child[0]->attr.name);
                                break;
                            case ppK:
                                if(currnode->child[0]->isArray)
                                {
                                    codeGen(currnode->child[0]);
                                    emitRM((char*)"ST", AC, toff-- - framesize, FP, (char*)"Save index");
                                }
                                //codeGen(currnode->child[0]);
                                t2 = (TreeNode*)tab->lookup(currnode->child[0]->attr.name);
                                if(t2 != NULL)
                                {
                                    if(t2->scopeT == local || t2->scopeT == param)
                                        offReg = 1;
                                    else
                                        offReg = 0;
                                }
                                if(currnode->child[0]->isArray)
                                {
                                    emitRM((char*)"LD", AC1, ++toff - framesize, FP, (char*)"Restore index");
                                    if(currnode->child[0]->scopeT == param)
                                        emitRM2((char*)"LD", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name);
                                    else
                                        emitRM2((char*)"LDA", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name);
                                    emitRO((char*)"SUB", AC2, AC2, AC1, (char*)"Compute offset of the value");
                                    emitRM2((char*)"LD", AC, 0, AC2, (char*)"load lhs variable", currnode->child[0]->attr.name);  // load mutable
                                    emitRM2((char*)"LDA", AC, 1, AC, (char*)"increment value of", currnode->child[0]->attr.name);              // decrement
                                    emitRM2((char*)"ST", AC, 0, AC2, (char*)"Store variable", currnode->child[0]->attr.name);
                                }
                                else
                                {
                                    emitRM2((char*)"LD", AC, currnode->child[0]->location, offReg, (char*)"load lhs variable", currnode->child[0]->attr.name);  // load mutable
                                    emitRM2((char*)"LDA", AC, 1, AC, (char*)"increment value of", currnode->child[0]->attr.name);              // decrement
                                    emitRM2((char*)"ST", AC, currnode->child[0]->location, offReg, (char*)"Store variable", currnode->child[0]->attr.name);     // store mutable
                                }
                                break;
                            case mmK:
                                if(currnode->child[0]->isArray)
                                {
                                    codeGen(currnode->child[0]);
                                    emitRM((char*)"ST", AC, toff-- - framesize, FP, (char*)"Save index");
                                }
                                //codeGen(currnode->child[0]);
                                t2 = (TreeNode*)tab->lookup(currnode->child[0]->attr.name);
                                if(t2 != NULL)
                                {
                                    if(t2->scopeT == local || t2->scopeT == param)
                                        offReg = 1;
                                    else
                                        offReg = 0;
                                }
                                if(currnode->child[0]->isArray)
                                {
                                    emitRM((char*)"LD", AC1, ++toff - framesize, FP, (char*)"Restore index");
                                    if(currnode->child[0]->scopeT == param)
                                        emitRM2((char*)"LD", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name);
                                    else
                                        emitRM2((char*)"LDA", AC2, currnode->child[0]->location, offReg, (char*)"Load address of base of array", currnode->child[0]->attr.name);
                                    emitRO((char*)"SUB", AC2, AC2, AC1, (char*)"Compute offset of the value");
                                    emitRM2((char*)"LD", AC, 0, AC2, (char*)"load lhs variable", currnode->child[0]->attr.name);  // load mutable
                                    emitRM2((char*)"LDA", AC, -1, AC, (char*)"increment value of", currnode->child[0]->attr.name);              // decrement
                                    emitRM2((char*)"ST", AC, 0, AC2, (char*)"Store variable", currnode->child[0]->attr.name);
                                }
                                else
                                {
                                    emitRM2((char*)"LD", AC, currnode->child[0]->location, offReg, (char*)"load lhs variable", currnode->child[0]->attr.name);  // load mutable
                                    emitRM2((char*)"LDA", AC, -1, AC, (char*)"increment value of", currnode->child[0]->attr.name);              // decrement
                                    emitRM2((char*)"ST", AC, currnode->child[0]->location, offReg, (char*)"Store variable", currnode->child[0]->attr.name);     // store mutable
                                }
                                break;
                            inexp = texp;
                        }
                        inexp = false;
                        break;
                    case callK:
                        texp = inexp;
                        inexp = false;
                        int ttemp = toff;
                        TreeNode *tmp = currnode->child[0];
                        //emitComment((char*)"EXPRESSION STMT");
                        emitComment2((char*)"\t\t\tBegin call to ", currnode->attr.name);
                        emitRM((char*)"ST", FP, toff - framesize, 1, (char*)"Store old fp in ghost frame");
                        toff -= 2;
                        while(tmp != NULL)
                        {
                            params++;
                            emitComment((char*)"\t\t\tLoad param 1");
                            codeGen(tmp);
                            emitRM((char*)"ST", AC, toff-- - framesize,FP, (char*)"Store parameter");
                            paramoff--;
                            tmp = tmp->sibling;
                            params--;
                        }
                        toff = ttemp;
                        paramoff = -2;
                        //t1 = (TreeNode*)tab->lookup(currnode->attr.name);
                        emitComment2((char*)"\t\t\tJump to", currnode->attr.name);
                        emitRM((char*)"LDA", FP, toff - framesize, 1, (char*)"Load address of new frame");
                        emitRM((char*)"LDA", AC, 1, PC, (char*)"Return address in ac");
                        //FIX THE DAMN symbtable
                        TreeNode* t = (TreeNode*)tab->lookup(currnode->attr.name);
                        emitRM2((char*)"LDA", PC, t->location - emitSkip(0) - 1, PC, (char*)"CALL", t->attr.name);
                        emitRM((char*)"LDA", AC, 0, RT, (char*)"Save the result in ac");
                        emitComment2((char*)"\t\t\tEnd call to", currnode->attr.name);
                        emitComment((char*)"EXPRESSION STMT");
                        calloff += 2;
                        inexp = texp;
                        break;                        
                }//end switch exp
                in_exp = false;
        }//end expK
        //else printf("Unknown node kind");
        if(params == 0)
            currnode = currnode->sibling;
        else
            currnode = NULL;
    }//end while
}//end function