簡易コンパイラのコード生成処理のルーチン。
スタック内での動きを記述。
これで、様々な四則演算をコンピュータにコードで教えることができる。
ソースは↓
/* ------------------------------------サブルーチン(コード生成)ここから--------------------------------- */ int code_generation() { /* ・構造体のkindにACCの時は'-1'そうでないときは'1'を格納。 ・構造体のdataにアドレスを格納。 */ struct stacks { int kind; char data; }stack[MAXLENG]; int p,q,r,gyou2; char *str; q=0; fprintf(fp2,"【code-generation】\n"); if(syntactic_result[0].result==1||syntactic_result[0].result==2) {/* 一つめのスタックに格納 */ str=syntactic_result[0].jiku; stack[0].kind=1; stack[0].data=(int)&str; } else { printf("code_generation ERROR!\n"); /* 一つめのスタックに識別子か定数が格納されなかった場合エラー表示 */ } for(p=1;p<MAXLENG;p++) { if(syntactic_result[p].result==1||syntactic_result[p].result==2) {/* 識別子か定数の場合はスタックにアドレスをプッシュダウンしていく */ if(stack[q].kind==0) { str=syntactic_result[p].jiku; stack[q].kind=1; stack[q].data=(int)&str; break; } q++; str=syntactic_result[p].jiku; stack[q].kind=1; stack[q].data=(int)&str; if(gyou_kaihi!=0) { for(gyou2=0;gyou2<=gyou_kaihi*MAXLENG;gyou2++) { str++; } } } /* ----------------------------------------------------------- スタック[i]とスタック[i-1]が演算数が記憶されたアドレスである時 ----------------------------------------------------------- */ else if(stack[q].kind==1 && stack[q-1].kind==1) { if(syntactic_result[p].result==3) {/* ':='のコード生成の判定 */ for(r=0;r<q;r++) {/* スタック内にACCの存在を検索 */ if(stack[r].kind==-1) { stack[r].kind=1; stack[r].data=(int)&str; fprintf(fp2,"STORE\t\t%p\n",str); str++; break; } } fprintf(fp2,"LOAD\t\t%p\n",temp[p-1]); fprintf(fp2,"STORE\t\t%p\n",temp[p-2]); stack[q].kind=0; stack[--q].kind=-1; } if(syntactic_result[p].result==4) {/* '+'のコード生成の判定 */ for(r=0;r<q;r++) { if(stack[r].kind==-1) { stack[r].kind=1; stack[r].data=(int)&str; fprintf(fp2,"STORE\t\t%p\n",str); str++; break; } } fprintf(fp2,"LOAD\t\t%p\n",temp[p-2]); fprintf(fp2,"ADD\t\t%p\n",temp[p-1]); stack[q].kind=0; stack[--q].kind=-1; } if(syntactic_result[p].result==5) {/* '-'のコード生成の判定 */ for(r=0;r<q;r++) { if(stack[r].kind==-1) { stack[r].kind=1; stack[r].data=(int)&str; fprintf(fp2,"STORE\t\t%p\n",str); str++; break; } } fprintf(fp2,"LOAD\t\t%p\n",temp[p-2]); fprintf(fp2,"SUB\t\t%p\n",temp[p-1]); stack[q].kind=0; stack[--q].kind=-1; } if(syntactic_result[p].result==6) {/* '*'のコード生成の判定 */ for(r=0;r<q;r++) { if(stack[r].kind==-1) { stack[r].kind=1; stack[r].data=(int)&str; fprintf(fp2,"STORE\t\t%p\n",str); str++; break; } } fprintf(fp2,"LOAD\t\t%p\n",temp[p-2]); fprintf(fp2,"MUL\t\t%p\n",temp[p-1]); stack[q].kind=0; stack[--q].kind=-1; } if(syntactic_result[p].result==7) {/* '/'のコード生成の判定 */ for(r=0;r<q;r++) { if(stack[r].kind==-1) { stack[r].kind=1; stack[r].data=(int)&str; fprintf(fp2,"STORE\t\t%p\n",str); str++; break; } } fprintf(fp2,"LOAD\t\t%p\n",temp[p-2]); fprintf(fp2,"DIV\t\t%p\n",temp[p-1]); stack[q].kind=0; stack[--q].kind=-1; } } /* -------------------------------------------------------------------------------------- スタック[i]が演算数が記憶されたアドレスで、スタック[i-1]が演算数がACCに記憶さてれている時 -------------------------------------------------------------------------------------- */ else if(stack[q].kind==1 && stack[q-1].kind==-1) { if(syntactic_result[p].result==3) { fprintf(fp2,"STORE\t\t%p\n",temp[p-1]);/* ':='のコード生成の判定 */ stack[q].kind=0; stack[--q].kind=-1; } if(syntactic_result[p].result==4) {/* '+'のコード生成の判定 */ fprintf(fp2,"ADD\t\t%p\n",temp[p-1]); stack[q].kind=0; stack[--q].kind=-1; } if(syntactic_result[p].result==5) {/* '-'のコード生成の判定 */ fprintf(fp2,"SUB\t\t%p\n",temp[p-1]); stack[q].kind=0; stack[--q].kind=-1; } if(syntactic_result[p].result==6) {/* '*'のコード生成の判定 */ fprintf(fp2,"MUL\t\t%p\n",temp[p-1]); stack[q].kind=0; stack[--q].kind=-1; } if(syntactic_result[p].result==7){/* '/'のコード生成の判定 */ fprintf(fp2,"DIV\t\t%p\n",temp[p-1]); stack[q].kind=0; stack[--q].kind=-1; } } /* -------------------------------------------------------------------------------------- スタック[i]が演算数がACCに記憶さてれていて、スタック[i-1]が演算数が記憶されたアドレスの時 -------------------------------------------------------------------------------------- */ else if(stack[q].kind==-1 && stack[q-1].kind==1) { if(syntactic_result[p].result==3) {/* ':='のコード生成の判定 */ fprintf(fp2,"STORE\t\t%p\n",temp[q-1]); stack[q].kind=0; stack[--q].kind=-1; } if(syntactic_result[p].result==4) {/* '+'のコード生成の判定 */ str--; fprintf(fp2,"ADD\t\t%p\n",str); str++; stack[q].kind=0; stack[--q].kind=-1; } if(syntactic_result[p].result==5) {/* '-'のコード生成の判定 */ fprintf(fp2,"STORE\t\t%p\n",str); str--; fprintf(fp2,"LOAD\t\t%p\n",str); str++; fprintf(fp2,"SUB\t\t%p\n",str); str++; stack[q].kind=0; stack[--q].kind=-1; } if(syntactic_result[p].result==6) {/* '*'のコード生成の判定 */ str--; fprintf(fp2,"MUL\t\t%p\n",str); str++; stack[q].kind=0; stack[--q].kind=-1; } if(syntactic_result[p].result==7) {/* '/'のコード生成の判定 */ fprintf(fp2,"STORE\t\t%p\n",str); str--; fprintf(fp2,"LOAD\t\t%p\n",str); str++; fprintf(fp2,"DIV\t\t%p\n",str); str++; stack[q].kind=0; stack[--q].kind=-1; } } } fprintf(fp2,"\n\n\n"); return 0; } /* -----------------------------------サブルーチン(コード生成)ここまで-------------------------------- */