package org.openlca.expressions;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
/**
* A read-eval-print-loop for formula evaluation.
*/
public class Repl {
private BufferedReader in;
private PrintStream out;
private PrintStream err;
FormulaInterpreter evaluator = new FormulaInterpreter();
public Repl(InputStream in, PrintStream out, PrintStream err) {
this.in = new BufferedReader(new InputStreamReader(in));
this.out = out;
this.err = err;
}
public void start() {
printWelcome();
String line = null;
try {
while ((line = in.readLine()) != null) {
String expression = line.trim();
if (expression.equalsIgnoreCase("exit")
|| expression.equalsIgnoreCase("quit"))
break;
eval(expression);
out.print("olca<< ");
}
} catch (Exception e) {
err.println("An unexpected error occurred: " + e.getMessage());
}
out.flush();
err.flush();
}
private void eval(String expression) {
if (expression.isEmpty())
out.println("olca>> ");
else if (expression.equalsIgnoreCase("help"))
printHelp();
else if (expression.startsWith("var "))
evalVariable(expression);
else
evalFormula(expression);
}
private void printWelcome() {
out.println("openLCA Formula Interpreter");
out.println("type 'help' to display the help message");
out.println("");
out.print("olca<< ");
}
private void printHelp() {
out.println(" evaluate an expression: \t type in the expression and press enter, e.g. sin(42)");
out.println(" define a variable: \t\t type var <variable name> = <expression>, e.g. var a = sin(42)");
out.println(" exit the interpreter: \t\t type 'exit' or 'quit' and press enter");
}
private void evalVariable(String expression) {
StringBuffer variableNameBuf = new StringBuffer();
StringBuffer formulaBuf = new StringBuffer();
parseVariableExpression(expression.substring(4), variableNameBuf,
formulaBuf);
String variableName = variableNameBuf.toString().trim();
String formula = formulaBuf.toString().trim();
if (variableName.isEmpty() || formula.isEmpty()) {
err.println("error>> Wrong variable declaration (syntax is "
+ "'var <identifier> = <expression>'). ");
} else {
evalVariable(variableName, formula);
}
}
private void parseVariableExpression(String expression,
StringBuffer variableNameBuf, StringBuffer formulaBuf) {
boolean after = false;
for (char c : expression.toCharArray()) {
if (c != '=' && !after) {
variableNameBuf.append(c);
} else if (c == '=' && !after) {
after = true;
} else if (after) {
formulaBuf.append(c);
}
}
}
private void evalVariable(String variableName, String formula) {
try {
evaluator.getGlobalScope().bind(variableName, formula);
double val = evaluator.eval(variableName);
out.println("olca>> " + variableName + " = " + val);
} catch (Exception e) {
err.println("error>> " + e.getMessage());
}
}
private void evalFormula(String expression) {
try {
Object result = evaluator.eval(expression);
out.println("olca>> " + result);
} catch (Exception e) {
err.println("error>> " + e.getMessage());
}
}
public static void main(String[] args) {
Repl repl = new Repl(System.in, System.out, System.err);
repl.start();
}
}