📄 cgen.h
字号:
class Cgen:public Code,public SymTab
{
private:
static int tmpOffset;
void cGen (TreeNode * tree);
void genStmt( TreeNode * tree);
void genExp( TreeNode * tree);
public:
Cgen(char *codefile):Code(codefile)
{
}
void codeGen(TreeNode * syntaxTree, char * codefile);
};
int Cgen::tmpOffset = 0;
void Cgen:: genStmt( TreeNode * tree)
{
TreeNode * p1, * p2, * p3;
int savedLoc1,savedLoc2,currentLoc;
int loc;
switch (tree->kind.stmt)
{
case IfK :
emitComment("-> if") ;
p1 = tree->child[0] ;
p2 = tree->child[1] ;
p3 = tree->child[2] ;
cGen(p1);
savedLoc1 = emitSkip(1) ;
emitComment("if: jump to else belongs here");
cGen(p2);
savedLoc2 = emitSkip(1) ;
emitComment("if: jump to end belongs here");
currentLoc = emitSkip(0) ;
emitBackup(savedLoc1) ;
emitRM_Abs("JEQ",ac,currentLoc,"if: jmp to else");
emitRestore() ;
cGen(p3);
currentLoc = emitSkip(0) ;
emitBackup(savedLoc2) ;
emitRM_Abs("LDA",pc,currentLoc,"jmp to end") ;
emitRestore() ;
emitComment("<- if") ;
break;
case RepeatK:
emitComment("-> repeat") ;
p1 = tree->child[0] ;
p2 = tree->child[1] ;
savedLoc1 = emitSkip(0);
emitComment("repeat: jump after body comes back here");
cGen(p1);
cGen(p2);
emitRM_Abs("JEQ",ac,savedLoc1,"repeat: jmp back to body");
emitComment("<- repeat") ;
break;
case AssignK:
emitComment("-> assign") ;
cGen(tree->child[0]);
loc = Find(tree->attr.name);
emitRM("ST",ac,loc,gp,"assign: store value");
emitComment("<- assign") ;
break;
case ReadK:
emitRO("IN",ac,0,0,"read integer value");
loc = Find(tree->attr.name);
emitRM("ST",ac,loc,gp,"read: store value");
break;
case WriteK:
cGen(tree->child[0]);
emitRO("OUT",ac,0,0,"write ac");
break;
default:
break;
}
}
void Cgen:: genExp( TreeNode * tree)
{
int loc;
TreeNode * p1, * p2;
switch (tree->kind.exp)
{
case ConstK :
emitComment("-> Const") ;
emitRM("LDC",ac,tree->attr.val,0,"load const");
emitComment("<- Const") ;
break;
case IdK :
emitComment("-> Id") ;
loc = Find(tree->attr.name);
emitRM("LD",ac,loc,gp,"load id value");
emitComment("<- Id") ;
break;
case OpK :
emitComment("-> Op") ;
p1 = tree->child[0];
p2 = tree->child[1];
cGen(p1);
emitRM("ST",ac,tmpOffset--,mp,"op: push left");
cGen(p2);
emitRM("LD",ac1,++tmpOffset,mp,"op: load left");
switch (tree->attr.op) {
case PLUS :
emitRO("ADD",ac,ac1,ac,"op +");
break;
case MINUS :
emitRO("SUB",ac,ac1,ac,"op -");
break;
case TIMES :
emitRO("MUL",ac,ac1,ac,"op *");
break;
case OVER :
emitRO("DIV",ac,ac1,ac,"op /");
break;
case LT :
emitRO("SUB",ac,ac1,ac,"op <") ;
emitRM("JLT",ac,2,pc,"br if true") ;
emitRM("LDC",ac,0,ac,"false case") ;
emitRM("LDA",pc,1,pc,"unconditional jmp") ;
emitRM("LDC",ac,1,ac,"true case") ;
break;
case EQ :
emitRO("SUB",ac,ac1,ac,"op ==") ;
emitRM("JEQ",ac,2,pc,"br if true");
emitRM("LDC",ac,0,ac,"false case") ;
emitRM("LDA",pc,1,pc,"unconditional jmp") ;
emitRM("LDC",ac,1,ac,"true case") ;
break;
default:
emitComment("BUG: Unknown operator");
break;
}
emitComment("<- Op") ;
break;
default:
break;
}
}
void Cgen::cGen( TreeNode * tree)
{ if (tree != NULL)
{ switch (tree->nodekind) {
case StmtK:
genStmt(tree);
break;
case ExpK:
genExp(tree);
break;
default:
break;
}
cGen(tree->sibling);
}
}
void Cgen::codeGen(TreeNode * syntaxTree, char * codefile)
{
char * s = new char[strlen(codefile)+7];
strcpy(s,"File: ");
strcat(s,codefile);
emitComment("TINY Compilation to TM Code");
emitComment(s);
emitComment("Standard prelude:");
emitRM("LD",mp,0,ac,"load maxaddress from location 0");
emitRM("ST",ac,0,ac,"clear location 0");
emitComment("End of standard prelude.");
cGen(syntaxTree);
emitComment("End of execution.");
emitRO("HALT",0,0,0,"");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -