📄 interpreter.java
字号:
/* * @(#)Interpreter.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 TAM;import java.io.DataInputStream;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;public class Interpreter { static String objectName;// DATA STORE static int[] data = new int[1024];// DATA STORE REGISTERS AND OTHER REGISTERS final static int CB = 0, SB = 0, HB = 1024; // = upper bound of data array + 1 static int CT, CP, ST, HT, LB, status; // status values final static int running = 0, halted = 1, failedDataStoreFull = 2, failedInvalidCodeAddress = 3, failedInvalidInstruction = 4, failedOverflow = 5, failedZeroDivide = 6, failedIOError = 7; static long accumulator; static int content (int r) { // Returns the current content of register r, // even if r is one of the pseudo-registers L1..L6. switch (r) { case Machine.CBr: return CB; case Machine.CTr: return CT; case Machine.PBr: return Machine.PB; case Machine.PTr: return Machine.PT; case Machine.SBr: return SB; case Machine.STr: return ST; case Machine.HBr: return HB; case Machine.HTr: return HT; case Machine.LBr: return LB; case Machine.L1r: return data[LB]; case Machine.L2r: return data[data[LB]]; case Machine.L3r: return data[data[data[LB]]]; case Machine.L4r: return data[data[data[data[LB]]]]; case Machine.L5r: return data[data[data[data[data[LB]]]]]; case Machine.L6r: return data[data[data[data[data[data[LB]]]]]]; case Machine.CPr: return CP; default: return 0; } }// PROGRAM STATUS static void dump() { // Writes a summary of the machine state. int addr, staticLink, dynamicLink, localRegNum; System.out.println (""); System.out.println ("State of data store and registers:"); System.out.println (""); if (HT == HB) System.out.println(" |--------| (heap is empty)"); else { System.out.println(" HB-->"); System.out.println(" |--------|"); for (addr = HB - 1; addr >= HT; addr--) { System.out.print(addr + ":"); if (addr == HT) System.out.print(" HT-->"); else System.out.print(" "); System.out.println("|" + data[addr] + "|"); } System.out.println(" |--------|"); } System.out.println(" |////////|"); System.out.println(" |////////|"); if (ST == SB) System.out.println(" |--------| (stack is empty)"); else { dynamicLink = LB; staticLink = LB; localRegNum = Machine.LBr; System.out.println(" ST--> |////////|"); System.out.println(" |--------|"); for (addr = ST - 1; addr >= SB; addr--) { System.out.print(addr + ":"); if (addr == SB) System.out.print(" SB-->"); else if (addr == staticLink) { switch (localRegNum) { case Machine.LBr: System.out.print(" LB-->"); break; case Machine.L1r: System.out.print(" L1-->"); break; case Machine.L2r: System.out.print(" L2-->"); break; case Machine.L3r: System.out.print(" L3-->"); break; case Machine.L4r: System.out.print(" L4-->"); break; case Machine.L5r: System.out.print(" L5-->"); break; case Machine.L6r: System.out.print(" L6-->"); break; } staticLink = data[addr]; localRegNum = localRegNum + 1; } else System.out.print(" "); if ((addr == dynamicLink) && (dynamicLink != SB)) System.out.print("|SL=" + data[addr] + "|"); else if ((addr == dynamicLink + 1) && (dynamicLink != SB)) System.out.print("|DL=" + data[addr] + "|"); else if ((addr == dynamicLink + 2) && (dynamicLink != SB)) System.out.print("|RA=" + data[addr] + "|"); else System.out.print("|" + data[addr] + "|"); System.out.println (""); if (addr == dynamicLink) { System.out.println(" |--------|"); dynamicLink = data[addr + 1]; } } } System.out.println (""); } static void showStatus () { // Writes an indication of whether and why the program has terminated. System.out.println (""); switch (status) { case running: System.out.println("Program is running."); break; case halted: System.out.println("Program has halted normally."); break; case failedDataStoreFull: System.out.println("Program has failed due to exhaustion of Data Store."); break; case failedInvalidCodeAddress: System.out.println("Program has failed due to an invalid code address."); break; case failedInvalidInstruction: System.out.println("Program has failed due to an invalid instruction."); break; case failedOverflow: System.out.println("Program has failed due to overflow."); break; case failedZeroDivide: System.out.println("Program has failed due to division by zero."); break; case failedIOError: System.out.println("Program has failed due to an IO error."); break; } if (status != halted) dump(); }// INTERPRETATION static void checkSpace (int spaceNeeded) { // Signals failure if there is not enough space to expand the stack or // heap by spaceNeeded. if (HT - ST < spaceNeeded) status = failedDataStoreFull; } static boolean isTrue (int datum) { // Tests whether the given datum represents true. return (datum == Machine.trueRep); } static boolean equal (int size, int addr1, int addr2) { // Tests whether two multi-word objects are equal, given their common // size and their base addresses. boolean eq; int index; eq = true; index = 0; while (eq && (index < size)) if (data[addr1 + index] == data[addr2 + index]) index = index + 1; else eq = false; return eq; } static int overflowChecked (long datum) { // Signals failure if the datum is too large to fit into a single word, // otherwise returns the datum as a single word. if ((-Machine.maxintRep <= datum) && (datum <= Machine.maxintRep)) return (int) datum; else { status = failedOverflow; return 0; } } static int toInt(boolean b) { return b ? Machine.trueRep : Machine.falseRep; } static int currentChar; static int readInt() throws java.io.IOException { int temp = 0; int sign = 1; do { currentChar = System.in.read(); } while (Character.isWhitespace((char) currentChar)); if ((currentChar == '-') || (currentChar == '+')) do { sign = (currentChar == '-') ? -1 : 1; currentChar = System.in.read(); } while ((currentChar == '-') || currentChar == '+'); if (Character.isDigit((char) currentChar)) do { temp = temp * 10 + (currentChar - '0'); currentChar = System.in.read(); } while (Character.isDigit((char) currentChar)); return sign * temp; } static void callPrimitive (int primitiveDisplacement) { // Invokes the given primitive routine. int addr, size; char ch; switch (primitiveDisplacement) { case Machine.idDisplacement: break; // nothing to be done case Machine.notDisplacement: data[ST - 1] = toInt(!isTrue(data[ST - 1])); break; case Machine.andDisplacement: ST = ST - 1; data[ST - 1] = toInt(isTrue(data[ST - 1]) & isTrue(data[ST])); break; case Machine.orDisplacement: ST = ST - 1; data[ST - 1] = toInt(isTrue(data[ST - 1]) | isTrue(data[ST])); break; case Machine.succDisplacement: data[ST - 1] = overflowChecked(data[ST - 1] + 1); break; case Machine.predDisplacement: data[ST - 1] = overflowChecked(data[ST - 1] - 1); break; case Machine.negDisplacement: data[ST - 1] = -data[ST - 1]; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -