/************************************************************************** * MiniPro2: Interpreter for version 2 of a miniature programming language. * * COS 126, Princeton University, Fall 2013, Programming Midterm 2 Part 1 * * Notes: functionally different from MiniPro in step() and isDone(); * has private helper method evaluate(), not part of API. * * Dependencies: ST, StdOut * * Compilation: javac-introcs MiniPro.java **************************************************************************/ public class MiniPro2 { private int pc; // the program counter private String[][] program; // the program itself private ST varTable; // values of all defined variables // Create interpreter for this program. Don't execute it yet! public MiniPro2(String[][] program) { this.program = program; pc = 0; // line 0 is always the first to execute varTable = new ST(); } // Return the current value of the variable named v. If no // such variable is currently defined, throw a RuntimeException. public int valueOf(String v) { if (!varTable.contains(v)) throw new RuntimeException("Variable named " + v + " not defined"); return varTable.get(v); } // Return the number of the line that will execute next. public int programCounter() { return pc; } // Check if this token is an integer or variable, and give the value // of it in either case. private int evaluate(String token) { // look at token, evaluate it if (token.matches("[a-z]+")) // it's a variable name return varTable.get(token); else // it's an integer return Integer.parseInt(token); } // Execute the line whose number equals the value of the // program counter. Then, increment the program counter. public void step() { String[] line = program[pc]; // current line (1d piece of 2d array) String command = line[1]; // assignment statement if (command.equals("=")) { // look at token on right-hand side, evaluate it String rhsToken = line[2]; int rhsValue = evaluate(rhsToken); // save value in variable varTable.put(line[0], rhsValue); } // println statement else if (command.equals("println")) { // get value of desired variable, then print it int value = varTable.get(line[0]); StdOut.println(value); } // mathematical operations else if (command.equals("+=")) { // which variable are we updating? int oldValue = varTable.get(line[0]); // what should its new value be? int newValue = oldValue + evaluate(line[2]); // update varTable.put(line[0], newValue); } else if (command.equals("-=")) { // which variable are we updating? int oldValue = varTable.get(line[0]); // what should its new value be? int newValue = oldValue - evaluate(line[2]); // update varTable.put(line[0], newValue); } else if (command.equals("*=")) { // which variable are we updating? int oldValue = varTable.get(line[0]); // what should its new value be? int newValue = oldValue * evaluate(line[2]); // update varTable.put(line[0], newValue); } // jump if positive statement else if (command.equals("pos?jump")) { // value of variable we are testing int testValue = evaluate(line[0]); if (testValue > 0) { // positive? pc += evaluate(line[2]); // jump! // return right now so that we don't hit the pc++ line below return; } // else, take no special action } // increment the program counter pc++; } // Is the program done? // For MiniPro2, we have to check not only being at the end, // but also after the end or before the start. public boolean isDone() { return pc >= program.length || pc < 0; } }