📄 encoder.java
字号:
/* * @(#)Encoder.java 2.1 2003/10/07 * * Copyright (C) 1999, 2003 D.A. Watt and D.F. Brown * Dept. of Computing Science, University of Glasgow, Glasgow G12 8QQ Scotland * and School of Computer and Math Sciences, The Robert Gordon University, * St. Andrew Street, Aberdeen AB25 1HG, Scotland. * All rights reserved. * * This software is provided free for educational use only. It may * not be used for commercial purposes without the prior written permission * of the authors. */package Triangle.CodeGenerator;import java.io.DataOutputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import TAM.Instruction;import TAM.Machine;import Triangle.ErrorReporter;import Triangle.StdEnvironment;import Triangle.AbstractSyntaxTrees.AST;import Triangle.AbstractSyntaxTrees.AnyTypeDenoter;import Triangle.AbstractSyntaxTrees.ArrayExpression;import Triangle.AbstractSyntaxTrees.ArrayTypeDenoter;import Triangle.AbstractSyntaxTrees.AssignCommand;import Triangle.AbstractSyntaxTrees.BinaryExpression;import Triangle.AbstractSyntaxTrees.BinaryOperatorDeclaration;import Triangle.AbstractSyntaxTrees.BoolTypeDenoter;import Triangle.AbstractSyntaxTrees.CallCommand;import Triangle.AbstractSyntaxTrees.CallExpression;import Triangle.AbstractSyntaxTrees.CharTypeDenoter;import Triangle.AbstractSyntaxTrees.CharacterExpression;import Triangle.AbstractSyntaxTrees.CharacterLiteral;import Triangle.AbstractSyntaxTrees.ConstActualParameter;import Triangle.AbstractSyntaxTrees.ConstDeclaration;import Triangle.AbstractSyntaxTrees.ConstFormalParameter;import Triangle.AbstractSyntaxTrees.Declaration;import Triangle.AbstractSyntaxTrees.DotVname;import Triangle.AbstractSyntaxTrees.EmptyActualParameterSequence;import Triangle.AbstractSyntaxTrees.EmptyCommand;import Triangle.AbstractSyntaxTrees.EmptyExpression;import Triangle.AbstractSyntaxTrees.EmptyFormalParameterSequence;import Triangle.AbstractSyntaxTrees.ErrorTypeDenoter;import Triangle.AbstractSyntaxTrees.FuncActualParameter;import Triangle.AbstractSyntaxTrees.FuncDeclaration;import Triangle.AbstractSyntaxTrees.FuncFormalParameter;import Triangle.AbstractSyntaxTrees.Identifier;import Triangle.AbstractSyntaxTrees.IfCommand;import Triangle.AbstractSyntaxTrees.IfExpression;import Triangle.AbstractSyntaxTrees.IntTypeDenoter;import Triangle.AbstractSyntaxTrees.IntegerExpression;import Triangle.AbstractSyntaxTrees.IntegerLiteral;import Triangle.AbstractSyntaxTrees.LetCommand;import Triangle.AbstractSyntaxTrees.LetExpression;import Triangle.AbstractSyntaxTrees.MultipleActualParameterSequence;import Triangle.AbstractSyntaxTrees.MultipleArrayAggregate;import Triangle.AbstractSyntaxTrees.MultipleFieldTypeDenoter;import Triangle.AbstractSyntaxTrees.MultipleFormalParameterSequence;import Triangle.AbstractSyntaxTrees.MultipleRecordAggregate;import Triangle.AbstractSyntaxTrees.Operator;import Triangle.AbstractSyntaxTrees.ProcActualParameter;import Triangle.AbstractSyntaxTrees.ProcDeclaration;import Triangle.AbstractSyntaxTrees.ProcFormalParameter;import Triangle.AbstractSyntaxTrees.Program;import Triangle.AbstractSyntaxTrees.RecordExpression;import Triangle.AbstractSyntaxTrees.RecordTypeDenoter;import Triangle.AbstractSyntaxTrees.SequentialCommand;import Triangle.AbstractSyntaxTrees.SequentialDeclaration;import Triangle.AbstractSyntaxTrees.SimpleTypeDenoter;import Triangle.AbstractSyntaxTrees.SimpleVname;import Triangle.AbstractSyntaxTrees.SingleActualParameterSequence;import Triangle.AbstractSyntaxTrees.SingleArrayAggregate;import Triangle.AbstractSyntaxTrees.SingleFieldTypeDenoter;import Triangle.AbstractSyntaxTrees.SingleFormalParameterSequence;import Triangle.AbstractSyntaxTrees.SingleRecordAggregate;import Triangle.AbstractSyntaxTrees.SubscriptVname;import Triangle.AbstractSyntaxTrees.TypeDeclaration;import Triangle.AbstractSyntaxTrees.UnaryExpression;import Triangle.AbstractSyntaxTrees.UnaryOperatorDeclaration;import Triangle.AbstractSyntaxTrees.VarActualParameter;import Triangle.AbstractSyntaxTrees.VarDeclaration;import Triangle.AbstractSyntaxTrees.VarFormalParameter;import Triangle.AbstractSyntaxTrees.Visitor;import Triangle.AbstractSyntaxTrees.Vname;import Triangle.AbstractSyntaxTrees.VnameExpression;import Triangle.AbstractSyntaxTrees.WhileCommand;public final class Encoder implements Visitor { // Commands public Object visitAssignCommand(AssignCommand ast, Object o) { Frame frame = (Frame) o; Integer valSize = (Integer) ast.E.visit(this, frame); encodeStore(ast.V, new Frame (frame, valSize.intValue()), valSize.intValue()); return null; } public Object visitCallCommand(CallCommand ast, Object o) { Frame frame = (Frame) o; Integer argsSize = (Integer) ast.APS.visit(this, frame); ast.I.visit(this, new Frame(frame.level, argsSize)); return null; } public Object visitEmptyCommand(EmptyCommand ast, Object o) { return null; } public Object visitIfCommand(IfCommand ast, Object o) { Frame frame = (Frame) o; int jumpifAddr, jumpAddr; Integer valSize = (Integer) ast.E.visit(this, frame); jumpifAddr = nextInstrAddr; emit(Machine.JUMPIFop, Machine.falseRep, Machine.CBr, 0); ast.C1.visit(this, frame); jumpAddr = nextInstrAddr; emit(Machine.JUMPop, 0, Machine.CBr, 0); patch(jumpifAddr, nextInstrAddr); ast.C2.visit(this, frame); patch(jumpAddr, nextInstrAddr); return null; } public Object visitLetCommand(LetCommand ast, Object o) { Frame frame = (Frame) o; int extraSize = ((Integer) ast.D.visit(this, frame)).intValue(); ast.C.visit(this, new Frame(frame, extraSize)); if (extraSize > 0) emit(Machine.POPop, 0, 0, extraSize); return null; } public Object visitSequentialCommand(SequentialCommand ast, Object o) { ast.C1.visit(this, o); ast.C2.visit(this, o); return null; } public Object visitWhileCommand(WhileCommand ast, Object o) { Frame frame = (Frame) o; int jumpAddr, loopAddr; jumpAddr = nextInstrAddr; emit(Machine.JUMPop, 0, Machine.CBr, 0); loopAddr = nextInstrAddr; ast.C.visit(this, frame); patch(jumpAddr, nextInstrAddr); ast.E.visit(this, frame); emit(Machine.JUMPIFop, Machine.trueRep, Machine.CBr, loopAddr); return null; } // Expressions public Object visitArrayExpression(ArrayExpression ast, Object o) { ast.type.visit(this, null); return ast.AA.visit(this, o); } public Object visitBinaryExpression(BinaryExpression ast, Object o) { Frame frame = (Frame) o; Integer valSize = (Integer) ast.type.visit(this, null); int valSize1 = ((Integer) ast.E1.visit(this, frame)).intValue(); Frame frame1 = new Frame(frame, valSize1); int valSize2 = ((Integer) ast.E2.visit(this, frame1)).intValue(); Frame frame2 = new Frame(frame.level, valSize1 + valSize2); ast.O.visit(this, frame2); return valSize; } public Object visitCallExpression(CallExpression ast, Object o) { Frame frame = (Frame) o; Integer valSize = (Integer) ast.type.visit(this, null); Integer argsSize = (Integer) ast.APS.visit(this, frame); ast.I.visit(this, new Frame(frame.level, argsSize)); return valSize; } public Object visitCharacterExpression(CharacterExpression ast, Object o) { Frame frame = (Frame) o; Integer valSize = (Integer) ast.type.visit(this, null); emit(Machine.LOADLop, 0, 0, ast.CL.spelling.charAt(1)); return valSize; } public Object visitEmptyExpression(EmptyExpression ast, Object o) { return new Integer(0); } public Object visitIfExpression(IfExpression ast, Object o) { Frame frame = (Frame) o; Integer valSize; int jumpifAddr, jumpAddr; ast.type.visit(this, null); ast.E1.visit(this, frame); jumpifAddr = nextInstrAddr; emit(Machine.JUMPIFop, Machine.falseRep, Machine.CBr, 0); valSize = (Integer) ast.E2.visit(this, frame); jumpAddr = nextInstrAddr; emit(Machine.JUMPop, 0, Machine.CBr, 0); patch(jumpifAddr, nextInstrAddr); valSize = (Integer) ast.E3.visit(this, frame); patch(jumpAddr, nextInstrAddr); return valSize; } public Object visitIntegerExpression(IntegerExpression ast, Object o) { Frame frame = (Frame) o; Integer valSize = (Integer) ast.type.visit(this, null); emit(Machine.LOADLop, 0, 0, Integer.parseInt(ast.IL.spelling)); return valSize; } public Object visitLetExpression(LetExpression ast, Object o) { Frame frame = (Frame) o; ast.type.visit(this, null); int extraSize = ((Integer) ast.D.visit(this, frame)).intValue(); Frame frame1 = new Frame(frame, extraSize); Integer valSize = (Integer) ast.E.visit(this, frame1); if (extraSize > 0) emit(Machine.POPop, valSize.intValue(), 0, extraSize); return valSize; } public Object visitRecordExpression(RecordExpression ast, Object o){ ast.type.visit(this, null); return ast.RA.visit(this, o); } public Object visitUnaryExpression(UnaryExpression ast, Object o) { Frame frame = (Frame) o; Integer valSize = (Integer) ast.type.visit(this, null); ast.E.visit(this, frame); ast.O.visit(this, new Frame(frame.level, valSize.intValue())); return valSize; } public Object visitVnameExpression(VnameExpression ast, Object o) { Frame frame = (Frame) o; Integer valSize = (Integer) ast.type.visit(this, null); encodeFetch(ast.V, frame, valSize.intValue()); return valSize; } // Declarations public Object visitBinaryOperatorDeclaration(BinaryOperatorDeclaration ast, Object o){ return new Integer(0); } public Object visitConstDeclaration(ConstDeclaration ast, Object o) { Frame frame = (Frame) o; int extraSize = 0; if (ast.E instanceof CharacterExpression) { CharacterLiteral CL = ((CharacterExpression) ast.E).CL; ast.entity = new KnownValue(Machine.characterSize, characterValuation(CL.spelling)); } else if (ast.E instanceof IntegerExpression) { IntegerLiteral IL = ((IntegerExpression) ast.E).IL; ast.entity = new KnownValue(Machine.integerSize, Integer.parseInt(IL.spelling)); } else { int valSize = ((Integer) ast.E.visit(this, frame)).intValue(); ast.entity = new UnknownValue(valSize, frame.level, frame.size); extraSize = valSize; } writeTableDetails(ast); return new Integer(extraSize); } public Object visitFuncDeclaration(FuncDeclaration ast, Object o) { Frame frame = (Frame) o; int jumpAddr = nextInstrAddr; int argsSize = 0, valSize = 0; emit(Machine.JUMPop, 0, Machine.CBr, 0); ast.entity = new KnownRoutine(Machine.closureSize, frame.level, nextInstrAddr); writeTableDetails(ast); if (frame.level == Machine.maxRoutineLevel) reporter.reportRestriction("can't nest routines more than 7 deep"); else { Frame frame1 = new Frame(frame.level + 1, 0); argsSize = ((Integer) ast.FPS.visit(this, frame1)).intValue(); Frame frame2 = new Frame(frame.level + 1, Machine.linkDataSize); valSize = ((Integer) ast.E.visit(this, frame2)).intValue(); } emit(Machine.RETURNop, valSize, 0, argsSize); patch(jumpAddr, nextInstrAddr); return new Integer(0); } public Object visitProcDeclaration(ProcDeclaration ast, Object o) { Frame frame = (Frame) o; int jumpAddr = nextInstrAddr; int argsSize = 0; emit(Machine.JUMPop, 0, Machine.CBr, 0); ast.entity = new KnownRoutine (Machine.closureSize, frame.level, nextInstrAddr); writeTableDetails(ast); if (frame.level == Machine.maxRoutineLevel) reporter.reportRestriction("can't nest routines so deeply"); else { Frame frame1 = new Frame(frame.level + 1, 0); argsSize = ((Integer) ast.FPS.visit(this, frame1)).intValue(); Frame frame2 = new Frame(frame.level + 1, Machine.linkDataSize); ast.C.visit(this, frame2); } emit(Machine.RETURNop, 0, 0, argsSize); patch(jumpAddr, nextInstrAddr); return new Integer(0); } public Object visitSequentialDeclaration(SequentialDeclaration ast, Object o) { Frame frame = (Frame) o; int extraSize1, extraSize2; extraSize1 = ((Integer) ast.D1.visit(this, frame)).intValue(); Frame frame1 = new Frame (frame, extraSize1); extraSize2 = ((Integer) ast.D2.visit(this, frame1)).intValue(); return new Integer(extraSize1 + extraSize2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -