Exemple #1
0
void emitHeader()
{
    emitComment((char*)"C- Compiler version C-F13");
    emitComment((char*)"Built: Dec 12, 2013");
    emitComment((char*)"Author: Brett Papineau");
    //filename conversion here
    emitComment2((char*)"File compiled: ", (char*)out);
}
Exemple #2
0
/*
 * Emit ASC code for a then statment as part of IF-THEN-ELSE.
 * Assumes the corresposding statement or matched_stat code has already
 * been emitted.
 */
void emitThenMatchedStat() {
	/* we don't have a symbol pointer, so just pass in non-null */
	CHECK_CAN_EMIT(1);

	emitComment("Bottom of an IF-THEN.");
	emitComment("Either THEN was executed, so GOTO,");
	emitComment("or land at %s%d if 'expr' was false",
	    LABEL_PREFIX, peekLabelStackTop(labelStack));
	
	emitStmt(STMT_LEN, "GOTO %s%d",
	    LABEL_PREFIX, peekLabelStackTop(labelStack) + 1);
	emitLabel(STMT_LEN, "%s%d",
	    LABEL_PREFIX, peekLabelStackTop(labelStack));
}
Exemple #3
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");
    }
}
Exemple #4
0
/*
 * Write generated code to file.
 *
 * Parameters:
 * 	fileName: name of the .asc file to which to write.
 * Return:
 * 	0 on success,
 * 	non-zero otherwise
 */
int emitToFile(char *fileName) {
	FILE *ascfp = NULL;

	if (doNotEmit) {
		return 1;
	}

	/* open the file */
	ascfp = fopen(fileName, "w");

	/* append end-of-program stuff here (like a STOP) */
	emitComment("End of user-defined pgram");
	emitStmt(STMT_LEN, "STOP");

	/* 
	 * append pre-defined ASC code here, so that it's at the bottom
	 * of the file
	 */
#ifndef ASC_SIMPLE
	emitPreDefCode();
#endif

	/* write the emitted code to file */
	writeStmtLL(ascfp, stmts);

	/* close the file */
	if (fclose(ascfp) != 0) {
		err(EXIT_FAILURE, "File IO error.");
	}

	return 0;
}
Exemple #5
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,"");
}
Exemple #6
0
/*
 * Emit ASC code for a then statment as part of IF-THEN.
 * Assumes the corresposding statement or matched_stat code has already
 * been emitted.
 */
void emitThenStat() {
	/* we don't have a symbol pointer, so just pass in non-null */
	CHECK_CAN_EMIT(1);

	emitComment("Bottom of IF-THEN as part of IF-THEN");
	emitLabel(STMT_LEN, "%s%d",
	    LABEL_PREFIX, peekLabelStackTop(labelStack));
	popLabels(labelStack);
}
Exemple #7
0
/*
 * Emit ASC code for an else statement
 * Assumes the corresponding statement code is already generated.
 */
void emitElseStat() {
	/* we don't have a symbol pointer, so just pass in non-null */
	CHECK_CAN_EMIT(1);

	emitComment("Bottom of ELSE stat");
	emitLabel(STMT_LEN, "%s%d",
	    LABEL_PREFIX, peekLabelStackTop(labelStack) + 1);
	popLabels(labelStack);
}
Exemple #8
0
/*
 * Emit code to goto the endo of the loop. Used for exit statments.
 */
void emitGotoLoopEnd() {
	/* we don't have a symbol pointer, so just pass in non-null */
	CHECK_CAN_EMIT(1);

	emitComment("Go to end of %s%d",
	    LOOP_PREFIX, peekLabelStackTop(loopLabelStack));
	emitStmt(STMT_LEN, "GOTO %s%d",
	    LOOP_PREFIX, peekLabelStackTop(loopLabelStack) + 1);
}
Exemple #9
0
void emitHead()
{
    emitComment(fileName);
    sprintf(buffer, ".class public %s", className);
    emitLine(buffer);
    emitLine(".super java/lang/Object");
    emitLineBreak();
    return;
}
Exemple #10
0
/*
 * Emit code for the end of a while loop.
 */
void emitEndWhile() {
	/* we don't have a symbol pointer, so just pass in non-null */
	CHECK_CAN_EMIT(1);

	emitComment("End of WHILE loop %s%d",
	    LOOP_PREFIX, peekLabelStackTop(loopLabelStack));
	emitLabel(STMT_LEN, "%s%d",
	    LOOP_PREFIX, peekLabelStackTop(loopLabelStack) + 1);

	popLabels(loopLabelStack);
}
Exemple #11
0
/*
 * Check that expr is true to do loop, otherwise skip loop
 */
