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

📄 encoder.java

📁 The triangle language processor will be consist of a compiler, an interpreter, and a disassembler
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
  // Value-or-variable names  public Object visitDotVname(DotVname ast, Object o) {    Frame frame = (Frame) o;    RuntimeEntity baseObject = (RuntimeEntity) ast.V.visit(this, frame);    ast.offset = ast.V.offset + ((Field) ast.I.decl.entity).fieldOffset;                   // I.decl points to the appropriate record field    ast.indexed = ast.V.indexed;    return baseObject;  }  public Object visitSimpleVname(SimpleVname ast, Object o) {    ast.offset = 0;    ast.indexed = false;    return ast.I.decl.entity;  }  public Object visitSubscriptVname(SubscriptVname ast, Object o) {    Frame frame = (Frame) o;    RuntimeEntity baseObject;    int elemSize, indexSize;    baseObject = (RuntimeEntity) ast.V.visit(this, frame);    ast.offset = ast.V.offset;    ast.indexed = ast.V.indexed;    elemSize = ((Integer) ast.type.visit(this, null)).intValue();    if (ast.E instanceof IntegerExpression) {      IntegerLiteral IL = ((IntegerExpression) ast.E).IL;      ast.offset = ast.offset + Integer.parseInt(IL.spelling) * elemSize;    } else {      // v-name is indexed by a proper expression, not a literal      if (ast.indexed)        frame.size = frame.size + Machine.integerSize;      indexSize = ((Integer) ast.E.visit(this, frame)).intValue();      if (elemSize != 1) {        emit(Machine.LOADLop, 0, 0, elemSize);        emit(Machine.CALLop, Machine.SBr, Machine.PBr,             Machine.multDisplacement);      }      if (ast.indexed)        emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement);      else        ast.indexed = true;    }    return baseObject;  }  // Programs  public Object visitProgram(Program ast, Object o) {    return ast.C.visit(this, o);  }  public Encoder (ErrorReporter reporter) {    this.reporter = reporter;    nextInstrAddr = Machine.CB;    elaborateStdEnvironment();  }  private ErrorReporter reporter;  // Generates code to run a program.  // showingTable is true iff entity description details  // are to be displayed.  public final void encodeRun (Program theAST, boolean showingTable) {    tableDetailsReqd = showingTable;    //startCodeGeneration();    theAST.visit(this, new Frame (0, 0));    emit(Machine.HALTop, 0, 0, 0);  }  // Decides run-time representation of a standard constant.  private final void elaborateStdConst (Declaration constDeclaration,					int value) {    if (constDeclaration instanceof ConstDeclaration) {      ConstDeclaration decl = (ConstDeclaration) constDeclaration;      int typeSize = ((Integer) decl.E.type.visit(this, null)).intValue();      decl.entity = new KnownValue(typeSize, value);      writeTableDetails(constDeclaration);    }  }  // Decides run-time representation of a standard routine.  private final void elaborateStdPrimRoutine (Declaration routineDeclaration,                                          int routineOffset) {    routineDeclaration.entity = new PrimitiveRoutine (Machine.closureSize, routineOffset);    writeTableDetails(routineDeclaration);  }  private final void elaborateStdEqRoutine (Declaration routineDeclaration,                                          int routineOffset) {    routineDeclaration.entity = new EqualityRoutine (Machine.closureSize, routineOffset);    writeTableDetails(routineDeclaration);  }  private final void elaborateStdRoutine (Declaration routineDeclaration,                                          int routineOffset) {    routineDeclaration.entity = new KnownRoutine (Machine.closureSize, 0, routineOffset);    writeTableDetails(routineDeclaration);  }  private final void elaborateStdEnvironment() {    tableDetailsReqd = false;    elaborateStdConst(StdEnvironment.falseDecl, Machine.falseRep);    elaborateStdConst(StdEnvironment.trueDecl, Machine.trueRep);    elaborateStdPrimRoutine(StdEnvironment.notDecl, Machine.notDisplacement);    elaborateStdPrimRoutine(StdEnvironment.andDecl, Machine.andDisplacement);    elaborateStdPrimRoutine(StdEnvironment.orDecl, Machine.orDisplacement);    elaborateStdConst(StdEnvironment.maxintDecl, Machine.maxintRep);    elaborateStdPrimRoutine(StdEnvironment.addDecl, Machine.addDisplacement);    elaborateStdPrimRoutine(StdEnvironment.subtractDecl, Machine.subDisplacement);    elaborateStdPrimRoutine(StdEnvironment.multiplyDecl, Machine.multDisplacement);    elaborateStdPrimRoutine(StdEnvironment.divideDecl, Machine.divDisplacement);    elaborateStdPrimRoutine(StdEnvironment.moduloDecl, Machine.modDisplacement);    elaborateStdPrimRoutine(StdEnvironment.lessDecl, Machine.ltDisplacement);    elaborateStdPrimRoutine(StdEnvironment.notgreaterDecl, Machine.leDisplacement);    elaborateStdPrimRoutine(StdEnvironment.greaterDecl, Machine.gtDisplacement);    elaborateStdPrimRoutine(StdEnvironment.notlessDecl, Machine.geDisplacement);    elaborateStdPrimRoutine(StdEnvironment.chrDecl, Machine.idDisplacement);    elaborateStdPrimRoutine(StdEnvironment.ordDecl, Machine.idDisplacement);    elaborateStdPrimRoutine(StdEnvironment.eolDecl, Machine.eolDisplacement);    elaborateStdPrimRoutine(StdEnvironment.eofDecl, Machine.eofDisplacement);    elaborateStdPrimRoutine(StdEnvironment.getDecl, Machine.getDisplacement);    elaborateStdPrimRoutine(StdEnvironment.putDecl, Machine.putDisplacement);    elaborateStdPrimRoutine(StdEnvironment.getintDecl, Machine.getintDisplacement);    elaborateStdPrimRoutine(StdEnvironment.putintDecl, Machine.putintDisplacement);    elaborateStdPrimRoutine(StdEnvironment.geteolDecl, Machine.geteolDisplacement);    elaborateStdPrimRoutine(StdEnvironment.puteolDecl, Machine.puteolDisplacement);    elaborateStdEqRoutine(StdEnvironment.equalDecl, Machine.eqDisplacement);    elaborateStdEqRoutine(StdEnvironment.unequalDecl, Machine.neDisplacement);  }  // Saves the object program in the named file.  public void saveObjectProgram(String objectName) {    FileOutputStream objectFile = null;    DataOutputStream objectStream = null;    int addr;    try {      objectFile = new FileOutputStream (objectName);      objectStream = new DataOutputStream (objectFile);      addr = Machine.CB;      for (addr = Machine.CB; addr < nextInstrAddr; addr++)        Machine.code[addr].write(objectStream);      objectFile.close();    } catch (FileNotFoundException s) {      System.err.println ("Error opening object file: " + s);    } catch (IOException s) {      System.err.println ("Error writing object file: " + s);    }  }  boolean tableDetailsReqd;  public static void writeTableDetails(AST ast) {  }  // OBJECT CODE  // Implementation notes:  // Object code is generated directly into the TAM Code Store, starting at CB.  // The address of the next instruction is held in nextInstrAddr.  private int nextInstrAddr;  // Appends an instruction, with the given fields, to the object code.  private void emit (int op, int n, int r, int d) {    Instruction nextInstr = new Instruction();    if (n > 255) {        reporter.reportRestriction("length of operand can't exceed 255 words");        n = 255; // to allow code generation to continue    }    nextInstr.op = op;    nextInstr.n = n;    nextInstr.r = r;    nextInstr.d = d;    if (nextInstrAddr == Machine.PB)      reporter.reportRestriction("too many instructions for code segment");    else {        Machine.code[nextInstrAddr] = nextInstr;        nextInstrAddr = nextInstrAddr + 1;    }  }  // Patches the d-field of the instruction at address addr.  private void patch (int addr, int d) {    Machine.code[addr].d = d;  }  // DATA REPRESENTATION  public int characterValuation (String spelling) {  // Returns the machine representation of the given character literal.    return spelling.charAt(1);      // since the character literal is of the form 'x'}  }  // REGISTERS  // Returns the register number appropriate for object code at currentLevel  // to address a data object at objectLevel.  private int displayRegister (int currentLevel, int objectLevel) {    if (objectLevel == 0)      return Machine.SBr;    else if (currentLevel - objectLevel <= 6)      return Machine.LBr + currentLevel - objectLevel; // LBr|L1r|...|L6r    else {      reporter.reportRestriction("can't access data more than 6 levels out");      return Machine.L6r;  // to allow code generation to continue    }  }  // Generates code to fetch the value of a named constant or variable  // and push it on to the stack.  // currentLevel is the routine level where the vname occurs.  // frameSize is the anticipated size of the local stack frame when  // the constant or variable is fetched at run-time.  // valSize is the size of the constant or variable's value.  private void encodeStore(Vname V, Frame frame, int valSize) {    RuntimeEntity baseObject = (RuntimeEntity) V.visit(this, frame);    // If indexed = true, code will have been generated to load an index value.    if (valSize > 255) {      reporter.reportRestriction("can't store values larger than 255 words");      valSize = 255; // to allow code generation to continue    }    if (baseObject instanceof KnownAddress) {      ObjectAddress address = ((KnownAddress) baseObject).address;      if (V.indexed) {        emit(Machine.LOADAop, 0, displayRegister(frame.level, address.level),             address.displacement + V.offset);        emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement);        emit(Machine.STOREIop, valSize, 0, 0);      } else {        emit(Machine.STOREop, valSize, displayRegister(frame.level,	     address.level), address.displacement + V.offset);      }    } else if (baseObject instanceof UnknownAddress) {      ObjectAddress address = ((UnknownAddress) baseObject).address;      emit(Machine.LOADop, Machine.addressSize, displayRegister(frame.level,           address.level), address.displacement);      if (V.indexed)        emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement);      if (V.offset != 0) {        emit(Machine.LOADLop, 0, 0, V.offset);        emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement);      }      emit(Machine.STOREIop, valSize, 0, 0);    }  }  // Generates code to fetch the value of a named constant or variable  // and push it on to the stack.  // currentLevel is the routine level where the vname occurs.  // frameSize is the anticipated size of the local stack frame when  // the constant or variable is fetched at run-time.  // valSize is the size of the constant or variable's value.  private void encodeFetch(Vname V, Frame frame, int valSize) {    RuntimeEntity baseObject = (RuntimeEntity) V.visit(this, frame);    // If indexed = true, code will have been generated to load an index value.    if (valSize > 255) {      reporter.reportRestriction("can't load values larger than 255 words");      valSize = 255; // to allow code generation to continue    }    if (baseObject instanceof KnownValue) {      // presumably offset = 0 and indexed = false      int value = ((KnownValue) baseObject).value;      emit(Machine.LOADLop, 0, 0, value);    } else if ((baseObject instanceof UnknownValue) ||               (baseObject instanceof KnownAddress)) {      ObjectAddress address = (baseObject instanceof UnknownValue) ?                              ((UnknownValue) baseObject).address :                              ((KnownAddress) baseObject).address;      if (V.indexed) {        emit(Machine.LOADAop, 0, displayRegister(frame.level, address.level),             address.displacement + V.offset);        emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement);        emit(Machine.LOADIop, valSize, 0, 0);      } else        emit(Machine.LOADop, valSize, displayRegister(frame.level,	     address.level), address.displacement + V.offset);    } else if (baseObject instanceof UnknownAddress) {      ObjectAddress address = ((UnknownAddress) baseObject).address;      emit(Machine.LOADop, Machine.addressSize, displayRegister(frame.level,           address.level), address.displacement);      if (V.indexed)        emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement);      if (V.offset != 0) {        emit(Machine.LOADLop, 0, 0, V.offset);        emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement);      }      emit(Machine.LOADIop, valSize, 0, 0);    }  }  // Generates code to compute and push the address of a named variable.  // vname is the program phrase that names this variable.  // currentLevel is the routine level where the vname occurs.  // frameSize is the anticipated size of the local stack frame when  // the variable is addressed at run-time.  private void encodeFetchAddress (Vname V, Frame frame) {    RuntimeEntity baseObject = (RuntimeEntity) V.visit(this, frame);    // If indexed = true, code will have been generated to load an index value.    if (baseObject instanceof KnownAddress) {      ObjectAddress address = ((KnownAddress) baseObject).address;      emit(Machine.LOADAop, 0, displayRegister(frame.level, address.level),           address.displacement + V.offset);      if (V.indexed)        emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement);    } else if (baseObject instanceof UnknownAddress) {      ObjectAddress address = ((UnknownAddress) baseObject).address;      emit(Machine.LOADop, Machine.addressSize,displayRegister(frame.level,           address.level), address.displacement);      if (V.indexed)        emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement);      if (V.offset != 0) {        emit(Machine.LOADLop, 0, 0, V.offset);        emit(Machine.CALLop, Machine.SBr, Machine.PBr, Machine.addDisplacement);      }    }  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -