int GPerlVirtualMachine::run(GPerlVirtualMachineCode *codes) { static GPerlVirtualMachineCode *top; GPerlVirtualMachineCode *pc = codes; Reg reg_[MAX_CALLSTACK_SIZE]; Reg *reg = reg_; GPerlEnv *callstack = createCallStack(); GPerlObject **argstack = createArgStack(); static char shared_buf[128] = {0};//TODO must be variable buffer static string outbuf = ""; #include "gen_label.cpp" DISPATCH_START(); CASE(UNDEF), { GPERL_UNDEF(); pc++; BREAK(); });
/* ***************************************************************************************************************** * codeGenerator: * child : The ASTNode for which the code has to be generated. * funInfo : This has the FunctionNode(see astDef.h for details) for the function * which has the 'child'. * currLabel : Possible label which can be assigned to the current instruction. * parentLabel : The label of the parent node in AST. * This function simply does the post order traversal of a function and generates code for that function. * In our case it works only for the main function. ***************************************************************************************************************** */ void codeGenerator(ASTNode* child,FunctionNode* funInfo,Label* currLabel, int parentLabel){ if(child==NULL){ return; } int tempCount = funInfo->width; int tempLabel = currLabel->labelNum; InstructionList* funLabel = NULL; ASTNode* ifChild = NULL; int ifFlag=0; TokenName tokenName = child->token->tokenName; switch(tokenName){ case TK_MAIN: funLabel = createLabel(1,0); strcpy(funLabel->label,"main"); generate(funLabel); createCallStack(child); break; case TK_ASSIGNOP: generateArithmeticExpression(child,funInfo->funTok,&tempCount); break; case TK_IF: currLabel->labelNum += 2; generateBooleanExpression(child->child,funInfo->funTok,addLabel(1,tempLabel),addLabel(0,tempLabel),currLabel,&tempCount); generate(createLabel(1,tempLabel)); break; case TK_ELSE: generate(createInstruction(JMP,-1,-1,parentLabel+1,1,0)); generate(createLabel(0,parentLabel)); break; case TK_READ: generateScanf(child->child,funInfo); break; case TK_WRITE: generatePrintf(child->child,funInfo); break; case TK_WHILE: generate(createLabel(1,currLabel->labelNum)); currLabel->labelNum += 2; generateBooleanExpression(child->child,funInfo->funTok,addLabel(1,tempLabel+1),addLabel(0,tempLabel),currLabel,&tempCount); generate(createLabel(1,tempLabel+1)); break; } if(tokenName==TK_IF) codeGenerator(child->child,funInfo,currLabel, tempLabel); else codeGenerator(child->child,funInfo,currLabel, parentLabel); switch(tokenName){ case TK_MAIN: generate(createInstruction(ADD,RSP,IMM,0,0,funInfo->width+funInfo->tempCount)); generate(createInstruction(RET,-1,-1,-1,-1,-1)); break; case TK_WHILE: generate(createInstruction(JMP,-1,-1,tempLabel,1,0)); generate(createLabel(0,tempLabel)); break; case TK_IF: generate(createLabel(1,tempLabel+1)); ifChild = child->child; while(ifChild!=NULL){ if(ifChild->token->tokenName==TK_ELSE){ ifFlag = 1; break; } ifChild = ifChild->next; } if(!ifFlag) generate(createLabel(0,tempLabel)); break; } codeGenerator(child->next,funInfo,currLabel, parentLabel); }