// Interpreter.java // Interpreter is a class to represent an interpreter for the PL/0 programming // language. It works by traversing the syntax tree constructed by the parser. public class Interpreter { protected Store store; // memory store public Interpreter (int numStackFrames, int mainProgramSize) { store = new Store (numStackFrames, mainProgramSize); } public Store store () { return store; } // m interprets PL/0 programs. public void m (SyntaxTree syntaxTree) { s (syntaxTree); } // s interprets statements. public void s (SyntaxTree syntaxTree) { if (syntaxTree . root () . equals (";")) { s (syntaxTree . left ()); s (syntaxTree . right ()); } else if (syntaxTree . root () . equals (":=")) store . update (syntaxTree . left () . varLoc (), e (syntaxTree . right ())); else if (syntaxTree . root () . equals ("call")) { store . createStackFrame (syntaxTree . left () . varLoc ()); s (syntaxTree . left () . procBody ()); // execute body of procedure store . restoreStackFrame (syntaxTree . left () . varLoc ()); } else if (syntaxTree . root () . equals ("if-then")) { if (c (syntaxTree . left ())) s (syntaxTree . right ()); } else if (syntaxTree . root () . equals ("while-do")) { if (c (syntaxTree . left ())) { s (syntaxTree . right ()); // execute body of while loop s (syntaxTree); // execute while loop recursively } } } // c interprets conditions. public boolean c (SyntaxTree syntaxTree) { if (syntaxTree . root () . equals ("=")) return e (syntaxTree . left ()) == e (syntaxTree . right ()); else if (syntaxTree . root () . equals ("<")) return e (syntaxTree . left ()) < e (syntaxTree . right ()); else if (syntaxTree . root () . equals (">")) return e (syntaxTree . left ()) > e (syntaxTree . right ()); else if (syntaxTree . root () . equals ("<>")) return e (syntaxTree . left ()) != e (syntaxTree . right ()); else if (syntaxTree . root () . equals ("<=")) return e (syntaxTree . left ()) <= e (syntaxTree . right ()); else if (syntaxTree . root () . equals (">=")) return e (syntaxTree . left ()) >= e (syntaxTree . right ()); else // syntaxTree . root () . equals ("odd") return e (syntaxTree . left ()) % 2 == 1; } // e interprets expressions. public int e (SyntaxTree syntaxTree) { int e; if (syntaxTree . root () . equals ("+")) if (syntaxTree . right () == null) return e (syntaxTree . left ()); else return e (syntaxTree . left ()) + e (syntaxTree . right ()); else if (syntaxTree . root () . equals ("-")) if (syntaxTree . right () == null) return e (syntaxTree . left ()); else return e (syntaxTree . left ()) - e (syntaxTree . right ()); else if (syntaxTree . root () . equals ("*")) return e (syntaxTree . left ()) * e (syntaxTree . right ()); else if (syntaxTree . root () . equals ("/")) { int divisor = e (syntaxTree . right ()); if (divisor == 0) { ErrorMessage . print ("Division by zero"); return 0; // will not happen as ErrorMessage . print exits } else return e (syntaxTree . left ()) / divisor; } else if (syntaxTree . root () . equals ("id")) { e = store . access (syntaxTree . varLoc ()); if (e == Store . UNDEFINED) ErrorMessage . print ("Value of variable is undefined"); return e; } else // syntaxTree . root () . equals ("int") return syntaxTree . constValue (); } }