📄 cgen.c
字号:
if(level == 0){
//数组
if(tree->child[0]){
if(tree->type.type == Double){
emitRM(opADD,ac1,ac1,gp, "op: add ixa");
if(addrFlag){
emitRM(opLDA,ac,loc,ac1,"array assign: store double addr");
emitRM(opPUSH, ac, 0, 0, "array assign: push double addr");
} else {
emitRM(opLD,ac,loc,ac1,"array assign: store double value",sizeofdouble);
emitRM(opPUSH, ac, 0, 0, "array assign: push double value",sizeofdouble);
}
}else if(tree->type.type == Integer){
emitRM(opADD,ac1,ac1,gp, "op: add ixa");
if(addrFlag){
emitRM(opLDA,ac,loc,ac1,"array assign: store addr");
emitRM(opPUSH, ac, 0, 0, "array assign: push addr");
} else {
emitRM(opLD,ac,loc,ac1,"array assign: store value");
emitRM(opPUSH, ac, 0, 0, "array assign: push value");
}
}else if(tree->type.type == Char){
emitRM(opADD,ac1,ac1,gp, "op: add ixa");
if(addrFlag){
emitRM(opLDA,ac,loc,ac1,"array assign: store char addr");
emitRM(opPUSH, ac, 0, 0, "array assign: push char addr");
} else {
emitRM(opLD,ac,loc,ac1,"array assign: store char value",sizeofchar);
emitRM(opPUSH, ac, 0, 0, "array assign: push char value",sizeofchar);
}
}
}else if(tree->type.type == Double){
if(addrFlag){
emitRM(opLDA,ac,loc,gp,"load id double addr",sizeofint, flag);
emitRM(opPUSH, ac, 0, 0, "assign: push double addr");
} else {
emitRM(opLD,ac,loc,gp,"load id double value",sizeofdouble, flag);
emitRM(opPUSH, ac, 0, 0, "assign: push double value", sizeofdouble);
}
} else if(tree->type.type == Integer){
if(addrFlag){
emitRM(opLDA,ac,loc,gp,"load id addr");
emitRM(opPUSH, ac, 0, 0, "assign: push addr");
}else{
emitRM(opLD,ac,loc,gp,"load id value");
emitRM(opPUSH, ac, 0, 0, "assign: push value");
}
} else if(tree->type.type == Char || tree->type.type == String){
if(addrFlag){
emitRM(opLDA,ac,loc,gp,"load id addr");
emitRM(opPUSH, ac, 0, 0, "assign: push addr");
}else{
emitRM(opLD,ac,loc,gp,"load id char value", sizeofchar);
emitRM(opPUSH, ac, 0, 0, "assign: push char value", sizeofchar);
}
} else if(tree->type.type == Struct){
if(addrFlag){
emitRM(opLDA,ac,loc,gp,"load id struct addr");
emitRM(opPUSH, ac, 0, 0, "assign: push struct addr");
}
}
} else {
//数组
if(tree->child[0]){
emitRM(opLDA,bp,base[level-1],sp,"load base top");
if(tree->type.type == Double){
emitRM(opADD,ac1,ac1,bp, "op: add ixa");
if(addrFlag){
emitRM(opLDA,ac,loc,ac1,"array assign: store double add");
emitRM(opPUSH, ac, 0, 0, "array assign: push double addr");
} else {
emitRM(opLD,ac,loc,ac1,"array assign: store double value",sizeofdouble);
emitRM(opPUSH, ac, 0, 0, "array assign: push double value",sizeofdouble);
}
}else if(tree->type.type == Integer){
emitRM(opADD,ac1,ac1,bp, "op: add ixa");
if(addrFlag){
emitRM(opLDA,ac,loc,ac1,"array assign: store addr");
emitRM(opPUSH, ac, 0, 0, "array assign: push addr");
} else {
emitRM(opLD,ac,loc,ac1,"array assign: store value");
emitRM(opPUSH, ac, 0, 0, "array assign: push value");
}
}else if(tree->type.type == Char){
emitRM(opADD,ac1,ac1,bp, "op: add ixa");
if(addrFlag){
emitRM(opLDA,ac,loc,ac1,"array assign: store char addr");
emitRM(opPUSH, ac, 0, 0, "array assign: push char addr");
} else {
emitRM(opLD,ac,loc,ac1,"array assign: store char value",sizeofchar);
emitRM(opPUSH, ac, 0, 0, "array assign: push char value",sizeofchar);
}
}
}else if(tree->type.type == Double){
emitRM(opLDA,bp,base[level-1],sp,"load base top");
printf("flag:%d\n", flag);
if(addrFlag){
emitRM(opLDA,ac,loc,bp,"load id double addr",sizeofint, flag);
emitRM(opPUSH, ac, 0, 0, "assign: push double addr");
} else {
emitRM(opLD,ac,loc,bp,"load id double value",sizeofdouble, flag);
emitRM(opPUSH, ac, 0, 0, "assign: push double value",sizeofdouble);
}
} else if(tree->type.type == Integer){
emitRM(opLDA,bp,base[level-1],sp,"load base top");
if(addrFlag){
emitRM(opLDA,ac,loc,bp,"load id addr");
emitRM(opPUSH, ac, 0, 0, "assign: push addr");
} else {
emitRM(opLD,ac,loc,bp,"load id value");
emitRM(opPUSH, ac, 0, 0, "assign: push value");
}
} else if(tree->type.type == Char || tree->type.type == String){
emitRM(opLDA,bp,base[level-1],sp,"load base top");
if(addrFlag){
emitRM(opLDA,ac,loc,bp,"load id char addr");
emitRM(opPUSH, ac, 0, 0, "assign: push char addr");
} else {
emitRM(opLD,ac,loc,bp,"load id char value",sizeofchar);
emitRM(opPUSH, ac, 0, 0, "assign: push char value",sizeofchar);
}
} else if(tree->type.type == Struct){
emitRM(opLDA,bp,base[level-1],sp,"load base top");
if(addrFlag){
emitRM(opLDA,ac,loc,bp,"load id struct addr");
emitRM(opPUSH, ac, 0, 0, "assign: push struct addr");
}
}
}
if (TraceCode)
emitComment("<- Id") ;
break; /* IdK */
case OpK :
if (TraceCode)
emitComment("-> Op") ;
p1 = tree->child[0];
p2 = tree->child[1];
/* gen code for ac = left arg */
cGen(p1);
/* gen code for ac = right operand */
cGen(p2);
type = getType(p1);
type2 = getType(p2);
if(type == Double){
emitRM(opPOP,ac,0,0,"op: pop double right",sizeofdouble);
emitRM(opPOP,ac1,0,0,"op: pop double left",sizeofdouble);
}else if(type == Integer){
emitRM(opPOP,ac,0,0,"op: pop right");
emitRM(opPOP,ac1,0,0,"op: pop left");
}else if(type == Char){
emitRM(opPOP,ac,0,0,"op: pop right",sizeofchar);
emitRM(opPOP,ac1,0,0,"op: pop left",sizeofchar);
}
switch (tree->attr.op) {
case PLUS :
if((type == Double)||(type2 == Double))
emitRO(opADD,ac,ac1,ac,"op +",sizeofdouble);
else
emitRO(opADD,ac,ac1,ac,"op +");
break;
case SUB :
if((type == Double)||(type2 == Double))
emitRO(opSUB,ac,ac1,ac,"op -",sizeofdouble);
else
emitRO(opSUB,ac,ac1,ac,"op -");
break;
case MUT :
if((type == Double)||(type2 == Double))
emitRO(opMUL,ac,ac1,ac,"op *",sizeofdouble);
else
emitRO(opMUL,ac,ac1,ac,"op *");
break;
case DIV :
if((type == Double)||(type2 == Double))
emitRO(opDIV,ac,ac1,ac,"op /",sizeofdouble);
else
emitRO(opDIV,ac,ac1,ac,"op /");
break;
case LT :
if((type == Double)||(type2 == Double))
emitRO(opLT,ac,ac1,ac,"op <",sizeofdouble) ;
else if((type == Integer)||(type2 == Integer))
emitRO(opLT,ac,ac1,ac,"op <") ;
else if((type == Char)||(type2 == Char))
emitRO(opLT,ac,ac1,ac,"op <",sizeofchar) ;
break;
case LE :
if((type == Double)||(type2 == Double))
emitRO(opLE,ac,ac1,ac,"op <=",sizeofdouble) ;
else if((type == Integer)||(type2 == Integer))
emitRO(opLE,ac,ac1,ac,"op <=") ;
else if((type == Char)||(type2 == Char))
emitRO(opLE,ac,ac1,ac,"op <=",sizeofchar) ;
break;
case GT :
if((type == Double)||(type2 == Double))
emitRO(opGT,ac,ac1,ac,"op >",sizeofdouble) ;
else if((type == Integer)||(type2 == Integer))
emitRO(opGT,ac,ac1,ac,"op >") ;
else if((type == Char)||(type2 == Char))
emitRO(opGT,ac,ac1,ac,"op >",sizeofchar) ;
break;
case GE :
if((type == Double)||(type2 == Double))
emitRO(opGE,ac,ac1,ac,"op >=",sizeofdouble) ;
else if((type == Integer)||(type2 == Integer))
emitRO(opGE,ac,ac1,ac,"op >=") ;
else if((type == Char)||(type2 == Char))
emitRO(opGE,ac,ac1,ac,"op >=",sizeofchar) ;
break;
case EQ :
if((type == Double)||(type2 == Double))
emitRO(opEQ,ac,ac1,ac,"op ==",sizeofdouble) ;
else if((type == Integer)||(type2 == Integer))
emitRO(opEQ,ac,ac1,ac,"op ==") ;
else if((type == Char)||(type2 == Char))
emitRO(opEQ,ac,ac1,ac,"op ==",sizeofchar) ;
break;
case NEQ :
if((type == Double)||(type2 == Double))
emitRO(opNEQ,ac,ac1,ac,"op !=",sizeofdouble) ;
else if((type == Integer)||(type2 == Integer))
emitRO(opNEQ,ac,ac1,ac,"op !=") ;
else if((type == Char)||(type2 == Char))
emitRO(opNEQ,ac,ac1,ac,"op !=",sizeofchar) ;
break;
case AND :
emitRO(opAND,ac,ac1,ac,"op and") ;
break;
case OR :
emitRO(opOR,ac,ac1,ac,"op or") ;
break;
case NOT :
emitRO(opNOT,ac,0,ac,"op not") ;
break;
default:
emitComment("BUG: Unknown operator");
break;
} /* case op */
if((type == Double)&&(tree->attr.op == PLUS || tree->attr.op == SUB
|| tree->attr.op == MUT || tree->attr.op == DIV))
emitRM(opPUSH, ac, 0, 0, "op: push double result",sizeofdouble);
else
emitRM(opPUSH, ac, 0, 0, "op: push result");
if (TraceCode)
emitComment("<- Op") ;
break; /* OpK */
default:
break;
}
} /* genExp */
/* Procedure cGen recursively generates code by
* tree traversal
*/
static void cGen( TreeNode * tree, int addrFlag)
{
while(tree != NULL)
{
switch (tree->nodekind) {
case DecK:
genDec(tree, addrFlag);
break;
case StmtK:
genStmt(tree, addrFlag);
break;
case ExpK:
genExp(tree, addrFlag);
break;
default:
break;
}
tree = tree->sibling;
}
}
/**********************************************/
/* the primary function of the code generator */
/**********************************************/
/* Procedure codeGen generates code to a code
* file by traversal of the syntax tree. The
* second parameter (codefile) is the file name
* of the code file, and is used to print the
* file name as a comment in the code file
*/
void codeGen(TreeNode * syntaxTree, char * codefile)
{
int loc;
emitLoc = 0;
char *s = (char*)malloc(strlen(codefile)+7);
strcpy(s,"File: ");
strcat(s,codefile);
emitComment("TINY Compilation to TM Code");
emitComment(s);
/* generate standard prelude */
emitComment("Standard prelude:");
emitRM(opLD,gp,0,ac,"set location gp");
emitRM(opLDA,sp,0,gp,"copy gp to sp");
nGlobalTop = DADDR_SIZE - pTable->memloc;
printf("nGlobalTop: %d\n", nGlobalTop);
emitRM(opLDC,tp,nGlobalTop,0,"set tp");
emitRM(opST,ac,0,ac,"clear location ac");
emitRM(opST,mp,0,ac,"load maxaddress from location 0");
emitComment("End of standard prelude.");
/* generate code for TINY program */
cGen(syntaxTree);
/* finish */
emitComment("End of execution.");
emitRO(opHALT,0,0,0,"");
};
/********************************************/
static STEPRESULT stepTM ()
{
INSTRUCTION currentinstruction;
char c, c2;
int pcindex,r,s,t,m,ok,iNum,iNum2,n;
double dNum,dNum2;
pcindex = reg[PC_REG] ;
//printf("pcindex:%d\n", pcindex);
if ( (pcindex < 0) || (pcindex > IADDR_SIZE) )
return srIMEM_ERR ;
reg[PC_REG] = pcindex + 1 ;
currentinstruction = iMem[pcindex] ;
switch (opClass(currentinstruction.iop) )
{
case opclRR :
/***********************************/
r = currentinstruction.iarg1 ;
s = currentinstruction.iarg2 ;
t = currentinstruction.iarg3 ;
break;
case opclRM :
/***********************************/
r = currentinstruction.iarg1 ;
s = currentinstruction.iarg3 ;
m = currentinstruction.iarg2 + reg[s] ;
if ( (m < 0) || (m > DADDR_SIZE))
return srDMEM_ERR ;
break;
case opclRA :
/***********************************/
r = currentinstruction.iarg1 ;
s = currentinstruction.iarg3 ;
m = currentinstruction.iarg2 + reg[s] ;
break;
} /* case */
switch ( currentinstruction.iop)
{
/* RR instructions */
case opHALT :
/***********************************/
printf("HALT: %1d,%1d,%1d\n",r,s,t);
return srHALT ;
/* break; */
case opSYSCALL:
//read
if(s == ReadC){
getInput();
printf("in_Line: %s\n", in_Line);
if(currentinstruction.isize == sizeofdouble){
dNum = atof(in_Line);
memcpy((BYTE*)&dreg[ac1],&dNum,sizeofdouble);
printf("double read %f %f\n", dNum, reg[r]);
} else if(currentinstruction.isize == sizeofint){
iNum = atoi(in_Line);
memcpy((BYTE*)®[ac1],&iNum,sizeofint);
printf("integer read %d %d\n", iNum, reg[r]);
} else if(currentinstruction.isize == sizeofchar){
iNum = atoi(in_Line);
c = (char)iNum;
memcpy((BYTE*)®[ac1],&c,sizeofchar);
printf("char read %c %c\n", c, reg[r]);
}
}
//write
else if(s == WriteC){
if(currentinstruction.isize == sizeofdouble){
printf("double write: %f\n", dreg[r]);
}else if(currentinstruction.isize == sizeofint) {
memcpy(&iNum,(BYTE*)®[r],sizeofint);
printf("integer write: %d\n", iNum);
}else if(currentinstruction.isize == sizeofchar) {
memcpy(&c,(BYTE*)®[r],sizeofchar);
printf("char write: %c\n", c);
}else if(currentinstruction.isize == typestring) {
printf("string write: ");
m = reg[r];
memcpy(&c,(BYTE*)&dMem[m],sizeofchar);
while(c != '\0'){
printf("%c", c);
memcpy(&c,(BYTE*)&dMem[++m],sizeofchar);
}
printf("\n");
}
}
//abs
else if(s == AbsC){
iNum = reg[ac];
printf("before abs %d\n", iNum);
if(iNum <0){
iNum = - iNum;
memcpy((BYTE*)®[ac],&iNum,sizeofint);
}
printf("after abs %d\n", reg[ac]);
}
//floor
else if(s == FloorC){
printf("before FloorC %f\n", dreg[ac]);
memcpy((BYTE*)&dNum,&dreg[ac],sizeofdouble);
dNum = floor(dNum);
printf("after FloorC %f\n", dNum);
memcpy((BYTE*)&dreg[ac],&dNum,sizeofdouble);
}
//ceil
else if(s == CeilC){
printf("before CeilC %f\n", dreg[ac]);
memcpy((BYTE*)&dNum,&dreg[ac],sizeofdouble);
dNum = ceil(dNum);
printf("after CeilC %f\n", dNum);
memcpy((BYTE*)&dreg[ac],&dNum,sizeofdouble);
}
//fabs
else if(s == FAbsC){
memcpy((BYTE*)&dNum,&dreg[ac],sizeofdouble);
printf("before fabs %f\n", dNum);
if(dNum <0){
dNum = - dNum;
memcpy((BYTE*)&dreg[ac],&dNum,sizeofdouble);
}
printf("after fabs %f\n", dreg[ac]);
}
//fmod
else if(s == FModC){
memcpy((BYTE*)&dNum,&dreg[ac1],sizeofdouble);
memcpy((BYTE*)&dNum2,&dreg[ac],sizeofdouble);
printf("before fabs %f %f\n", dNum, dNum2);
dNum = fmod(dNum, dNum2);
memcpy((BYTE*)&dreg[ac],&dNum,sizeofdouble);
printf("after fabs %f\n", dreg[ac]);
}
//strcmp
else if(s == StrCmpC){
m = reg[ac];
n = reg[ac1];
for(;;){
memcpy(&c,(BYTE*)&dMem[m++],sizeofchar);
memcpy(&c2,(BYTE*)&dMem[n++],sizeofchar);
if(c != c2)
break;
}
if(c > c2)
iNum = 1;
else if(c == c2)
iNum = 0;
else
iNum = -1;
memcpy((BYTE*)®[ac],&iNum,sizeofint);
}
//strcat
else if(s == StrCatC){
}
//strcpy
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -