void B1ChnlInit(B1ChnlPrms *inst){ int i; for(i=0; i<2; i++,inst++) { B1AcqPrms *acqH = &inst->acq; B1TrkPrms *trkH = &inst->trk; memset(inst,0,sizeof(B1ChnlPrms)); inst->chnlPros = ACQ_FLG; if(i == 0){ inst->satID = DATA_ID; inst->chnlID = B1DID; } else{ inst->satID = PILOT_ID; inst->chnlID = B1PID; } codeGen(inst->satID,inst->code); acq_Init(acqH,inst->chnlID,inst->code); trk_Init(trkH,inst->chnlID); // for test //inst->TCAR.phs = 0 ; //inst->TCAR.fcw = xx; //inst->TPRN.phs = 0; //inst->TPRN.fcw = xx; //inst->prnIndex = 0; // for test } }
void outputNotation(OA::ProcHandle proc, OA::OA_ptr<SageIRInterface> sageIRInterface, std::ostream &outFile) { NotationGenerator codeGen(sageIRInterface, outFile); codeGen.generate(proc); }
main( int argc, char * argv[] ) { TreeNode * syntaxTree; char pgm[120]; /* source code file name */ if (argc != 2) // 检查参数个数 { fprintf(stderr,"usage: %s <filename>\n",argv[0]); exit(1); } strcpy(pgm,argv[1]) ; if (strchr (pgm, '.') == NULL) // 自动检测补全后缀 strcat(pgm,".tny"); source = fopen(pgm,"r"); if (source==NULL) { fprintf(stderr,"File %s not found\n",pgm); exit(1); } // 输出导至标准输出 listing = stdout; /* send listing to screen */ fprintf(listing,"\nTINY COMPILATION: %s\n",pgm); #if NO_PARSE while (getToken()!=ENDFILE); // 关键函数1 #else // parse()自己调用了getToken() syntaxTree = parse(); // 关键函数2 if (TraceParse) { fprintf(listing,"\nSyntax tree:\n"); printTree(syntaxTree); } #if !NO_ANALYZE if (! Error) // Error是一个全局变量,parse()会将状态写在这里 { if (TraceAnalyze) fprintf(listing,"\nBuilding Symbol Table...\n"); buildSymtab(syntaxTree); // 关键函数3 if (TraceAnalyze) fprintf(listing,"\nChecking Types...\n"); typeCheck(syntaxTree); // 关键函数4 if (TraceAnalyze) fprintf(listing,"\nType Checking Finished\n"); } // 上面这两个函数可以看成一个整体,输入是一棵语法树,输出是一颗带标记的语法树,和一张符号表 #if !NO_CODE if (! Error) // 又是一次错误检查 { char * codefile; // 组建输出文件的文件名 int fnlen = strcspn(pgm,"."); codefile = (char *) calloc(fnlen+4, sizeof(char)); strncpy(codefile,pgm,fnlen); strcat(codefile,".tm"); code = fopen(codefile,"w"); if (code == NULL) { printf("Unable to open %s\n",codefile); exit(1); } codeGen(syntaxTree,codefile); // 关键函数5 fclose(code); } #endif #endif #endif fclose(source); return 0; }
void Kontext::createInteger() { std::vector<llvm::Type*> types(1, llvm::Type::getInt32Ty(this->getContext())); auto leType = llvm::StructType::create(this->getContext(), makeArrayRef(types), "Integer", false); std::vector<KObjectAttr> attributes(1, KObjectAttr("innerInt", nullptr)); auto o = KObject("Integer", leType, std::move(attributes)); this->addType("Integer", o); this->setObject("Integer"); std::vector<llvm::Type *> argTypes; argTypes.emplace_back(leType->getPointerTo()); argTypes.emplace_back(llvm::Type::getInt32Ty(this->getContext())); auto fType = llvm::FunctionType::get(llvm::Type::getVoidTy(this->getContext()), makeArrayRef(argTypes), false); auto func = llvm::Function::Create(fType, llvm::GlobalValue::ExternalLinkage, "_KN7IntegerC1E", this->module()); auto bBlock = llvm::BasicBlock::Create(this->getContext(), "entry", func, nullptr); this->pushBlock(bBlock); auto argIter = func->arg_begin(); auto obj = InstanciatedObject::Create("self", &(*argIter), *this, KCallArgList()); (*argIter).setName("self"); obj->store(*this); argIter++; (*argIter).setName("leValue"); auto leBlock = KBlock(); auto decl = std::make_shared<KVarDecl>("innerInt", llvm::Type::getInt32Ty(this->getContext()), &(*argIter)); decl->setInObj(); leBlock.emplaceStatement(std::move(decl)); leBlock.codeGen(*this); llvm::ReturnInst::Create(this->getContext(), _blocks.top()->returnValue, bBlock); this->popBlock(); this->createIntegerAdd(); this->createIntegerPrint(); this->popObject(); }
Regex::Regex(std::string str) { AstCodeGen codeGen(str); Ptr astNode =codeGen.generateAst(); // print(astNode); AstToNfa *astToNfa = new AstToNfa; this->node = astNode->accept(astToNfa); this->node->last->finalStatus = true; delete astToNfa; }
int main(int argc, char *argv[]) { char pgm[20]; if(argc != 2) { fprintf(stderr, "usage: %s <filename>\n", argv[0]); exit(1); } strcpy(pgm, argv[1]); source = fopen(pgm, "r"); if(source == NULL) { fprintf(stderr, "File %s not found\n", pgm); exit(1); } listing = stdout; /* send listing to screen */ fprintf(listing, "\nC-MINUS COMPILATION: %s\n", pgm); #if NO_PARSE while(getToken() != ENDFILE); #else syntaxTree = parse(); if (TraceParse) { fprintf(listing,"\nSyntax tree:\n"); printTree(syntaxTree); } #if !NO_ANALYZE if (! Error) { if (TraceAnalyze) fprintf(listing,"\nBuilding Symbol Table...\n"); buildSymtab(syntaxTree); if (TraceAnalyze) fprintf(listing,"\nChecking Types...\n"); typeCheck(syntaxTree); if (TraceAnalyze) fprintf(listing,"\nType Checking Finished\n"); } #if !NO_CODE if (! Error) { char * codefile; int fnlen = strcspn(pgm,"."); codefile = (char *) calloc(fnlen+4, sizeof(char)); strncpy(codefile,pgm,fnlen); strcat(codefile,".tm"); code = fopen(codefile,"w"); if (code == NULL) { printf("Unable to open %s\n",codefile); exit(1); } codeGen(syntaxTree,codefile); fclose(code); } #endif #endif #endif fclose(source); return 0; return 0; }
param_ret_t *do_ST_interpreter (void *userctx, char *pgm) { extern char *yy_scan_bytes(); char *my_string_buffer = yy_scan_bytes (pgm, strlen(pgm)+1); int my_parse_result = yyparse (); if (my_parse_result) return NULL; yy_delete_buffer (my_string_buffer); yylex_destroy(); param_ret_t *pret = codeGen (programBlock, userctx); cleanUp (programBlock); return pret; }
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"); } }
int main(int argc, char* argv[]) { if (argc != 2) { fprintf(stderr, "usage: %s <filename>\n", argv[0]); exit(1); } char pgm[120]; strcpy(pgm, argv[1]); if (strchr(pgm, '.') == NULL) strcat(pgm, ".cm"); source = fopen(pgm, "r"); if (source == NULL) { fprintf(stderr, "File %s not found\n", pgm); exit(1); } listing = stdout; #if NO_PARSE while (getToken() != ENDFILE); #else ASTNode* root = parse(); if (TraceParse) { fprintf(listing,"\nSyntax tree:\n"); printAST(root); } #endif if (!Error) { int fnlen = strcspn(pgm,"."); char* codefile = (char *) calloc(fnlen+1, sizeof(char)); strncpy(codefile,pgm,fnlen); codeGen(root, codefile); } fclose(source); return 0; }
int main(int argc, char **argv) { /* Handle the fiddliness of command line arguments elsewhere */ if (ParseCommandLine(argc, argv) != 0) { usage(); exit(1); } /* If the supplied filename lacks an extension, add one. */ if (strchr(sourceFileName, '.') == NULL) strcat(sourceFileName, ".cm"); /* Open the source file */ source = fopen(sourceFileName, "r"); /* If it failed, bomb out. */ if (source == NULL) { fprintf(stderr, "Sorry, but the source file %s could not be found.\n", sourceFileName); exit(1); }; /* By default, send output to standard output */ listing = stdout; fprintf(listing, COPYRIGHT "\n"); fprintf(listing, "*** C- COMPILATION: %s\n", sourceFileName); fprintf(listing, "*** Compiler built as " BUILDTYPE " version.\n"); /* If the compiler was built scanner-only, then only run the scanner */ #if NO_PARSE while (getToken() != ENDOFFILE) { /* do nothing */ }; #else fprintf(listing, "*** Parsing source program...\n"); syntaxTree = Parse(); /* Tracing enabled? Let's have it... */ if (TraceParse) { fprintf(listing, "*** Dumping syntax tree\n"); printTree(syntaxTree); }; #if !NO_ANALYSE if (!Error) { fprintf(listing, "*** Building symbol table...\n"); buildSymbolTable(syntaxTree); fprintf(listing, "*** Performing type checking...\n"); typeCheck(syntaxTree); } #if !NO_CODE if (!Error) { codeGen(syntaxTree, "output.dcl", "output"); /* did code generation succeed? */ if (!Error) { fprintf(listing,"*** Output written to \"output.dcl\"\n"); /* tracing? remind user */ if (TraceCode) fprintf(listing, "*** CODE TRACING OPTION ENABLED; see output\n"); } } #endif #endif #endif if (!Error) fprintf(listing,"*** COMPILATION COMPLETE: %d lines processed.\n", lineno); else fprintf(listing,"*** ERRORS WERE ENCOUNTERED: %d lines processed.\n", lineno); return EXIT_SUCCESS; }
int main( int argc, char * argv[] ) { /*TreeNode * syntaxTree = NULL;*/ char pgm[255]; /* source code file name */ #ifdef DEBUG source = fopen("J:\\pure_c\\story\\src\\bin\\Debug\\test.str", "rb"); #else if (argc != 2) { fprintf(stderr, "usage: %s <filename>\n", argv[0]); exit(1); } strcpy(pgm, argv[1]); if (strchr (pgm, '.') == NULL) strcat(pgm, ".str"); source = fopen(pgm, "rb"); #endif // DEBUG if (source == NULL) { fprintf(stderr, "File %s not found\n", pgm); exit(1); } listing = stdout; /* send listing to screen */ /*fprintf(listing, "\nSTORY COMPILATION: %s\n", pgm);*/ /*GlobalState *gs; gs.GCdebt = 0; gs.totalBytes = 0; gs.gcoList = NULL;*/ StState *st = StState_Create(ReallocateMemory, NULL); /*st.globalState = &gs; gs.stringTable = StringTable_Create(&st, 20);*/ LexState scanState; scanState.appState = st; scanState.lineNumber = 0; scanState.lookAhead.token = TK_EOS; scanState.currentChar = 0; FileInputBuffer fib; fib.inputFile = source; fib.length = 0; MemoryStream ms; Stream_CreateFileMemoryStream(&ms, &fib); scanState.stream = &ms; MemoryBuffer mbuff; MemoryBuffer* pmbuff = &mbuff; MemoryBuffer_Create(st, pmbuff); scanState.tokenBuffer = pmbuff; #if NO_PARSE Stream_Fill(scanState.stream); scanState.currentChar = *scanState.stream->currentPosition++; Lexer_ScanNextToken(&scanState); while(TRUE) { /*st_debug("token type: %d\n", scanState.currentToken.token);*/ PrintToken(&scanState.currentToken, scanState.tokenBuffer->buffer); if (scanState.currentToken.token == TK_EOS) break; Lexer_ScanNextToken(&scanState); } /*fclose(source);*/ MemoryBuffer_Free(st, pmbuff); /*while (getToken(&scanState) != EOS);*/ #else syntaxTree = parse(); if (TraceParse) { fprintf(listing, "\nSyntax tree:\n"); printTree(syntaxTree); } #if !NO_ANALYZE if (!Error) { if (TraceAnalyze) fprintf(listing,"\nBuilding Symbol Table...\n"); buildSymtab(syntaxTree); if (TraceAnalyze) fprintf(listing, "\nChecking Types...\n"); typeCheck(syntaxTree); if (TraceAnalyze) fprintf(listing, "\nType Checking Finished\n"); } #if !NO_CODE if (! Error) { char * codefile; int fnlen = strcspn(pgm, "."); codefile = (char *) calloc(fnlen+4, sizeof(char)); strncpy(codefile, pgm, fnlen); strcat(codefile, ".tm"); code = fopen(codefile,"w"); if (code == NULL) { printf("Unable to open %s\n",codefile); exit(1); } codeGen(syntaxTree,codefile); fclose(code); } #endif #endif #endif fclose(source); return 0; }
// Code generation function void codeGen(node *node, ofstream &outputFile) { string label; string label2; string argRight; if (node == NULL) { return; } // <program> if (node->label == "program()") { // Go to program() children codeGen(node->left, outputFile); codeGen(node->center, outputFile); // Put stop into output file outputFile << "\tSTOP\n"; // Loop thru to add lines to clear variables for (int i = 0; i < temp.size(); i++) { outputFile << temp[i] << " 0\n"; } } // <block> else if (node->label == "block()") { // Grab current scope size to track current place int start = (int)scope.size(); codeGen(node->left, outputFile); codeGen(node->center, outputFile); // Send scope position to pop function to pop correct amount pop(start, outputFile); } // <var> and <mvars> else if (node->label == "var()" || node->label == "mvars()") { // Check for variable to save current scope point if (node->label == "var()") { scopeStart = (int)scope.size(); } // Add token to stack push(node->storedTokens[0], outputFile); // Traverse children nodes codeGen(node->left, outputFile); codeGen(node->center, outputFile); } // <type> else if (node->label == "type()") { // var reached, return to var() return; } // <expr> else if (node->label == "expr()") { // Check if node has tokens stored in it if (node->storedTokens.size() > 0) { // If * star token was received if (node->storedTokens[0].tokenType == STARtk) { // Right hand evaluation codeGen(node->center, outputFile); // Copy new var name into argRight argRight = createVarName(VAR); // Add to asm output file outputFile << "\tSTORE " << argRight << "\n"; // Left hand evalutation codeGen(node->left, outputFile); // Add to asm output file outputFile << "\tMULT " << argRight << "\n"; } // If / slash token was received else if (node->storedTokens[0].tokenType == SLASHtk) { // Right hand evaluation codeGen(node->center, outputFile); // Copy new var name into argRight argRight = createVarName(VAR); // Add to asm output file outputFile << "\tSTORE " << argRight << "\n"; // Left hand evalutation codeGen(node->left, outputFile); // Add to asm output file outputFile << "\tDIV " << argRight << "\n"; } } else { // Go to children nodes codeGen(node->left, outputFile); } } // <T> else if (node->label == "T()") { // Check if node has tokens stored in it if (node->storedTokens.size() > 0) { // If + plus token was received if (node->storedTokens[0].tokenType == PLUStk) { // Right hand evaluation codeGen(node->center, outputFile); // Copy new var name into argRight argRight = createVarName(VAR); // Add to asm output file outputFile << "\tSTORE " << argRight << "\n"; // Left hand evalutation codeGen(node->left, outputFile); // Add to asm output file outputFile << "\tADD " << argRight << "\n"; } // If - minus token was received else if (node->storedTokens[0].tokenType == MINUStk) { // Right hand evaluation codeGen(node->center, outputFile); // Copy new var name into argRight argRight = createVarName(VAR); // Add to asm output file outputFile << "\tSTORE " << argRight << "\n"; // Left hand evalutation codeGen(node->left, outputFile); // Add to asm output file outputFile << "\tSUB " << argRight << "\n"; } } else { // Go to children nodes codeGen(node->left, outputFile); } } // <F> else if (node->label == "F()") { // Check if node has tokens stored in it if (node->storedTokens.size() > 0) { // Check for negation if (node->storedTokens[0].tokenType == MINUStk) { // Traverse lower to get value codeGen(node->left, outputFile); // Add negation to asm file outputFile << "\tMULT -1\n"; } } // If no negation, traverse lower else { codeGen(node->left, outputFile); } } // <R> else if (node->label == "R()") { // Check if node has tokens stored in it if (node->storedTokens.size() > 0) { // Check for ID if (node->storedTokens[0].tokenType == IDtk) { // Check variable depth in stack distanceFromTop = find(node->storedTokens[0].token); // Add ID to stack to be used later if (distanceFromTop == -1) { // Variable does not exist error(node->storedTokens[0], false); } // Add to outputfile outputFile << "\tSTACKR " << distanceFromTop << "\n"; } // Check for NUM else if (node->storedTokens[0].tokenType == NUMtk) { // NUM requires no validation, write to asm file outputFile << "\tLOAD " << node->storedTokens[0].token << "\n"; } } // Check for ( else { codeGen(node->left, outputFile); } } // <stats> else if (node->label == "stats()") { // Check children nodes codeGen(node->left, outputFile); codeGen(node->center, outputFile); } // <mStat> else if (node->label == "mStat()") { // Check children nodes codeGen(node->left, outputFile); codeGen(node->center, outputFile); } // <stat> else if (node->label == "stat()") { // Check children nodes codeGen(node->left, outputFile); } // <in> else if (node->label == "inStat()") { argRight = createVarName(VAR); // Get depth of IDtk distanceFromTop = find(node->storedTokens[0].token); if (distanceFromTop == -1) { error(node->storedTokens[0], false); } outputFile << "\tREAD " << argRight << "\n"; outputFile << "\tLOAD " << argRight << "\n"; outputFile << "\tSTACKW " << distanceFromTop << "\n"; } // <out> else if (node->label == "outStat()") { // Evaluation expr codeGen(node->left, outputFile); // Copy new var name into argRight argRight = createVarName(VAR); // Add lines to asm out outputFile << "\tSTORE " << argRight << "\n"; outputFile << "\tWRITE " << argRight << "\n"; } // <if> else if (node->label == "ifStat()") { // Copy new label/var name into label/argRight label = createVarName(LABEL); argRight = createVarName(VAR); // Evaluate right hand side inside brackets codeGen(node->center, outputFile); outputFile << "\tSTORE " << argRight << "\n"; // Evaluate left hand side inside brackets codeGen(node->left, outputFile); outputFile << "\tSUB " << argRight << "\n"; // RO token option: =< if (node->storedTokens[0].tokenType == EQUALLESSTHANtk) { outputFile << "\tBRPOS " << label << "\n"; } // RO token option: => else if (node->storedTokens[0].tokenType == EQUALGREATERTHANtk) { outputFile << "\tBRNEG " << label << "\n"; } // RO token option: == else if (node->storedTokens[0].tokenType == EQUALEQUALtk) { outputFile << "\tBRPOS " << label << "\n"; outputFile << "\tBRNEG " << label << "\n"; } // RO token option: > else if (node->storedTokens[0].tokenType == GREATERTHANtk) { outputFile << "\tBRZNEG " << label << "\n"; } // RO token option: < else if (node->storedTokens[0].tokenType == LESSTHANtk) { outputFile << "\tBRZPOS " << label << "\n"; } // RO token option: =!= else if (node->storedTokens[0].tokenType == EQUALEXCLAMATIONEQUALtk) { outputFile << "\tBRZERO " << label << "\n"; } // Go to block after if statement codeGen(node->right, outputFile); // Output asm language outputFile << "\n" << label << ": NOOP\n"; } // <loop> else if (node->label == "loop()") { // Copy labels and vars label = createVarName(LABEL); label2 = createVarName(LABEL); argRight = createVarName(VAR); // Insert break point label outputFile << "\n" << label << ": NOOP\n"; // Evaluate right side inside bracket codeGen(node->center, outputFile); // Insert asm storage outputFile << "\tSTORE " << argRight << "\n"; // Evaluate left hand side inside bracket codeGen(node->left, outputFile); // Insert asm language outputFile << "\tSUB " << argRight << "\n"; // RO token option: =< if (node->storedTokens[0].tokenType == EQUALLESSTHANtk) { outputFile << "\tBRPOS " << label2 << "\n"; } // RO token option: => else if (node->storedTokens[0].tokenType == EQUALGREATERTHANtk) { outputFile << "\tBRNEG " << label2 << "\n"; } // RO token option: == else if (node->storedTokens[0].tokenType == EQUALEQUALtk) { outputFile << "\tBRPOS " << label2 << "\n"; outputFile << "\tBRNEG " << label2 << "\n"; } // RO token option: > else if (node->storedTokens[0].tokenType == GREATERTHANtk) { outputFile << "\tBRZNEG " << label2 << "\n"; } // RO token option: < else if (node->storedTokens[0].tokenType == LESSTHANtk) { outputFile << "\tBRZPOS " << label2 << "\n"; } // RO token option: =!= else if (node->storedTokens[0].tokenType == EQUALEXCLAMATIONEQUALtk) { outputFile << "\tBRZERO " << label2 << "\n"; } // Go to block after brackets of loop codeGen(node->right, outputFile); // Add asm information outputFile << "\tBR " << label << "\n"; outputFile << "\n" << label2 << ": NOOP\n"; } // <assign> else if (node->label == "assign()") { // Right hand evaluation of <expr> codeGen(node->left, outputFile); // Get variable depth distanceFromTop = find(node->storedTokens[0].token); // Add lines to asm file if (distanceFromTop == -1) { error(node->storedTokens[0], false); } // Print into asm file outputFile << "\tSTACKW " << distanceFromTop << "\n"; } // <RO> - will never run, no seperate RO nodes else { // RO token information is part of the if/loop nodes return; } }
main(int argc, char * argv[]) { // char* pgm = "D:\\code\\Visual Studio\\visual studio 2015\\Projects\\TINY\\tiny\\Debug\\SAMPLE.TNY"; TreeNode * syntaxTree; char pgm[120]; /* source code file name */ if (argc != 2) { fprintf(stderr, "usage: %s <filename>\n", argv[0]); exit(1); } strcpy(pgm, argv[1]); if (strchr(pgm, '.') == NULL) strcat(pgm, ".tny"); //char* pgm = "D:\\code\\Visual Studio\\visual studio 2015\\Projects\\TINY\\tiny\\Debug\\SAMPLE.TNY"; source = fopen(pgm, "r"); if (source == NULL) { fprintf(stderr, "File %s not found\n", pgm); exit(1); } listing = stdout; /* send listing to screen */ fprintf(listing, "\nTINY COMPILATION: %s\n", pgm); #if NO_PARSE while (getToken() != ENDFILE); #else syntaxTree = parse();//first 词法语法分析,构造语法树 if (TraceParse) { fprintf(listing, "\nSyntax tree:\n"); printTree(syntaxTree); printf("语法树OK\n"); } #if !NO_ANALYZE printf("Error?\n"); if (!Error) { printf("no error\n"); if (TraceAnalyze) fprintf(listing, "\nBuilding Symbol Table...\n"); buildSymtab(syntaxTree);//语义分析,构造符号表 if (TraceAnalyze) fprintf(listing, "\nChecking Types...\n"); typeCheck(syntaxTree);//语义分析,执行类型检查 if (TraceAnalyze) fprintf(listing, "\nType Checking Finished\n"); } else printf("it had error\n"); #if !NO_CODE printf("Error?\n"); if (!Error) { printf("no error\n"); char * codefile; int fnlen = strcspn(pgm, "."); codefile = (char *)calloc(fnlen + 4, sizeof(char)); strncpy(codefile, pgm, fnlen); strcat(codefile, ".tm"); code = fopen(codefile, "w"); if (code == NULL) { printf("Unable to open %s\n", codefile); exit(1); } codeGen(syntaxTree, codefile);//完成代码生成 fclose(code); } #endif #endif #endif fclose(source); return 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