import java.io.*;
class Id {
private String id;
double value;
Id(String s, double d) {
id = s; value = d;
}
public boolean equals(Object node) {
return id.equals(((Id)node).id);
}
public String toString() {
return id + " = " + value + "; ";
}
}
class Interpreter {
static String input;
static InputStreamReader isr = new InputStreamReader(System.in);
static BufferedReader buffer = new BufferedReader(isr);
static java.util.LinkedList idList = new java.util.LinkedList();
static char ch;
static int i = 0;
static public void addOrModify(String id, double e) {
Id tmp = new Id(new String(id),e);
int pos;
if ((pos = idList.indexOf(tmp)) != -1)
((Id)idList.get(pos)).value = e;
else idList.add(tmp);
}
static double findValue(String id) {
int pos;
if ((pos = idList.indexOf(new Id(id,0.0))) != -1)
return ((Id)idList.get(pos)).value;
else issueError("Unknown variable " + id);
return 0.0; // this statement will never be reached;
}
static void issueError(String s) {
System.out.println(s);
Runtime.getRuntime().exit(-1);
}
static void skipblanks() {
while (Character.isSpace(ch))
readCh();
}
static String getLine() {
i = 0;
System.out.flush();
try {
input = buffer.readLine();
} catch(IOException io) {
System.out.println("Problem with input.");
}
return input;
}
static void readCh() {
if (i < input.length())
ch = input.charAt(i++);
else issueError("Incomplete expression");
}
/** readId() reads strings of letters, underscores, dollar signs, and
* digits that start with a letter, an underscore, or a dollar sign.
* Examples of identifiers are: var1, x, _pqr123xyz, $aName, etc.
*/
static String readId() {
String id = "";
skipblanks();
if (Character.isJavaLetter(ch)) {
while (Character.isJavaLetterOrDigit(ch)) {
id += ch;
readCh(); // don't skip blanks;
}
}
else issueError("Identifier expected");
return id;
}
static double factor() {
double var, minus = 1.0;
readCh();
skipblanks();
while (ch == '+' || ch == '-') { // take all '+'s and '-'s.
if (ch == '-')
minus *= -1.0;
readCh();
}
if (Character.isDigit(ch) || ch == '.') { // factor can be a number
String number = new String();
while (Character.isDigit(ch)) {
number += ch;
readCh();
}
if (ch == '.') {
number += ch;
readCh();
}
while (Character.isDigit(ch)) {
number += ch;
readCh();
}
var = Double.valueOf(number).doubleValue();
}
else if (ch == '(') { // or a parenthesized expression,
var = expression();
skipblanks();
if (ch == ')')
readCh();
else issueError("Right paren left out");
}
else {
String id = readId(); // or an identifier.
var = findValue(id);
}
skipblanks();
return minus * var;
}
static double exponent () { // := ^
double f = factor();
if (ch == '^')
return Math.pow(f,exponent());
else return f;
}
static double term() {
double f = exponent();
while (true) {
switch (ch) {
case '*' : f *= exponent(); break;
case '/' : f /= exponent(); break;
default : return f;
}
}
}
static double expression() {
double t = term();
while (true) {
switch (ch) {
case '+' : t += term(); break;
case '-' : t -= term(); break;
default : return t;
}
}
}
static void getStatement() {
System.out.print("Enter a statement: ");
getLine();
readCh();
String str = readId();
if (str.toUpperCase().equals("STATUS")) {
java.util.Iterator it = idList.iterator();
while (it.hasNext())
System.out.println(it.next());
}
else if (str.toUpperCase().equals("PRINT")) {
str = readId();
System.out.println(str + " = " + findValue(str));
}
else if (str.toUpperCase().equals("END"))
Runtime.getRuntime().exit(0);
else {
skipblanks();
if (ch == '=') {
double e = expression();
if (ch != ';')
issueError("There are some extras in the statement");
else addOrModify(str,e);
}
else issueError("'=' is missing");
}
}
public static void main(String args[]) {
System.out.println("The program processes statements in the "
+ "following format:\n"
+ "\t = ;\n\tprint ;\n\tstatus;\n\tend;\n");
while (true) // exit caused by an errot or entering
getStatement(); // 'end;' in getStatement();
}
}