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}