CodeGen.c
资源名称:C语言编译器.rar [点击查看]
上传用户:wqdrylgs
上传日期:2007-02-09
资源大小:65k
文件大小:18k
源码类别:
汇编语言
开发平台:
WINDOWS
- #include <stdlib.h>
- #include "globals.h"
- #include "parse.h"
- #include "symtab.h"
- static int label_num = 0;
- TreeNode * Fun;
- void GenLabel(char lab[LABEL_SIZE])
- {
- static int i=1;
- char temp[LABEL_SIZE];
- strcpy(lab,"L");
- _itoa(i,temp,10);
- strcat(lab,temp);
- i++;
- }
- void StackSegmentBegin(void)
- {
- fprintf(inter_code,";*******************************************************n");
- fprintf(inter_code,"Stack_segtsegmentn");
- fprintf(inter_code,"tdwt1024 dup(?)n");
- fprintf(inter_code,"ttostlabeltwordn");
- fprintf(inter_code,"Stack_segtendsn");
- fprintf(inter_code,";*******************************************************n");
- fprintf(inter_code,"Data_segtsegmentn");
- }
- void StackSegmentEnd(void)
- {
- fprintf(inter_code,"Data_segtendsn");
- fprintf(inter_code,";*******************************************************n");
- }
- void CodeSegmentBegin(void)
- {
- fprintf(inter_code,"Code_segtsegmentn");
- fprintf(inter_code,"tassumetCS:Code_seg, DS:Data_seg, SS:Stack_segn");
- }
- void CodeSegmentEnd(void)
- {
- fprintf(inter_code,"Code_segtendsn");
- fprintf(inter_code,"tendtstartn");
- fprintf(inter_code,";*******************************************************n");
- }
- void VarDec_ini(char *name, int value)//local variable declaration with initial value
- {
- int os;
- ValEntry * pEntry = malloc(sizeof(ValEntry));
- if(pTable ->nestlevel == 0)
- fprintf(inter_code,"t%stdwt%dn",name,value);
- else
- {
- Lookup_Var(pTable, pTable ->funEntry, name, pEntry);
- os = pEntry ->offset;
- fprintf(inter_code,"tPUSHtAXn");//为该变量占个位置,迫使sp移动
- fprintf(inter_code,"tPUSHtAXn");//store value
- fprintf(inter_code,"tMOVtAX , %dn",value);
- fprintf(inter_code,"tPUSHtBPn");//calculate variable address
- fprintf(inter_code,"tADDtBP , %dn",os);
- fprintf(inter_code,"tMOVtSS:[BP] , AXn",os);//store value
- fprintf(inter_code,"tPOPtBPn");
- fprintf(inter_code,"tPOPtAXn");
- }
- }
- void VarDec(char *name)//local variable declaration without initial value
- {
- if(pTable ->nestlevel == 0)
- fprintf(inter_code,"t%stdwt?n",name);
- else
- fprintf(inter_code,"tPUSHtAXn");//为该变量占个位置,迫使sp移动
- }
- void ArrDec(char *name, int entitynum)
- {
- int i;
- if(pTable ->nestlevel == 0)
- fprintf(inter_code,"t%stdwt%d dup(?)n",name,entitynum);//to data file
- else
- for(i = 0; i < entitynum; i ++)
- fprintf(inter_code,"tPUSHtAXn");//为该变量占个位置,迫使sp移动
- }
- void ent(char *name, int para, int retvalue)
- {
- fprintf(inter_code,"t%stproctfarn",name);//to code file
- if(!strcmp("main",name)){//main function
- fprintf(inter_code,"start:n");
- fprintf(inter_code,"tMOVtAX , Stack_segn");
- fprintf(inter_code,"tMOVtSS , AXn");
- fprintf(inter_code,"tMOVtSP , offset tosnn");
- fprintf(inter_code,"tPUSHtDSn");
- fprintf(inter_code,"tSUBtAX , AXn");
- fprintf(inter_code,"tPUSHtAXnn");
- fprintf(inter_code,"tMOVtAX , Data_segn");
- fprintf(inter_code,"tMOVtDS , AXn");
- }
- fprintf(inter_code,"tPUSHtAXn");
- fprintf(inter_code,"tPUSHtBXn");
- fprintf(inter_code,"tPUSHtCXn");
- fprintf(inter_code,"tPUSHtDXn");
- fprintf(inter_code,"tPUSHtBPn");
- fprintf(inter_code,"tMOVtBP , SPn");//begin to accept local variables
- }
- //--------------------------------------------------
- void adi(void)
- {
- fprintf(inter_code,"tPOPtBXn");
- fprintf(inter_code,"tPOPtAXn");
- fprintf(inter_code,"tADDtAX , BXn");
- fprintf(inter_code,"tPUSHtAXn");
- }
- void andi(void)
- {
- fprintf(inter_code,"tPOPtBXn");
- fprintf(inter_code,"tPOPtAXn");
- fprintf(inter_code,"tANDtAX , BXn");
- fprintf(inter_code,"tPUSHtAXn");
- }
- void compound_enter(void)
- {
- }
- void compound_exit(void)
- {
- pTable = pTable->parent;
- }
- void cup(char *name, int paranum) //function call end, 'int' is the number of actual parameters
- {
- fprintf(inter_code,"tCALLt%sn",name);
- }
- void divi(void)
- {
- fprintf(inter_code,"tPOPtBXn");
- fprintf(inter_code,"tPOPtAXn");
- fprintf(inter_code,"tPUSHtDXn");
- fprintf(inter_code,"tIDIVtBXn");
- fprintf(inter_code,"tPOPtDXn");
- fprintf(inter_code,"tPUSHtAXn");
- }
- void equi(void)
- {
- fprintf(inter_code,"tPOPtBXn");
- fprintf(inter_code,"tPOPtAXn");
- fprintf(inter_code,"tCMPtAX , BXn");
- fprintf(inter_code,"tJEtLabel%dn",label_num);
- fprintf(inter_code,"tMOVtAX , 0n");
- fprintf(inter_code,"tPUSHtAXn");
- fprintf(inter_code,"tJMPtLabel%dn",label_num + 1);
- fprintf(inter_code,"Label%d:",label_num);
- fprintf(inter_code,"tMOVtAX , 1n");
- fprintf(inter_code,"tPUSHtAXn");
- fprintf(inter_code,"Label%d:",label_num + 1);
- label_num += 2;
- }
- void leave(char *name)
- {
- fprintf(inter_code,"t%stendpn",name);
- }
- void fjp(char*label)
- {
- fprintf(inter_code,"tPOPtAXn");
- fprintf(inter_code,"tCMPtAX , 0n");
- fprintf(inter_code,"tJEt%sn",label);
- }
- void gorei(void)
- {
- fprintf(inter_code,"tPOPtBXn");
- fprintf(inter_code,"tPOPtAXn");
- fprintf(inter_code,"tCMPtAX , BXn");
- fprintf(inter_code,"tJGEtLabel%dn",label_num);
- fprintf(inter_code,"tMOVtAX , 0n");
- fprintf(inter_code,"tPUSHtAXn");
- fprintf(inter_code,"tJMPtLabel%dn",label_num+1);
- fprintf(inter_code,"Label%d:",label_num);
- fprintf(inter_code,"tMOVtAX , 1n");
- fprintf(inter_code,"tPUSHtAXn");
- fprintf(inter_code,"Label%d:",label_num+1);
- label_num += 2;
- }
- void greater(void)
- {
- fprintf(inter_code,"tPOPtBXn");
- fprintf(inter_code,"tPOPtAXn");
- fprintf(inter_code,"tCMPtAX , BXn");
- fprintf(inter_code,"tJGtLabel%dn",label_num);
- fprintf(inter_code,"tMOVtAX , 0n");
- fprintf(inter_code,"tPUSHtAXn");
- fprintf(inter_code,"tJMPtLabel%dn",label_num+1);
- fprintf(inter_code,"Label%d:",label_num);
- fprintf(inter_code,"tMOVtAX , 1n");
- fprintf(inter_code,"tPUSHtAXn");
- fprintf(inter_code,"Label%d:",label_num+1);
- label_num += 2;
- }
- void ind(char *name)
- {
- if(pTable ->nestlevel == 0){
- fprintf(inter_code,"tPOPtBXn");
- fprintf(inter_code,"tPUSHtDS:[BX]n");
- }
- else{
- fprintf(inter_code,"tPOPtBXn");
- fprintf(inter_code,"tPUSHtBPn");
- fprintf(inter_code,"tMOVtBP , BXn");
- fprintf(inter_code,"tPUSHtSS:[BP]n");
- fprintf(inter_code,"tPOPtBPn");
- }
- }
- void ixa_elem_size(void)
- {
- fprintf(inter_code,"tPOPtAXn");
- fprintf(inter_code,"tPOPtBXn");
- fprintf(inter_code,"tSHLtAX , %dn",EXP_VARIABLE_LENGTH);//AX * VARIABLE_LENGTH
- fprintf(inter_code,"tADDtAX , BXn");
- fprintf(inter_code,"tPUSHtAXn");
- }
- void lab(char *label)
- {
- fprintf(inter_code,"%s :n",label);
- }
- void ldl(char value)
- {
- fprintf(inter_code,"tMOVtAX , %dn",(int)value);
- fprintf(inter_code,"tPUSHtAXn");
- }
- void lda(char *name)//load address
- {
- int addr = 0;
- ValEntry * pEntry = malloc(sizeof(ValEntry));
- if(pTable ->nestlevel == 0){
- fprintf(inter_code,"tLEAtAX , %sn",name);
- fprintf(inter_code,"tPUSHtAXn");
- }
- else{
- Lookup_Var(pTable, pTable ->funEntry, name, pEntry);
- addr = pEntry->offset;
- fprintf(inter_code,"tMOVtAX , BPn");
- fprintf(inter_code,"tADDtAX , %dn",addr);
- fprintf(inter_code,"tPUSHtAXn");
- }
- }
- void ldc(int value)//load constant
- {
- fprintf(inter_code,"tMOVtAX , %dn",value);
- fprintf(inter_code,"tPUSHtAXn");
- }
- void less(void)
- {
- fprintf(inter_code,"tPOPtBXn");
- fprintf(inter_code,"tPOPtAXn");
- fprintf(inter_code,"tCMPtAX , BXn");
- fprintf(inter_code,"tJLtLabel%dn",label_num);
- fprintf(inter_code,"tMOVtAX , 0n");
- fprintf(inter_code,"tPUSHtAXn");
- fprintf(inter_code,"tJMPtLabel%dn",label_num+1);
- fprintf(inter_code,"Label%d:",label_num);
- fprintf(inter_code,"tMOVtAX , 1n");
- fprintf(inter_code,"tPUSHtAXn");
- fprintf(inter_code,"Label%d:",label_num+1);
- label_num += 2;
- }
- void lod(char *name)
- {
- int addr = 0;
- ValEntry * pEntry = malloc(sizeof(ValEntry));
- Lookup_Var(pTable, pTable ->funEntry, name, pEntry);
- if(pTable ->nestlevel == 0){
- fprintf(inter_code,"tMOVtAX , %sn",name);
- fprintf(inter_code,"tPUSHtAXn");
- }
- else{
- Lookup_Var(pTable,pTable ->funEntry, name,pEntry);
- addr = pEntry ->offset;
- fprintf(inter_code,"tPUSHtBPn");
- fprintf(inter_code,"tADDtBP , %dn",addr);
- fprintf(inter_code,"tMOVtAX , SS:[BP]n");
- fprintf(inter_code,"tPOPtBPn");
- fprintf(inter_code,"tPUSHtAXn");
- }
- }
- void lorei(void)
- {
- fprintf(inter_code,"tPOPtBXn");
- fprintf(inter_code,"tPOPtAXn");
- fprintf(inter_code,"tCMPtAX , BXn");
- fprintf(inter_code,"tJLEtLabel%dn",label_num);
- fprintf(inter_code,"tMOVtAX , 0n");
- fprintf(inter_code,"tPUSHtAXn");
- fprintf(inter_code,"tJMPtLabel%dn",label_num+1);
- fprintf(inter_code,"Label%d:",label_num);
- fprintf(inter_code,"tMOVtAX , 1n");
- fprintf(inter_code,"tPUSHtAXn");
- fprintf(inter_code,"Label%d:",label_num+1);
- label_num += 2;
- }
- void mst(char *name)
- {
- }
- void multi(void)
- {
- fprintf(inter_code,"tPOPtBXn");
- fprintf(inter_code,"tPOPtAXn");
- fprintf(inter_code,"tPUSHtDXn");
- fprintf(inter_code,"tIMULtBXn");
- fprintf(inter_code,"tPOPtDXn");
- fprintf(inter_code,"tPUSHtAXn");
- }
- void neqi(void)
- {
- fprintf(inter_code,"tPOPtBXn");
- fprintf(inter_code,"tPOPtAXn");
- fprintf(inter_code,"tCMPtAX , BXn");
- fprintf(inter_code,"tJNEtLabel%dn",label_num);
- fprintf(inter_code,"tMOVtAX , 0n");
- fprintf(inter_code,"tPUSHtAXn");
- fprintf(inter_code,"tJMPtLabel%dn",label_num+1);
- fprintf(inter_code,"Label%d:",label_num);
- fprintf(inter_code,"tMOVtAX , 1n");
- fprintf(inter_code,"tPUSHtAXn");
- fprintf(inter_code,"Label%d:",label_num+1);
- label_num += 2;
- }
- void ori(void)
- {
- fprintf(inter_code,"tPOPtBXn");
- fprintf(inter_code,"tPOPtAXn");
- fprintf(inter_code,"tORtAX , BXn");
- fprintf(inter_code,"tPUSHtAXn");
- }
- void pop(void)
- {
- fprintf(inter_code,"tPOPtAXn");
- }
- void ret(int r,char * name)
- {
- int addr = 0;
- FunEntry * pEntry = malloc(sizeof(FunEntry));
- if(r){//if the function has a return value
- fprintf(inter_code,"tPOPtAXn");//get the return value from the top of the stack
- pEntry = Lookup_Fun(name);
- addr = pEntry ->ret_val;
- fprintf(inter_code,"tPUSHtBPn");
- fprintf(inter_code,"tADDtBP , %dn",addr);
- fprintf(inter_code,"tMOVtSS:[BP] , AXn");
- fprintf(inter_code,"tPOPtBPn");
- }
- fprintf(inter_code,"tMOVtSP , BPn");//release local parameters
- fprintf(inter_code,"tPOPtBPn");//pop bp
- fprintf(inter_code,"tPOPtDXn");
- fprintf(inter_code,"tPOPtCXn");
- fprintf(inter_code,"tPOPtBXn");
- fprintf(inter_code,"tPOPtAXn");
- fprintf(inter_code,"tRETn");
- }
- void stn(char *name)
- {
- if(pTable ->nestlevel == 0){
- fprintf(inter_code,"tPOPtBXn");//get the value from the top of the stack
- fprintf(inter_code,"tPOPtAXn");//get the actual address at STACK segment
- fprintf(inter_code,"tMOVtDS:[AX] , BXn");//load value
- fprintf(inter_code,"tPUSHtBXn");
- }
- else{
- fprintf(inter_code,"tPOPtBXn");//get the value from the top of the stack
- fprintf(inter_code,"tPOPtAXn");//get the actual address at STACK segment
- fprintf(inter_code,"tPUSHtBPn");
- fprintf(inter_code,"tMOVtBP , AXn");
- fprintf(inter_code,"tMOVtSS:[BP] , BXn");//load value
- fprintf(inter_code,"tPOPtBPn");
- fprintf(inter_code,"tPUSHtBXn");
- }
- }
- void subi(void)
- {
- fprintf(inter_code,"tPOPtDXn");
- fprintf(inter_code,"tPOPtCXn");
- fprintf(inter_code,"tSUBtCX , DXn");
- fprintf(inter_code,"tPUSHtCXn");
- }
- void ujp(char *label)
- {
- fprintf(inter_code,"tJMPt%sn",label);
- }
- void write(void)
- {
- fprintf(inter_code,"tWRITEtproctfarn");//to code file
- fprintf(inter_code,"tPUSHtAXn");
- fprintf(inter_code,"tPUSHtBXn");
- fprintf(inter_code,"tPUSHtCXn");
- fprintf(inter_code,"tPUSHtDXn");
- fprintf(inter_code,"tPUSHtBPn");
- fprintf(inter_code,"tMOVtBP , SPn");//begin to accept local variables
- fprintf(inter_code,"tMOVtBX , [BP + 14]n");
- fprintf(inter_code,"tMOVtCX , 10000n");
- fprintf(inter_code,"tCMPtBX , CXn");
- fprintf(inter_code,"tJLtw_label1n");
- fprintf(inter_code,"tCALLtWRITE_SUBn");
- fprintf(inter_code,"w_label1:n");
- fprintf(inter_code,"tMOVtCX , 1000n");
- fprintf(inter_code,"tCMPtBX , CXn");
- fprintf(inter_code,"tJLtw_label2n");
- fprintf(inter_code,"tCALLtWRITE_SUBn");
- fprintf(inter_code,"w_label2:n");
- fprintf(inter_code,"tMOVtCX , 100n");
- fprintf(inter_code,"tCMPtBX , CXn");
- fprintf(inter_code,"tJLtw_label3n");
- fprintf(inter_code,"tCALLtWRITE_SUBn");
- fprintf(inter_code,"w_label3:n");
- fprintf(inter_code,"tMOVtCX , 10n");
- fprintf(inter_code,"tCMPtBX , CXn");
- fprintf(inter_code,"tJLtw_label4n");
- fprintf(inter_code,"tCALLtWRITE_SUBn");
- fprintf(inter_code,"w_label4:n");
- fprintf(inter_code,"tMOVtCX , 1n");
- fprintf(inter_code,"tCALLtWRITE_SUBn");
- fprintf(inter_code,"tMOVtSP , BPn");//release local parameters
- fprintf(inter_code,"tPOPtBPn");//pop bp
- fprintf(inter_code,"tPOPtDXn");
- fprintf(inter_code,"tPOPtCXn");
- fprintf(inter_code,"tPOPtBXn");
- fprintf(inter_code,"tPOPtAXn");
- fprintf(inter_code,"tRETn");
- fprintf(inter_code,"tWRITEtendpnn");
- fprintf(inter_code,"tWRITE_SUBtproctnearn");
- fprintf(inter_code,"tMOVtAX , BXn");
- fprintf(inter_code,"tMOVtDX , 0n");
- fprintf(inter_code,"tDIVtCXn");
- fprintf(inter_code,"tMOVtBX , DXn");
- fprintf(inter_code,"tMOVtDL , ALn");
- fprintf(inter_code,"tADDtDL , '0'n");
- fprintf(inter_code,"tMOVtAH , 02hn");
- fprintf(inter_code,"tINTt21hn");
- fprintf(inter_code,"tRETn");
- fprintf(inter_code,"tWRITE_SUBtendpnn");
- }
- void CodeGen_TreeNode(TreeNode * node)
- {
- TreeNode * temp;
- int count;
- while (node != NULL)
- {
- switch(node ->nodekind){
- case Dec:
- switch(node-> kind.dec){
- case FunDecK:
- // more code to be filled
- break;
- case FunDefK:
- Fun = node;
- count = 0;
- temp = node-> child[0];
- while(temp)
- {
- count ++;
- temp = temp-> sibling;
- }
- ent(node ->attr.name, count, (node -> type != Void)? TRUE:FALSE);
- temp = node -> child[0]; // Param
- if(temp)
- CodeGen_TreeNode(temp);
- CodeGen_TreeNode(node ->child[1]); // comp_dec
- if(node -> type == Void)
- ret(FALSE,node ->attr.name);
- else
- ret(TRUE,node ->attr.name);
- leave(node ->attr.name);
- break;
- case VarK:
- temp = node -> child[0];
- if(node ->kind.exp == NumK)
- while(temp)
- {
- if(temp -> nodekind == Stmt) // AssignK ini
- VarDec_ini(temp ->child[0] ->attr.name, temp->child[1]->attr.val.i);
- else
- {
- if(temp ->child[0] == NULL)
- VarDec(temp ->attr.name);
- else
- ArrDec(temp ->attr.name, temp ->child[0] ->attr.val.i);
- }
- temp = temp ->sibling;
- }
- break;
- case CompK:
- pTable = node ->attr.table;
- temp = node ->child[0];
- if(temp) // Dec
- CodeGen_TreeNode(temp);
- temp = node ->child[1];
- if(temp) //stmt
- CodeGen_TreeNode(temp);
- compound_exit();
- break;
- case ParamK:
- break;
- default:
- break;
- }
- break;
- case Stmt:
- switch(node ->kind.stmt){
- case IfK:
- temp = node ->child[0];
- GenLabel(pTable ->lab1);
- GenLabel(pTable ->lab2);
- if(temp ->kind.exp == NumK) // optimize
- {
- if(temp -> attr.val.i == 0)
- ujp(pTable ->lab1);
- }
- else
- {
- CodeGen_TreeNode(temp);
- fjp(pTable ->lab1);
- }
- pTable = node ->child[1] ->attr.table;
- if(node ->child[1])
- CodeGen_TreeNode(node ->child[1]);
- if(node ->child[2])
- ujp(pTable ->lab2);
- lab(pTable ->lab1);
- if(node ->child[2])
- {
- pTable = node ->child[2] ->attr.table;
- CodeGen_TreeNode(node ->child[2]);
- lab(pTable ->lab2);
- }
- break;
- case WhileK:
- GenLabel(pTable ->lab1);
- GenLabel(pTable ->lab2);
- lab(pTable ->lab1);
- temp = node ->child[0];
- if(temp ->kind.exp == NumK) // optimize
- {
- if(temp ->attr.val.i == 0)
- ujp(pTable ->lab2);
- }
- else
- {
- CodeGen_TreeNode(temp);
- fjp(pTable ->lab2);
- }
- if(node -> child[1])
- CodeGen_TreeNode(node -> child[1]);
- ujp(pTable ->lab1);
- lab(pTable ->lab2);
- break;
- case CallK:
- mst(node -> attr.name);
- temp = node ->child[0];
- CodeGen_TreeNode(temp);
- cup(node ->attr.name, count);
- while(temp) // Param
- {
- pop();
- temp = temp -> sibling;
- }
- if(node ->call_stmt == 1)
- pop();
- break;
- case ReturnK:
- temp = node -> child[0];
- if(temp)
- {
- CodeGen_TreeNode(temp);
- ret(TRUE,pTable ->funEntry ->name);
- }
- else ret(FALSE,pTable ->funEntry ->name);
- break;
- case BreakK:
- ujp(pTable ->parent ->lab2);
- break;
- case ContinueK:
- ujp(pTable ->parent ->lab1);
- break;
- case AssignK:
- temp = node -> child[0];
- lda(temp ->attr.name);
- if(temp -> child[0]) //Arr
- {
- CodeGen_TreeNode(temp -> child[0]);
- ixa_elem_size();
- }
- CodeGen_TreeNode(node -> child[1]);
- stn(node -> child[0] ->attr.name);
- pop();
- break;
- default:
- break;
- }
- break;
- case Exp:
- switch(node -> kind.exp){
- case OpK:
- if(node -> child[0])
- CodeGen_TreeNode(node -> child[0]);
- if(node -> child[1])
- CodeGen_TreeNode(node -> child[1]);
- switch(node -> attr.op) {
- case PLUS: adi(); break;
- case SUB: subi(); break;
- case MUT: multi(); break;
- case DIV: divi(); break;
- case EQ: equi(); break;
- case NEQ: neqi(); break;
- case LE: lorei(); break;
- case GE: gorei(); break;
- case LT: less(); break;
- case GT: greater(); break;
- case AND: andi(); break;
- case OR: ori(); break;
- default: yyerror("Unknown Operator!");
- break;
- }
- break;
- case FnumK:
- // more code to be filled
- break;
- case NumK:
- ldc(node -> attr.val.i);
- break;
- case CharK:
- // ldc(node -> attr.val.i);
- break;
- case IdK:
- lod(node -> attr.name);
- break;
- case NotK:
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- node = node->sibling;
- }
- }