static void parser_create_new_var(string type) { string name="_"; name+=numtostring(tmpvarcode++); if(!symbtable_enter(name,"var",type,0,0))//assert cout << "Error:parser_create_new_var_symbtable_enter"<< endl; }
static void parser_create_new_var(symbItem *operand) { string name="_"; name+=numtostring(tmpvarcode++); if(!symbtable_enter(name,"arrvar",operand->type,0,0)) cout << "Error:parser_create_new_var_symbtable_enter"<<endl; // parser_arrvar_arr[symbtable_now->last_item]=operand; }
static symbItem* parser_create_new_lable() { string name="lab"; name+=numtostring(tmplablecode++); symbItem* ans=new symbItem(); ans->name=name; ans->kind="constpool"; ans->type="lable"; ans->link=NULL; global_const_pool.push(ans); return ans; }
void showtable(void) { Sint4 i,col; outtext("HIGH SCORES",16,25,3); col=2; for (i=1;i<11;i++) { strcpy(hsbuf,""); strcat(hsbuf,scoreinit[i]); strcat(hsbuf," "); numtostring(highbuf,scorehigh[i+1]); strcat(hsbuf,highbuf); outtext(hsbuf,16,31+13*i,col); col=1; } }
static symbItem* parser_create_new_const(symbItem *src) { symbItem *ans=new symbItem(); if(src->type=="char") { char tmp=src->value; ans->name="\'"; ans->name+=tmp; ans->name+="\'"; } else ans->name=numtostring(src->value); ans->kind="constpool"; ans->value=src->value; ans->type=src->type; ans->link=NULL; global_const_pool.push(ans); return ans; }
void savescores(void) { Sint4 i,p=0,j; if (gauntlet) p=111; if (diggers==2) p+=222; strcpy(scorebuf+p,"s"); for (i=1;i<11;i++) { strcpy(hsbuf,""); strcat(hsbuf,scoreinit[i]); strcat(hsbuf," "); numtostring(highbuf,scorehigh[i+1]); strcat(hsbuf,highbuf); for (j=0;j<11;j++) scorebuf[p+j+i*11-10]=hsbuf[j]; } writescores(); }
static int parser_factor() { symbItem *operand; if(lex_sym=="ident") { operand=symbtable_check(lex_token); if(operand==NULL) { global_error("legal ident",lex_token); return 0; } if(operand->kind=="array") { parser_create_new_var(operand); symbItem *ans=symbtable_now->last_item,*src2; lex_getsym(); if(lex_sym!="[") { global_error("[",lex_sym); return 0; } lex_getsym(); if(!parser_expression()) { string testset[]={"","]"}; parser_test(testset,2); if(lex_sym=="") { global_error("]","nothing"); return 0; } } else{ src2=operand_stack.top(); operand_stack.pop(); if(src2->kind=="const") src2=parser_create_new_const(src2); } if(lex_sym!="]") { global_error("]",lex_sym); return 0; } if(ans->type=="char"&&operand->type=="integer") { global_error("integer can not be asssigned to a char"); } global_new_quadruple("larray",operand,src2,ans);//ans=operand[src2] operand_stack.push(ans); lex_getsym(); } else if(operand->kind=="function") { parser_create_new_var(operand->type); symbItem *ans=symbtable_now->last_item; lex_getsym(); if(lex_sym=="("&&!operand->size) { global_error("no parameter",lex_sym); return 0; } else if(operand->size) { if(!parser_realparameterlist(operand)) return 0; } global_new_quadruple("call",operand,NULL,NULL); global_new_quadruple("assign",operand,NULL,ans); operand_stack.push(ans); } else if(operand->kind=="procedure") { global_error("factor","procedure "+operand->name); return 0; } else { operand_stack.push(operand);//获得操作数 lex_getsym(); } } else if(lex_sym=="(") { lex_getsym(); if(!parser_expression()) { string testset[]={"",")"}; parser_test(testset,2); if(lex_sym=="") { global_error(")","nothing"); return 0; } } if(lex_sym!=")") { global_error(")",lex_sym); return 0; } lex_getsym(); } else if(lex_sym=="digit") { symbItem *item=new symbItem(); item->name=numtostring(lex_value); item->value=lex_value; item->kind="constpool"; item->type="integer";//digit,char,string,lable item->link=NULL; operand_stack.push(item); global_const_pool.push(item);//放到常量池里面 lex_getsym(); } else { global_error("legal factor",lex_sym); return 0; } #ifdef PARSER_DEBUG cout << "因子" << endl; #endif return 1; }
static void generate_basic(quadfunc *nowfunc,quadblock *block)// { clear_tmpregpool(); quadruple *nowquad=block->firstcode; level=nowfunc->table->level; while(nowquad!=block->lastcode->link) { print_pool_info(); fprintf(x86codes,";%s\n",nowquad->opr.data()); if(nowquad->opr=="lab") { clear_tmpregpool(); fprintf(x86codes,"%s:\n",nowquad->src1->name.data()); } /* display 区的构造总述如下:假定是从第 i 层模块进入到第 j 层模块,则: (1) 如果 j=i+1(即进入一个 BEGIN 类型的模块或调用当前模块局部声明 的过程块),则复制 i 层的 display 区,然后增加一个指向 i 层模块活动记录基址 的指针。 (2) 如果 j<=i(即调用对当前模块来说是属于全程声明的过程模块),则来 自 i 层模块活动记录中的 display 区前面 j-1 个入口将组成 j 层模块的 display 区。 */ else if(nowquad->opr=="call") { /*i*/ /*j*/ clear_tmpregpool(); int mynum=0; int callerlev=nowfunc->table->level,calleelev=nowquad->src1->level+1;//函数代码所在层次=定义层次+1 if(callerlev+1==calleelev)//main调用他自己定义的过程,需要加入callerlve的dispaly区以及callerlev的ebp,注意反填 { fprintf(x86codes,"push ebp\n"); for(int i=(callerlev-1)*4;i>=0;) { fprintf(x86codes,"push dword [ebp+%d]\n",i+8); i-=4; mynum++; } } else//caller>=callee { for(int i=(calleelev-1)*4;i>=0;) { fprintf(x86codes,"push dword [ebp+%d]\n",i+8); i-=4; mynum++; } } #ifdef WIN_FORM fprintf(x86codes,"mov [ebp-8],ebx\nmov [ebp-12],edi\ncall _%s0%d\nmov ebx,[ebp-8]\nmov edi,[ebp-12]\nadd esp,%d\n", nowquad->src1->name.data(),nowquad->src1->adr,(nowquad->src1->size+mynum)*4); #else fprintf(x86codes,"mov [ebp-8],ebx\nmov [ebp-12],edi\ncall %s0%d\nmov ebx,[ebp-8]\nmov edi,[ebp-12]\nadd esp,%d\n", nowquad->src1->name.data(),nowquad->src1->adr,(nowquad->src1->size+mynum)*4); #endif } else if(nowquad->opr=="ret") { clear_tmpregpool(); if(nowfunc->table->level) { if(nowquad->src1->kind=="function"&&nowquad->src1->type=="char") fprintf(x86codes,"movsx eax,byte [ebp-4]\nmov esp,ebp\npop ebp\nret\n"); else fprintf(x86codes,"mov eax,[ebp-4]\nmov esp,ebp\npop ebp\nret\n"); } else fprintf(x86codes,"mov esp,ebp\nret\n"); } else if(nowquad->opr=="func")//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! { clear_tmpregpool(); if(nowquad->src1->name=="main") { #ifdef WIN_FORM fprintf(x86codes,"_main:\nmov ebp,esp\nsub esp,%d\n",nowfunc->table->localsnum*4+16); #else fprintf(x86codes,"main:\nmov ebp,esp\nsub esp,%d\n",nowfunc->table->localsnum*4+16); #endif } else { #ifdef WIN_FORM fprintf(x86codes,"_%s0%d:\npush ebp\nmov ebp,esp\nsub esp,%d\n" ,nowquad->src1->name.data(),nowquad->src1->adr,nowfunc->table->localsnum*4+16); #else fprintf(x86codes,"%s0%d:\npush ebp\nmov ebp,esp\nsub esp,%d\n" ,nowquad->src1->name.data(),nowquad->src1->adr,nowfunc->table->localsnum*4+16); #endif } } else if(nowquad->opr=="jmp") { clear_tmpregpool(); fprintf(x86codes,"jmp %s\n",nowquad->src1->name.data()); } else if(nowquad->opr=="add"||nowquad->opr=="sub"||nowquad->opr=="imul") {//只需要一个寄存器就好。 string src1,src2,ans; mod_mark(nowquad); if(nowquad->src1->kind=="constpool") src1=nowquad->src1->name; else{ putsrcinreg(nowquad->src1,src1,1,nowquad,0); } if(nowquad->src2->kind=="constpool") src2=nowquad->src2->name; else putsrcinreg(nowquad->src2,src2,1,nowquad,0); putsrcinreg(nowquad->ans,ans,0,nowquad,1); if(ans==src1&&ans==src2) fprintf(x86codes,"%s %s,%s\n",nowquad->opr.data(),ans.data(),ans.data()); else if(src1==ans) { fprintf(x86codes,"%s %s,%s\n",nowquad->opr.data(),src1.data(),src2.data()); } else if(src2==ans) { fprintf(x86codes,"mov eax,%s\n%s eax,%s\nmov %s,eax\n",src1.data(), nowquad->opr.data(),src2.data(),ans.data()); } else fprintf(x86codes,"mov %s,%s\n%s %s,%s\n",ans.data(),src1.data(),nowquad->opr.data(),ans.data(),src2.data()); }else if(nowquad->opr=="idiv") { string src1,src2,ans; mod_mark(nowquad); if(nowquad->src2->kind=="constpool") { int id=register_reg(nowquad->src2,0); mod_mark(nowquad); fprintf(x86codes,"mov %s,%s\n",tmpadr_reg[id].data(),nowquad->src2->name.data()); mod_reg_pool(id,1,NULL,0); src2=tmpadr_reg[id]; } else putsrcinreg(nowquad->src2,src2,1,nowquad,0); if(nowquad->src1->kind=="constpool") src1=nowquad->src1->name; else putsrcinreg(nowquad->src1,src1,1,nowquad,0); fprintf(x86codes,"mov eax,%s\n",src1.data()); if(tmpregpool[tmpreg_adr["edx"]].write_back) { hwrite_back(tmpregpool[tmpreg_adr["edx"]].value,"edx"); mod_reg_pool(tmpreg_adr["edx"],0,NULL,0); } fprintf(x86codes,"cdq\n"); nolock[tmpreg_adr["edx"]]=0; fprintf(x86codes,"idiv %s\n",src2.data()); nolock[tmpreg_adr["edx"]]=1;//解锁的时机不太对 putsrcinreg(nowquad->ans,ans,0,nowquad,1); fprintf(x86codes,"mov %s,eax\n",ans.data()); } else if(nowquad->opr=="je"||nowquad->opr=="jl"||nowquad->opr=="jle"|| nowquad->opr=="jg"||nowquad->opr=="jne"||nowquad->opr=="jge") { string src1,src2; mod_mark(nowquad); if(nowquad->src1->kind=="constpool") { fprintf(x86codes,"mov eax,%s\n",nowquad->src1->name.data()); src1="eax"; } else putsrcinreg(nowquad->src1,src1,1,nowquad,0); if(nowquad->src2->kind=="constpool") src2=numtostring(nowquad->src2->value); else putsrcinreg(nowquad->src2,src2,1,nowquad,0); clear_tmpregpool(); fprintf(x86codes,"cmp %s,%s\n%s %s\n",src1.data(),src2.data(),nowquad->opr.data(),nowquad->ans->name.data()); } else if(nowquad->opr=="assign") { string src1,ans; mod_mark(nowquad); if(nowquad->src1->kind=="function") { putsrcinreg(nowquad->src1,src1,0,nowquad,0); fprintf(x86codes,"mov %s,eax\n",src1.data()); hwrite_back(nowquad->ans,src1); } else if(nowquad->ans->kind=="function") { int flag=0; if(nowquad->src1->kind=="constpool") { flag=1; src1=numtostring(nowquad->src1->value); } else putsrcinreg(nowquad->src1,src1,1,nowquad,0); string ifdword=flag?"dword":""; if(nowquad->ans->level==level-1) { fprintf(x86codes,"mov %s [ebp-4],%s\n",ifdword.data(),src1.data()); } else { fprintf(x86codes,"mov eax,[ebp+%d]\nmov %s [eax-4],%s\n",8+4*(nowquad->ans->level+1),ifdword.data(),src1.data()); } } else { if(nowquad->src1->kind=="constpool") { int id=register_reg(nowquad->src1,0); mod_mark(nowquad); fprintf(x86codes,"mov %s,%s\n",tmpadr_reg[id].data(),nowquad->src1->name.data()); mod_reg_pool(id,1,NULL,0); src1=tmpadr_reg[id]; } else putsrcinreg(nowquad->src1,src1,1,nowquad,0); hwrite_back(nowquad->ans,src1); int id=checkifintmpreg(nowquad->ans); mod_reg_pool(id,0,NULL,0); } } else if(nowquad->opr=="neg"||nowquad->opr=="inc"||nowquad->opr=="dec") { mod_mark(nowquad); int id=checkifintmpreg(nowquad->src1); string src1; if(id) { src1=tmpadr_reg[id]; mod_reg_pool(id,1,nowquad->src1,1); } else putsrcinreg(nowquad->src1,src1,1,nowquad,1); fprintf(x86codes,"%s %s\n",nowquad->opr.data(),src1.data()); } else if(nowquad->opr=="rpara")//rpara增加一个参数(笑脸)取地址或者全局寄存器 { clear_tmpregpool(); if(nowquad->src1->level==level) { if(nowquad->src1->kind=="parameter") { if(nowquad->src1->para_ifvar) fprintf(x86codes,"mov eax,[ebp+%d]\npush eax\n",4+4*(level+nowquad->src1->adr)); else fprintf(x86codes,"lea eax,[ebp+%d]\npush eax\n",4+4*(level+nowquad->src1->adr)); } else if(nowquad->src1->adr%4) { if(nowquad->src1->kind!="arrvar") fprintf(x86codes,"lea eax,[ebp-%d]\npush eax\n",4+nowquad->src1->adr*4); else fprintf(x86codes,"push %s\n",adr_reg[nowquad->src1->adr].data()); } else { if(nowquad->src1->kind=="arrvar") fprintf(x86codes,"push dword [ebp%d]\n",nowquad->src1->adr); else fprintf(x86codes,"lea eax,[ebp%d]\npush eax\n",nowquad->src1->adr); } } else { if(nowquad->src1->kind=="parameter") { if(nowquad->src1->para_ifvar) { fprintf(x86codes,"mov eax,[ebp+%d]\npush dword [eax+%d]\n",8+nowquad->src1->level*4,4+4*(nowquad->src1->level+nowquad->src1->adr)); } else fprintf(x86codes,"mov eax,[ebp+%d]\nlea eax,[eax+%d]\npush eax\n",8+nowquad->src1->level*4,4+4*(nowquad->src1->level+nowquad->src1->adr)); } else if(nowquad->src1->adr%4) { if(nowquad->src1->kind=="arrvar") fprintf(x86codes,"mov eax,[ebp+%d]\npush dword[eax-%d]\n",8+nowquad->src1->level*4,4+4*nowquad->src1->adr); else fprintf(x86codes,"mov eax,[ebp+%d]\nlea eax,[eax-%d]\npush eax\n",8+nowquad->src1->level*4,4+4*nowquad->src1->adr); } else { if(nowquad->src1->kind=="arrvar") fprintf(x86codes,"mov eax,[ebp+%d]\npush dword [eax%d]\n",8+nowquad->src1->level*4,nowquad->src1->adr); else fprintf(x86codes,"mov eax,[ebp+%d]\nlea eax,[eax%d]\npush eax\n",8+nowquad->src1->level*4,nowquad->src1->adr); } } } else if(nowquad->opr=="fpara") { mod_mark(nowquad); string src1="eax"; symbItem *srca=nowquad->src1; if(srca->kind=="constpool") fprintf(x86codes,"mov eax,%s\n",srca->name.data()); else putsrcinreg(srca,src1,1,nowquad,0); fprintf(x86codes,"push %s\n",src1.data()); } else if(nowquad->opr=="larray")//larray src1 src2 ans : ans=src1[src2]//larray指令具有二义性,arrvar类型代表地址,否则给一个数 { mod_mark(nowquad);int flag=0; string src1,src2,ans,tm; if(nowquad->src2->kind=="constpool") { src2=numtostring(nowquad->src2->value); } else putsrcinreg(nowquad->src2,src2,1,nowquad,0); putsrcinreg(nowquad->ans,ans,0,nowquad,1); if(nowquad->ans->kind=="arrvar") flag=1; tm=flag==1?ans:"eax"; if(nowquad->src1->level==level) { fprintf(x86codes,"lea %s,[ebp+%s*4%d]\n",tm.data(),src2.data(),nowquad->src1->adr); } else { fprintf(x86codes,"mov eax,[ebp+%d]\nlea %s,[eax+%s*4%d]\n",8+nowquad->src1->level*4,tm.data(),src2.data(),nowquad->src1->adr); } if(!flag) { if(nowquad->ans->type=="integer")//????????????????????????? fprintf(x86codes,"mov %s,[eax]\n",ans.data()); else fprintf(x86codes,"mov %s,[eax]\n",ans.data()); } else { write_backarrvar(nowquad->ans,ans); } } else if(nowquad->opr=="sarray") { mod_mark(nowquad); int id=register_reg(nowquad->src1,0); mod_mark(nowquad); string eax=tmpadr_reg[id]; string src2,ans; if(nowquad->src2->kind=="constpool") { src2=numtostring(nowquad->src2->value); } else putsrcinreg(nowquad->src2,src2,1,nowquad,0); if(nowquad->src1->level==level) { fprintf(x86codes,"lea %s,[ebp+%s*4%d]\n",eax.data(),src2.data(),nowquad->src1->adr); } else { fprintf(x86codes,"mov %s,[ebp+%d]\nlea %s,[%s+%s*4%d]\n",eax.data(),8+nowquad->src1->level*4,eax.data(),eax.data(),src2.data(),nowquad->src1->adr); } if(nowquad->ans->kind=="constpool") { ans=numtostring(nowquad->ans->value); fprintf(x86codes,"mov dword [%s],%s\n",eax.data(),ans.data()); } else { putsrcinreg(nowquad->ans,ans,1,nowquad,0); fprintf(x86codes,"mov [%s],%s\n",eax.data(),ans.data()); } mod_reg_pool(id,0,NULL,0); } else if(nowquad->opr=="writes") { mod_mark(nowquad); #ifdef WIN_FORM fprintf(x86codes,"push str%d\ncall _printf\nadd esp,4\n",nowquad->src1->value); #else fprintf(x86codes,"push str%d\ncall printf\nadd esp,4\n",nowquad->src1->value); #endif } else if(nowquad->opr=="writee")//tmp var的类型们不一定是int { mod_mark(nowquad); string src1="eax"; if(nowquad->src1->kind=="constpool") { fprintf(x86codes,"mov eax,%s\n",nowquad->src1->name.data()); } else{ putsrcinreg(nowquad->src1,src1,1,nowquad,0); } if(nowquad->src1->type=="integer"||nowquad->src1->type=="char"&&(nowquad->src1->kind!="arrvar"&&nowquad->src1->name[0]=='_')) { #ifdef WIN_FORM fprintf(x86codes,"push %s\npush strint\n",src1.data()); clear_tmpregpool(); fprintf(x86codes,"call _printf\nadd esp,8\n"); #else fprintf(x86codes,"push %s\npush strint\n",src1.data()); clear_tmpregpool(); fprintf(x86codes,"call printf\nadd esp,8\n"); #endif } else { #ifdef WIN_FORM fprintf(x86codes,"push %s\npush stroutchar\n",src1.data()); clear_tmpregpool(); fprintf(x86codes,"call _printf\nadd esp,8\n"); #else fprintf(x86codes,"push %s\npush stroutchar\n",src1.data()); clear_tmpregpool(); fprintf(x86codes,"call printf\nadd esp,8\n"); #endif } } else if(nowquad->opr=="read") { string src1; mod_mark(nowquad); putsrcinreg(nowquad->src1,src1,0,nowquad,1); if(nowquad->src1->type=="integer") { #ifdef WIN_FORM fprintf(x86codes,"sub esp,4\npush esp\n push strint\n"); clear_tmpregpool(); fprintf(x86codes,"call _scanf\nadd esp,8\n"); putsrcinreg(nowquad->src1,src1,0,nowquad,1); fprintf(x86codes,"mov %s,[esp]\n",src1.data()); #else fprintf(x86codes,"sub esp,4\npush esp\n push strint\n"); clear_tmpregpool(); fprintf(x86codes,"call scanf\nadd esp,8\n"); putsrcinreg(nowquad->src1,src1,0,nowquad,1); fprintf(x86codes,"mov %s,[esp]\n",src1.data()); #endif } else { #ifdef WIN_FORM fprintf(x86codes,"sub esp,4\npush esp\n push strchar\n"); clear_tmpregpool(); fprintf(x86codes,"call _scanf\n"); putsrcinreg(nowquad->src1,src1,0,nowquad,1); fprintf(x86codes,"add esp,8\nmovsx %s,byte[esp]\n",src1.data()); #else fprintf(x86codes,"sub esp,4\npush esp\n push strchar\n"); clear_tmpregpool(); fprintf(x86codes,"call scanf\n"); putsrcinreg(nowquad->src1,src1,0,nowquad,1); fprintf(x86codes,"add esp,8\nmovsx %s,byte[esp]\n",src1.data()); #endif } fprintf(x86codes,"add esp,4\n"); } else { cout << "IMPOSSIBLE!"<<endl; } nowquad=nowquad->link; } clear_tmpregpool(); }