void emitWhileLoopCondCheck(Symbol *s) {
	/* we don't have a symbol pointer, so just pass in non-null */
	CHECK_CAN_EMIT(s);

	if (! (s->kind == CONST_KIND && isConstResultSym(s))) {
		emitPushSymbolValue(s);
	}

	emitComment("If expr is false, skip loop body");
	emitStmt(STMT_LEN, "IFZ %s%d",
	    LOOP_PREFIX, peekLabelStackTop(loopLabelStack) + 1);
}
Exemple #12
0
/*
 * Beginning of a while loop
 */
void emitBeginWhile() {
	/* we don't have a symbol pointer, so just pass in non-null */
	CHECK_CAN_EMIT(1);

	/* Reserve loop labels. One for the top, one for the bottom */
	reserveLabels(loopLabelStack, 2);

	emitComment("Top of WHILE loop %s%d",
	    LOOP_PREFIX, peekLabelStackTop(loopLabelStack));
	emitLabel(STMT_LEN, "%s%d",
	    LOOP_PREFIX, peekLabelStackTop(loopLabelStack));
}
Exemple #13
0
/*
 * Emit the pre-defined ASC functions.
 */
void emitPreDefCode() {
	emitBlankLine();
	emitSepLine();
	emitBlankLine();
	emitComment("Pre-defined ASC functions to follow");
	emitBlankLine();
	emitSepLine();
	emitBlankLine();

	/* call to generated function in PreDefAsc.c */
	emitPreDefAsc();
}
Exemple #14
0
/*
 * Emit ASC code to start an if statement.
 * Assumes the correspoding expression has already been emitted
 *
 * Note that both IF-THEN-ELSE and IF-THEN statements
 * reserve two labels, but only one is ever used in IF-THEN statements.
 */
void emitIfStat(Symbol *s) {
	CHECK_CAN_EMIT(s);
	/* reserve labels for THEN and ELSE */
	reserveLabels(labelStack, 2);

	if (! (s->kind == CONST_KIND && isConstResultSym(s))) {
		emitPushSymbolValue(s);
	}

	emitComment("IF expr THEN. If 'expr' is false skip to %s%d",
	    LABEL_PREFIX, peekLabelStackTop(labelStack));
	emitStmt(STMT_LEN, "IFZ %s%d", 
	    LABEL_PREFIX, peekLabelStackTop(labelStack));
}
Exemple #15
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 */
Exemple #16
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 */
Exemple #17
0
/* Procedure emitBackup backs up to 
 * loc = a previously skipped location
 */
void emitBackup( int loc)
{ if (loc > highEmitLoc) emitComment("BUG in emitBackup");
  emitLoc = loc ;
} /* emitBackup */
Exemple #18
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;
	}
}
Exemple #19
0
void escreverComentario(FILE *out, char *str){
	emitComment(out, str );
}
Exemple #20
0
/*
 * Emit anything that must be emitted before the code generated from the
 * input PAL. This includes predefined funcs and procs, constants, etc.
 */
