📄 codegen.c
字号:
fprintf(inter_code,"\tCMP\tAX , BX\n");
fprintf(inter_code,"\tJNE\tLabel%d\n",label_num);
fprintf(inter_code,"\tMOV\tAX , 0\n");
fprintf(inter_code,"\tPUSH\tAX\n");
fprintf(inter_code,"\tJMP\tLabel%d\n",label_num+1);
fprintf(inter_code,"Label%d:",label_num);
fprintf(inter_code,"\tMOV\tAX , 1\n");
fprintf(inter_code,"\tPUSH\tAX\n");
fprintf(inter_code,"Label%d:",label_num+1);
label_num += 2;
}
void ori(void)
{
fprintf(inter_code,"\tPOP\tBX\n");
fprintf(inter_code,"\tPOP\tAX\n");
fprintf(inter_code,"\tOR\tAX , BX\n");
fprintf(inter_code,"\tPUSH\tAX\n");
}
void pop(void)
{
fprintf(inter_code,"\tPOP\tAX\n");
}
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,"\tPOP\tAX\n");//get the return value from the top of the stack
pEntry = Lookup_Fun(name);
addr = pEntry ->ret_val;
fprintf(inter_code,"\tPUSH\tBP\n");
fprintf(inter_code,"\tADD\tBP , %d\n",addr);
fprintf(inter_code,"\tMOV\tSS:[BP] , AX\n");
fprintf(inter_code,"\tPOP\tBP\n");
}
fprintf(inter_code,"\tMOV\tSP , BP\n");//release local parameters
fprintf(inter_code,"\tPOP\tBP\n");//pop bp
fprintf(inter_code,"\tPOP\tDX\n");
fprintf(inter_code,"\tPOP\tCX\n");
fprintf(inter_code,"\tPOP\tBX\n");
fprintf(inter_code,"\tPOP\tAX\n");
fprintf(inter_code,"\tRET\n");
}
void stn(char *name)
{
if(pTable ->nestlevel == 0){
fprintf(inter_code,"\tPOP\tBX\n");//get the value from the top of the stack
fprintf(inter_code,"\tPOP\tAX\n");//get the actual address at STACK segment
fprintf(inter_code,"\tMOV\tDS:[AX] , BX\n");//load value
fprintf(inter_code,"\tPUSH\tBX\n");
}
else{
fprintf(inter_code,"\tPOP\tBX\n");//get the value from the top of the stack
fprintf(inter_code,"\tPOP\tAX\n");//get the actual address at STACK segment
fprintf(inter_code,"\tPUSH\tBP\n");
fprintf(inter_code,"\tMOV\tBP , AX\n");
fprintf(inter_code,"\tMOV\tSS:[BP] , BX\n");//load value
fprintf(inter_code,"\tPOP\tBP\n");
fprintf(inter_code,"\tPUSH\tBX\n");
}
}
void subi(void)
{
fprintf(inter_code,"\tPOP\tDX\n");
fprintf(inter_code,"\tPOP\tCX\n");
fprintf(inter_code,"\tSUB\tCX , DX\n");
fprintf(inter_code,"\tPUSH\tCX\n");
}
void ujp(char *label)
{
fprintf(inter_code,"\tJMP\t%s\n",label);
}
void write(void)
{
fprintf(inter_code,"\tWRITE\tproc\tfar\n");//to code file
fprintf(inter_code,"\tPUSH\tAX\n");
fprintf(inter_code,"\tPUSH\tBX\n");
fprintf(inter_code,"\tPUSH\tCX\n");
fprintf(inter_code,"\tPUSH\tDX\n");
fprintf(inter_code,"\tPUSH\tBP\n");
fprintf(inter_code,"\tMOV\tBP , SP\n");//begin to accept local variables
fprintf(inter_code,"\tMOV\tBX , [BP + 14]\n");
fprintf(inter_code,"\tMOV\tCX , 10000\n");
fprintf(inter_code,"\tCMP\tBX , CX\n");
fprintf(inter_code,"\tJL\tw_label1\n");
fprintf(inter_code,"\tCALL\tWRITE_SUB\n");
fprintf(inter_code,"w_label1:\n");
fprintf(inter_code,"\tMOV\tCX , 1000\n");
fprintf(inter_code,"\tCMP\tBX , CX\n");
fprintf(inter_code,"\tJL\tw_label2\n");
fprintf(inter_code,"\tCALL\tWRITE_SUB\n");
fprintf(inter_code,"w_label2:\n");
fprintf(inter_code,"\tMOV\tCX , 100\n");
fprintf(inter_code,"\tCMP\tBX , CX\n");
fprintf(inter_code,"\tJL\tw_label3\n");
fprintf(inter_code,"\tCALL\tWRITE_SUB\n");
fprintf(inter_code,"w_label3:\n");
fprintf(inter_code,"\tMOV\tCX , 10\n");
fprintf(inter_code,"\tCMP\tBX , CX\n");
fprintf(inter_code,"\tJL\tw_label4\n");
fprintf(inter_code,"\tCALL\tWRITE_SUB\n");
fprintf(inter_code,"w_label4:\n");
fprintf(inter_code,"\tMOV\tCX , 1\n");
fprintf(inter_code,"\tCALL\tWRITE_SUB\n");
fprintf(inter_code,"\tMOV\tSP , BP\n");//release local parameters
fprintf(inter_code,"\tPOP\tBP\n");//pop bp
fprintf(inter_code,"\tPOP\tDX\n");
fprintf(inter_code,"\tPOP\tCX\n");
fprintf(inter_code,"\tPOP\tBX\n");
fprintf(inter_code,"\tPOP\tAX\n");
fprintf(inter_code,"\tRET\n");
fprintf(inter_code,"\tWRITE\tendp\n\n");
fprintf(inter_code,"\tWRITE_SUB\tproc\tnear\n");
fprintf(inter_code,"\tMOV\tAX , BX\n");
fprintf(inter_code,"\tMOV\tDX , 0\n");
fprintf(inter_code,"\tDIV\tCX\n");
fprintf(inter_code,"\tMOV\tBX , DX\n");
fprintf(inter_code,"\tMOV\tDL , AL\n");
fprintf(inter_code,"\tADD\tDL , '0'\n");
fprintf(inter_code,"\tMOV\tAH , 02h\n");
fprintf(inter_code,"\tINT\t21h\n");
fprintf(inter_code,"\tRET\n");
fprintf(inter_code,"\tWRITE_SUB\tendp\n\n");
}
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;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -