import java.io.File; import java.util.ArrayList; import java.util.Scanner; import java.util.StringTokenizer; public class VPL { static String fileName; static Scanner keys; static int max; static int[] mem; static int ip, bp, sp, rv, hp, numPassed, gp; static int step; public static void main(String[] args) throws Exception { keys = new Scanner( System.in ); if( args.length != 2 ) { System.out.println("Usage: java VPL " ); System.exit(1); } fileName = args[0]; max = Integer.parseInt( args[1] ); mem = new int[max]; // load the program into the front part of // memory Scanner input = new Scanner( new File( fileName ) ); String line; StringTokenizer st; int opcode; ArrayList labels, holes; labels = new ArrayList(); holes = new ArrayList(); int label; // load the code int k=0; while ( input.hasNextLine() ) { line = input.nextLine(); System.out.println("parsing line [" + line + "]"); if( line != null ) {// extract any tokens st = new StringTokenizer( line ); if( st.countTokens() > 0 ) {// have a token, so must be an instruction (as opposed to empty line) opcode = Integer.parseInt(st.nextToken()); // load the instruction into memory: if( opcode == labelCode ) {// note index that comes where label would go label = Integer.parseInt(st.nextToken()); labels.add( new IntPair( label, k ) ); } else if( opcode == noopCode ){ } else {// opcode actually gets stored mem[k] = opcode; k++; if( opcode == callCode || opcode == jumpCode || opcode == condJumpCode ) {// note the hole immediately after the opcode to be filled in later label = Integer.parseInt( st.nextToken() ); mem[k] = label; holes.add( new IntPair( k, label ) ); ++k; } // load correct number of arguments (following label, if any): for( int j=0; j to go on" ); keys.nextLine(); */ oldIp = ip; op = mem[ ip ]; ip++; // extract the args into a, b, c for convenience: a = -1; b = -2; c = -3; // numArgs is wrong for these guys, need one more! if( op == callCode || op == jumpCode || op == condJumpCode ) { actualNumArgs = numArgs( op ) + 1; } else actualNumArgs = numArgs( op ); if( actualNumArgs == 1 ) { a = mem[ ip ]; ip++; } else if( actualNumArgs == 2 ) { a = mem[ ip ]; ip++; b = mem[ ip ]; ip++; } else if( actualNumArgs == 3 ) { a = mem[ ip ]; ip++; b = mem[ ip ]; ip++; c = mem[ ip ]; ip++; } // implement all operations here: // ******************************************** // put your work right here! if ( op == oppCode ) { mem[ bp+2 + a ] = - mem[ bp+2 + b ]; } else { System.out.println("Fatal error: unknown opcode [" + op + "]" ); System.exit(1); } step++; }while( !done ); }// main // use symbolic names for all opcodes: // op to produce comment private static final int noopCode = 0; // ops involved with registers private static final int labelCode = 1; private static final int callCode = 2; private static final int passCode = 3; private static final int allocCode = 4; private static final int returnCode = 5; // return a means "return and put // copy of value stored in cell a in register rv private static final int getRetvalCode = 6;//op a means "copy rv into cell a" private static final int jumpCode = 7; private static final int condJumpCode = 8; // arithmetic ops private static final int addCode = 9; private static final int subCode = 10; private static final int multCode = 11; private static final int divCode = 12; private static final int remCode = 13; private static final int equalCode = 14; private static final int notEqualCode = 15; private static final int lessCode = 16; private static final int lessEqualCode = 17; private static final int andCode = 18; private static final int orCode = 19; private static final int notCode = 20; private static final int oppCode = 21; // ops involving transfer of data private static final int litCode = 22; // litCode a b means "cell a gets b" private static final int copyCode = 23;// copy a b means "cell a gets cell b" private static final int getCode = 24; // op a b means "cell a gets // contents of cell whose // index is stored in b" private static final int putCode = 25; // op a b means "put contents // of cell b in cell whose offset is stored in cell a" // system-level ops: private static final int haltCode = 26; private static final int inputCode = 27; private static final int outputCode = 28; private static final int newlineCode = 29; private static final int symbolCode = 30; private static final int newCode = 31; // global variable ops: private static final int allocGlobalCode = 32; private static final int toGlobalCode = 33; private static final int fromGlobalCode = 34; // debug ops: private static final int debugCode = 35; // return the number of arguments after the opcode, // except ops that have a label return number of arguments // after the label, which always comes immediately after // the opcode private static int numArgs( int opcode ) { // highlight specially behaving operations if( opcode == labelCode ) return 1; // not used else if( opcode == jumpCode ) return 0; // jump label else if( opcode == condJumpCode ) return 1; // condJump label expr else if( opcode == callCode ) return 0; // call label // for all other ops, lump by count: else if( opcode==noopCode || opcode==haltCode || opcode==newlineCode || opcode==debugCode ) return 0; // op else if( opcode==passCode || opcode==allocCode || opcode==returnCode || opcode==getRetvalCode || opcode==inputCode || opcode==outputCode || opcode==symbolCode || opcode==allocGlobalCode ) return 1; // op arg1 else if( opcode==notCode || opcode==oppCode || opcode==litCode || opcode==copyCode || opcode==newCode || opcode==toGlobalCode || opcode==fromGlobalCode ) return 2; // op arg1 arg2 else if( opcode==addCode || opcode==subCode || opcode==multCode || opcode==divCode || opcode==remCode || opcode==equalCode || opcode==notEqualCode || opcode==lessCode || opcode==lessEqualCode || opcode==andCode || opcode==orCode || opcode==getCode || opcode==putCode ) return 3; else { System.out.println("Fatal error: unknown opcode [" + opcode + "]" ); System.exit(1); return -1; } }// numArgs private static void showMem( int a, int b ) { for( int k=a; k<=b; ++k ) { System.out.println( k + ": " + mem[k] ); } }// showMem }// VPL