void emitInit() {
	emitComment("ASC code generated by Yet Another CMPUT415 Compiler.");
	emitComment("May the Force be ever in your favour, Mr. Potter.");
	emitComment("CMPUT 415 - Fall 2013");
	emitBlankLine();
}
Exemple #21
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
Exemple #22
0
    void emitHeaderStart()
    {
        const char *tn = ls.structname.fullname.c_str();
        const char *sn = ls.structname.shortname.c_str();
        string tnDots = dotsToUnderscores(ls.structname.fullname);
        const char *tn_ = tnDots.c_str();

        emitAutoGeneratedWarning();

        emit(0, "#include <zcm/zcm_coretypes.h>");
        emit(0, "");
        emit(0, "#ifndef __%s_hpp__", tn_);
        emit(0, "#define __%s_hpp__", tn_);
        emit(0, "");

        // do we need to #include <vector> and/or <string>?
        bool emitIncludeVector = false;
        bool emitIncludeString = false;
        for (auto& lm : ls.members) {
            if (!emitIncludeVector &&
                lm.dimensions.size() != 0 && !lm.isConstantSizeArray()) {
                emit(0, "#include <vector>");
                emitIncludeVector = true;
            }
            if (!emitIncludeString &&
                lm.type.fullname == "string") {
                emit(0, "#include <string>");
                emitIncludeString = true;
            }
        }

        // include header files for other ZCM types
        for (auto& lm : ls.members) {
            auto& mtn = lm.type.fullname;
            if (!ZCMGen::isPrimitiveType(mtn) && mtn != tn) {
                emit(0, "#include \"%s%s%s.hpp\"",
                     zcm.gopt->getString("cpp-include").c_str(),
                     zcm.gopt->getString("cpp-include").size()>0 ? "/":"",
                     dotsToSlashes(mtn).c_str());
            }
        }

        emit(0, "\n");
        emitPackageNamespaceStart();

        // define the class
        emitComment(0, ls.comment);
        emit(0, "class %s", sn);
        emit(0, "{");

        // data members
        if(ls.members.size() > 0) {
            emit(1, "public:");
            for (auto& lm : ls.members) {
                auto& mtn = lm.type.fullname;
                emitComment(2, lm.comment);
                string mappedTypename = mapTypeName(mtn);
                int ndim = (int)lm.dimensions.size();
                if (ndim == 0) {
                    emit(2, "%-10s %s;", mappedTypename.c_str(), lm.membername.c_str());
                } else {
                    if (lm.isConstantSizeArray()) {
                        emitStart(2, "%-10s %s", mappedTypename.c_str(), lm.membername.c_str());
                        for (auto& ld : lm.dimensions)
                            emitContinue("[%s]", ld.size.c_str());
                        emitEnd(";");
                    } else {
                        emitStart(2, "");
                        for (int d = 0; d < ndim; d++)
                            emitContinue("std::vector< ");
                        emitContinue("%s", mappedTypename.c_str());
                        for (int d = 0; d < ndim; d++)
                            emitContinue(" >");
                        emitEnd(" %s;", lm.membername.c_str());
                    }
                }
                emit(0, "");
            }
        }

        // constants
        if (ls.constants.size() > 0) {
            emit(1, "public:");
            emit(2, "#if __cplusplus > 199711L /* if c++11 */");
            for (auto& lc : ls.constants) {
                assert(ZCMGen::isLegalConstType(lc.type));
                emitComment(2, lc.comment);
                string mt = mapTypeName(lc.type);
                const char *suffix = lc.type == "int64_t" ? "LL" : "";
                emit(2, "static constexpr %-8s %s = %s%s;", mt.c_str(),
                        lc.membername.c_str(), lc.valstr.c_str(), suffix);
            }
            emit(2, "#else");
            for (auto& lc : ls.constants) {
                assert(ZCMGen::isLegalConstType(lc.type));
                string mt = mapTypeName(lc.type);
                const char *suffix = lc.type == "int64_t" ? "LL" : "";
                emit(2, "static const     %-8s %s = %s%s;", mt.c_str(),
                        lc.membername.c_str(), lc.valstr.c_str(), suffix);
            }
            emit(2, "#endif");
            emit(0, "");
        }

        emit(1, "public:");
        emit(2, "/**");
        emit(2, " * Destructs a message properly if anything inherits from it");
        emit(2, "*/");
        emit(2, "virtual ~%s() {}", ls.structname.shortname.c_str());
        emit(0, "");
        emit(2, "/**");
        emit(2, " * Encode a message into binary form.");
        emit(2, " *");
        emit(2, " * @param buf The output buffer.");
        emit(2, " * @param offset Encoding starts at thie byte offset into @p buf.");
        emit(2, " * @param maxlen Maximum number of bytes to write.  This should generally be");
        emit(2, " *  equal to getEncodedSize().");
        emit(2, " * @return The number of bytes encoded, or <0 on error.");
        emit(2, " */");
        emit(2, "inline int encode(void *buf, int offset, int maxlen) const;");
        emit(0, "");
        emit(2, "/**");
        emit(2, " * Check how many bytes are required to encode this message.");
        emit(2, " */");
        emit(2, "inline int getEncodedSize() const;");
        emit(0, "");
        emit(2, "/**");
        emit(2, " * Decode a message from binary form into this instance.");
        emit(2, " *");
        emit(2, " * @param buf The buffer containing the encoded message.");
        emit(2, " * @param offset The byte offset into @p buf where the encoded message starts.");
        emit(2, " * @param maxlen The maximum number of bytes to reqad while decoding.");
        emit(2, " * @return The number of bytes decoded, or <0 if an error occured.");
        emit(2, " */");
        emit(2, "inline int decode(const void *buf, int offset, int maxlen);");
        emit(0, "");
        emit(2, "/**");
        emit(2, " * Retrieve the 64-bit fingerprint identifying the structure of the message.");
        emit(2, " * Note that the fingerprint is the same for all instances of the same");
        emit(2, " * message type, and is a fingerprint on the message type definition, not on");
        emit(2, " * the message contents.");
        emit(2, " */");
        emit(2, "inline static int64_t getHash();");
        emit(0, "");
        emit(2, "/**");
        emit(2, " * Returns \"%s\"", ls.structname.shortname.c_str());
        emit(2, " */");
        emit(2, "inline static const char* getTypeName();");

        emit(0, "");
        emit(2, "// ZCM support functions. Users should not call these");
        emit(2, "inline int _encodeNoHash(void *buf, int offset, int maxlen) const;");
        emit(2, "inline int _getEncodedSizeNoHash() const;");
        emit(2, "inline int _decodeNoHash(const void *buf, int offset, int maxlen);");
        emit(2, "inline static uint64_t _computeHash(const __zcm_hash_ptr *p);");
        emit(0, "};");
        emit(0, "");
    }
Exemple #23
0
// emitBackup backs up to 
// loc = a previously skipped location
// 
void emitBackup(int loc)
{
    if (loc>highEmitLoc) emitComment((char *)"BUG in emitBackup");
    emitLoc = loc;
}