📄 cgen.c
字号:
#include "globals.h"
#include "cgen.h"
typedef enum{
ADD,SUB,MULT,DIV,EQC,READC,WRITEC,RETURNC,ASSIG,LABEL,JUMP,JUMP0,JUMPN0}CodeKind;
typedef struct AddressRec{char* name;int dataoff;}*address;
typedef struct ARGrecordRec{
enum{ValueForm,LabelForm,AddrForm,TddrForm} form;
union{
int value;
int label;
address addr;}atr;
} *ARGrecord;
static int tempcn=0;
static int label=0;
ARGrecord GenVar(TreeNode *tree)
{ ARGrecord L;
L=(ARGrecord)malloc(sizeof(struct ARGrecordRec));
L->form=AddrForm;
L->atr.addr=(address)malloc(sizeof(struct AddressRec));
L->atr.addr->name=tree->attr.name;
L->atr.addr->dataoff=st_lookup(tree->attr.name);
return L;
}//为变量声称arg结构。
ARGrecord NewTemp()
{ ARGrecord L;
L=(ARGrecord)malloc(sizeof(ARGrecord));
L->form=TddrForm;
L->atr.addr=(address)malloc(sizeof(struct AddressRec));
L->atr.addr->dataoff=tempcn;
tempcn++;
return L;
}//临时变量
ARGrecord ARGvalue(int value)
{ ARGrecord L;
L=(ARGrecord)malloc(sizeof(struct ARGrecordRec));
L->form=ValueForm;
L->atr.value=value;
return L;
}//为值定义arg结构
ARGrecord ARGlabel()
{ ARGrecord L;
L=(ARGrecord)malloc(sizeof(struct ARGrecordRec));
L->form=LabelForm;
L->atr.label=label;
label++;
return L;
}
ARGrecord genexp(TreeNode *tree)
{
TreeNode *p1,*p2;
char *str="";
ARGrecord Larg=(ARGrecord)malloc(sizeof(struct ARGrecordRec)),
rarg=(ARGrecord)malloc(sizeof(struct ARGrecordRec)),
arg=(ARGrecord)malloc(sizeof(struct ARGrecordRec)),
temp=(ARGrecord)malloc(sizeof(struct ARGrecordRec));
TokenType op;
switch(tree->kind.exp){
case ConstK:
Larg=ARGvalue(tree->attr.val);
return Larg;
break;
case IdK:
Larg=GenVar(tree);
return Larg;
break;
case OpK:
p1=tree->child[0];
p2=tree->child[1];
Larg=genexp(p1);
rarg=genexp(p2);
op=tree->attr.op;
switch(op)
{case EQ:str="=";break;
case LT:str="<";break;
case MINUS: str="-";break;
case PLUS: str="+";break;
case TIMES:str="*";break;
case OVER: str="/";break;
default: break;
}
temp=NewTemp();
//根据3*3,选择9种情况进行返回。
if(Larg->form==ValueForm&&rarg->form==ValueForm)
fprintf(code,"%s %d %d %s%d\n",str,Larg->atr.value ,rarg->atr.value,
"T",temp->atr.addr->dataoff);
if(Larg->form==ValueForm&&rarg->form==AddrForm)
fprintf(code,"%s %d %s %s%d\n",str,Larg->atr.value ,rarg->atr.addr->name,
"T",temp->atr.addr->dataoff);
if(Larg->form==AddrForm&&rarg->form==ValueForm)
fprintf(code,"%s %s %d %s%d\n",str,Larg->atr.addr->name ,rarg->atr.value,
"T",temp->atr.addr->dataoff);
if(Larg->form==AddrForm&&rarg->form==AddrForm)
fprintf(code,"%s %s %s %s%d\n",str,Larg->atr.addr->name ,rarg->atr.addr->name,
"T",temp->atr.addr->dataoff);
if(Larg->form==AddrForm&&rarg->form==TddrForm)
fprintf(code,"%s %s %s%d %s%d\n",str,Larg->atr.addr->name ,"T",rarg->atr.addr->dataoff,
"T",temp->atr.addr->dataoff);
if(Larg->form==ValueForm&&rarg->form==TddrForm)
fprintf(code,"%s %d %s%d %s%d\n",str,Larg->atr.value ,"T",rarg->atr.addr->dataoff,
"T",temp->atr.addr->dataoff);
if(Larg->form==TddrForm&&rarg->form==AddrForm)
fprintf(code,"%s %s%d %s %s%d\n",str,"T",Larg->atr.addr->dataoff ,rarg->atr.addr->name,
"T",temp->atr.addr->dataoff);
if(Larg->form==TddrForm&&rarg->form==ValueForm)
fprintf(code,"%s %s%d %d %s%d\n",str,"T",Larg->atr.addr->dataoff ,rarg->atr.value,
"T",temp->atr.addr->dataoff);
if(Larg->form==TddrForm&&rarg->form==TddrForm)
fprintf(code,"%s %s%d %s%d %s%d\n",str,"T",Larg->atr.addr->dataoff,"T",rarg->atr.addr->dataoff,
"T",temp->atr.addr->dataoff);
arg=temp;
return arg;
break;
default:
return NULL;
}
}
static void genstmt(TreeNode *tree)
{
TreeNode *p1,*p2,*p3;
ARGrecord ElseLarg=(ARGrecord)malloc(sizeof(struct ARGrecordRec)),
OutLarg=(ARGrecord)malloc(sizeof(struct ARGrecordRec)),
Earg=(ARGrecord)malloc(sizeof(struct ARGrecordRec)),
startlarg=(ARGrecord)malloc(sizeof(struct ARGrecordRec)),
Larg=(ARGrecord)malloc(sizeof(struct ARGrecordRec)),
Rarg=(ARGrecord)malloc(sizeof(struct ARGrecordRec));
switch(tree->kind.stmt){
case IfK:
p1=tree->child[0];
p2=tree->child[1];
p3=tree->child[2];
ElseLarg=ARGlabel();
OutLarg=ARGlabel();
Earg=genexp(p1);
if(Earg->form==ValueForm)
fprintf(code,"%s %d %s%d\n","JUMP0",Earg->atr.value,"L",ElseLarg->atr.label);
if(Earg->form==AddrForm)
fprintf(code,"%s %s %s%d\n","JUMP0",Earg->atr.addr->name ,"L",ElseLarg->atr.label);
if(Earg->form==TddrForm)
fprintf(code,"%s %s%d %s%d\n","JUMP0","T",Earg->atr.addr->dataoff, "L",ElseLarg->atr.label);
GenMidCode(p2,code);
fprintf(code,"%s %s%d\n","JUMP","L",OutLarg->atr.label);
fprintf(code,"%s%d:\n","L",ElseLarg->atr.label);
GenMidCode(p3,code);
fprintf(code,"%s%d:\n","L",OutLarg->atr.label);
break;
case RepeatK:
p1=tree->child[0];
p2=tree->child[1];
startlarg=ARGlabel();
fprintf(code,"%s%d:","L",startlarg->atr.label);
GenMidCode(p1,code);
Earg=genexp(p2);
if(Earg->form==ValueForm)
fprintf(code,"%s %d %s%d\n","JUMPN0",Earg->atr.value,"L",startlarg->atr.label);
if(Earg->form==AddrForm)
fprintf(code,"%s %s %s%d\n","JUMPN0",Earg->atr.addr->name,"L",startlarg->atr.label);
if(Earg->form==TddrForm)
fprintf(code,"%s %s%d %s%d\n","JUMPN0","T",Earg->atr.addr->dataoff,"L",startlarg->atr.label);
break;
case AssignK:
Larg->atr.addr=(address)malloc(sizeof(struct AddressRec));
Larg->atr.addr->name=tree->attr.name;
Rarg=genexp(tree->child[0]);
if(Rarg->form==ValueForm)
fprintf(code,"%s %s %d\n","ASSIG",Larg->atr.addr->name,Rarg->atr.value);
if(Rarg->form==AddrForm)
fprintf(code,"%s %s %s\n","ASSIG",Larg->atr.addr->name,Rarg->atr.addr->name );
if(Rarg->form==TddrForm)
fprintf(code,"%s %s %s%d\n","ASSIG",Larg->atr.addr->name,"T",Rarg->atr.addr->dataoff);
break;
case ReadK:
Larg->atr.addr=(address)malloc(sizeof(struct AddressRec));
Larg->atr.addr->name=tree->attr.name;
fprintf(code,"%s %s \n","READC",Larg->atr.addr->name);
break;
case WriteK:
Larg=genexp(tree->child[0]);
if(Larg->form==ValueForm)
fprintf(code,"%s %d \n","WRITEC",Larg->atr.value);
if(Larg->form==AddrForm)
fprintf(code,"%s %s \n","WRITEC",Larg->atr.addr->name );
if(Larg->form==TddrForm)
fprintf(code,"%s %s%d\n","WRITEC","T",Larg->atr.addr->dataoff);
break;
default:
break;
}
}
void GenMidCode( TreeNode *tree,FILE* codefile)
{if(tree!=NULL)
{switch(tree->nodekind) {
case StmtK:
genstmt(tree);
break;
case ExpK:
genexp(tree);
break;
default:
break;
}
GenMidCode(tree->sibling,code);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -