001package algs35; 002import stdlib.*; 003/* *********************************************************************** 004 * Compilation: javac Interpreter.java 005 * Execution: java Interpreter 006 * Dependencies: In.java ST.java 007 * 008 * Parses simple arithmetic expressions of the form z = x and 009 * z = x + y, where x and y can be symbolic variables or real 010 * numbers. Uses a symbol table to store the mapping between 011 * variable names and their values. 012 * 013 * 014 * % java Interpreter 015 * >> x := 34 016 * x = 34.0 017 * 018 * >> y := 23 * x 019 * y := 782.0 020 * 021 * >> z := x ^ y 022 * z := Infinity 023 * 024 * >> z := y ^ 2 025 * z := 611524.0 026 * 027 * >> x 028 * x := 34.0 029 * 030 * >> x := sqrt 2 031 * x := 1.4142135623730951 032 * 033 * >> <Ctrl-d> 034 * 035 * Remarks 036 * ------- 037 * 038 * - Currently allows values on the LHS, e.g., 17 = x + y, 039 * and treats "17" as a variable name. 040 * 041 * 042 *************************************************************************/ 043 044public class XInterpreter { 045 046 public static void main(String[] args) { 047 048 ST<String, Double> st = new ST<>(); 049 050 // read in one line at a time and parse 051 String line; 052 StdOut.print(">> "); 053 while ((line = StdIn.readLine()) != null) { 054 String[] tokens = line.split("\\s"); 055 056 // singe variable - just print out its value 057 if (tokens.length == 1) { 058 String zvar = tokens[0]; 059 StdOut.println(zvar + " := " + st.get(zvar)); 060 } 061 062 // z = x 063 else if (tokens.length == 3) { 064 String zvar = tokens[0]; 065 String eq = tokens[1]; 066 String xvar = tokens[2]; 067 if (!eq.equals(":=")) throw new Error("Illegal assignment"); 068 Double x = st.get(xvar); 069 if (x == null) x = Double.parseDouble(xvar); 070 st.put(zvar, x); 071 StdOut.println(zvar + " := " + st.get(zvar)); 072 } 073 074 // z = function x 075 else if (tokens.length == 4) { 076 String zvar = tokens[0]; 077 String eq = tokens[1]; 078 String func = tokens[2]; 079 String xvar = tokens[3]; 080 if (!eq.equals(":=")) throw new Error("Illegal assignment"); 081 Double x = st.get(xvar); 082 if (x == null) x = Double.parseDouble(xvar); 083 if (func.equals("sin")) st.put(zvar, Math.sin(x)); 084 else if (func.equals("cos")) st.put(zvar, Math.cos(x)); 085 else if (func.equals("sqrt")) st.put(zvar, Math.sqrt(x)); 086 else if (func.equals("-")) st.put(zvar, -x); 087 else throw new Error("Illegal function"); 088 StdOut.println(zvar + " := " + st.get(zvar)); 089 } 090 091 // z = x + y 092 else if (tokens.length == 5) { 093 String zvar = tokens[0]; 094 String eq = tokens[1]; 095 String xvar = tokens[2]; 096 String op = tokens[3]; 097 String yvar = tokens[4]; 098 if (!eq.equals(":=")) throw new Error("Illegal assignment"); 099 Double x = st.get(xvar); 100 Double y = st.get(yvar); 101 if (x == null) x = Double.parseDouble(xvar); 102 if (y == null) y = Double.parseDouble(yvar); 103 if (op.equals("+")) st.put(zvar, x + y); 104 else if (op.equals("-")) st.put(zvar, x - y); 105 else if (op.equals("*")) st.put(zvar, x * y); 106 else if (op.equals("/")) st.put(zvar, x / y); 107 else if (op.equals("^")) st.put(zvar, Math.pow(x, y)); 108 else throw new Error("Illegal operator"); 109 StdOut.println(zvar + " = " + st.get(zvar)); 110 } 111 112 else throw new Error("Illegal expression"); 113 StdOut.println(); 114 StdOut.print(">> "); 115 } 116 117 } 118}