📄 gen.java
字号:
package jeex.tiny;
import jeex.tiny.Tree.*;
import java.util.Vector;
/**
* A class for code generation.
*/
class Gen extends Tree.Visitor {
Code C;
Gen(Code code) {
this.C = code;
}
/**
* Main entry of generation.
* @param tree - root of the abstract syntax tree
*/
void main(Tree tree) {
tree.visit(this);
C.emitRO("HALT",Code.AC,Code.AC,Code.AC,"halt");
}
void _case(StmtSeq tree) {
Vector v = tree.statements;
for(int i = 0; i < v.size(); i++) {
Tree tree1 = (Tree)v.get(i);
tree1.visit(this);
}
}
void _case(IfStmt tree) {
C.emitComment("-> if");
tree.condition.visit(this);
Code.EmitLoc savedLoc1 = C.emitSkip(1);
tree.thenPart.visit(this);
if (tree.elsePart != null) {
C.emitComment("else ->");
Code.EmitLoc savedLoc2 = C.emitSkip(1);
int loc = C.currentEmitLoc();
C.emitBackup(savedLoc1);
C.emitRMAbs("JEQ",Code.AC,loc,"if: jump to else");
C.emitRestore();
tree.elsePart.visit(this);
loc = C.currentEmitLoc();
C.emitBackup(savedLoc2);
C.emitRMAbs("LDA",Code.PC,loc,"if: jump to end with else");
C.emitRestore();
C.emitComment("<- else");
} else {
int loc = C.currentEmitLoc();
C.emitBackup(savedLoc1);
C.emitRMAbs("JEQ",Code.AC,loc,"if: jump to end no else");
C.emitRestore();
}
C.emitComment("<- if");
}
void _case(RepeatStmt tree) {
C.emitComment("repeat ->");
int loc = C.currentEmitLoc();
tree.stmtSeq.visit(this);
tree.condition.visit(this);
C.emitRMAbs("JEQ",Code.AC,loc,"repeat: jump back to body");
C.emitComment("<- repeat");
}
void _case(AssignStmt tree) {
C.emitComment("assign ->");
Symbol s = null;
if (!Symbol.isDefined(((Ident)tree.ident).name))
s = Symbol.enter(((Ident)tree.ident).name);
else
s = Symbol.get(((Ident)tree.ident).name);
tree.expr.visit(this);
C.emitRM("ST",Code.AC,s.address,Code.GP,"assign: store value");
C.emitComment("<- assign");
}
void _case(ReadStmt tree) {
C.emitComment("read ->");
Symbol s = null;
if (!Symbol.isDefined(((Ident)tree.ident).name))
s = Symbol.enter(((Ident)tree.ident).name);
else
s = Symbol.get(((Ident)tree.ident).name);
C.emitRO("IN",Code.AC,0,0,"read integer value");
C.emitRM("ST",Code.AC,s.address,Code.GP,"read: store value");
C.emitComment("<- read");
}
void _case(WriteStmt tree) {
C.emitComment("write ->");
tree.expr.visit(this);
C.emitRO("OUT",Code.AC,0,0,"write ac");
C.emitComment("<- write");
}
void _case(Expr tree) {
C.emitComment("boolean expr->");
tree.first.visit(this);
C.emitRM("ST",Code.AC,tmpOffset--,Code.MP,"op: push left");
tree.second.visit(this);
C.emitRM("LD",Code.AC1,++tmpOffset,Code.MP,"op: load left");
switch(tree.op) {
case Tokens.EQ :
C.emitRO("SUB",Code.AC,Code.AC1,Code.AC,"op =") ;
C.emitRM("JEQ",Code.AC,2,Code.PC,"if true,go true case");
C.emitRM("LDC",Code.AC,0,Code.AC,"false case: false = 0") ;
C.emitRM("LDA",Code.PC,1,Code.PC,"unconditional jmp") ;
C.emitRM("LDC",Code.AC,1,Code.AC,"true case: true = 1") ;
break;
case Tokens.LT:
C.emitRO("SUB",Code.AC,Code.AC1,Code.AC,"op <") ;
C.emitRM("JLT",Code.AC,2,Code.PC,"if true,go true case");
C.emitRM("LDC",Code.AC,0,Code.AC,"false case: false = 0") ;
C.emitRM("LDA",Code.PC,1,Code.PC,"unconditional jmp") ;
C.emitRM("LDC",Code.AC,1,Code.AC,"true case: true = 1") ;
break;
default:
throw new RuntimeException("unknown operator");
}
C.emitComment("<- boolean expr");
}
void _case(ParExpr tree) {
tree.expr.visit(this);
}
void _case(Operation tree) {
C.emitComment("operator " + TokenUtil.tokenToString(tree.op) + " ->");
tree.left.visit(this);
C.emitRM("ST",Code.AC,tmpOffset--,Code.MP,"op: push left");
tree.right.visit(this);
C.emitRM("LD",Code.AC1,++tmpOffset,Code.MP,"op: load left");
switch(tree.op) {
case Tokens.PLUS :
C.emitRO("ADD",Code.AC,Code.AC1,Code.AC,"op: +");
break;
case Tokens.MINUS:
C.emitRO("SUB",Code.AC,Code.AC1,Code.AC,"op: -");
break;
case Tokens.MUL:
C.emitRO("MUL",Code.AC,Code.AC1,Code.AC,"op: *");
break;
case Tokens.DIV:
C.emitRO("DIV",Code.AC,Code.AC1,Code.AC,"op: /");
break;
default:
throw new RuntimeException("unknown operator");
}
C.emitComment("<- operator " + TokenUtil.tokenToString(tree.op));
}
void _case(Ident tree) {
C.emitComment("id ->");
if(!Symbol.isDefined(tree.name)) {
Log.error(tree.name + " not defined");
} else {
Symbol s = Symbol.get(tree.name);
C.emitRM("LD",Code.AC,s.address,Code.GP,"load id value");
}
C.emitComment("<- id");
}
void _case(Literal tree) {
C.emitComment("const ->");
C.emitRM("LDC",Code.AC,tree.value,0,"load const");
C.emitComment("<- const");
}
private int tmpOffset = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -