⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gen.java

📁 java语言开发的基于tiny语言的编译器
💻 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 + -