Beispiel #1
0
// the classic back patch using the emit functions
int backPatchJumpToHere(int addr, char *comment)
{
    int currloc;

    currloc = emitSkip(0);
    emitBackup(addr);
    emitRMAbs((char *)"LDA", PC, currloc, comment);
    emitBackup(currloc);
}
Beispiel #2
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