Compiler vs. Interpreter
There is no problem in creating interpreters for a particular language or a subset of it.
Your approach is correct under some conditions:
Your interpreter really meets your needs. Certainly you would not be able to emulate the entire Java language in this way, but a simplified set of instructions.
The interpreter meets your performance requirements. Of course interpreting or emulating is always slower than having a compiled code, but in many cases this will be imperceptible to the user if it is used sparingly at specific points and storing the results in cache when possible.
Define exactly the scope of your language
As I understand it, you do not need all the features of Java, but mostly some expressions and also print commands.
In this case, specify exactly the syntax and grammar of this sub-language derived from Java and consider whether it will be possible to implement all the necessary functionality.
I do not know how you're doing the code interpretation, but even if you're not building a compiler, you're going to use compiler theory because you've already created or will need to create lexical, syntactic, and semantic parsers.
If you happen to be interpreting the language using regex , split or substring if there are multiple levels of parentheses in mathematical expressions.
Finally, creating an interpreter, even if only for a very small scope like math expressions, is not entirely trivial unless you have a good theoretical background or at least practice on the subject.
See an example of an expression interpreter in my other answer.
Other options
If you really need to run some more complex code and do not want to reinvent the wheel, consider using an existing interpreter.
There are several libraries in Java that can help you:
Rhino
This JavaScript interpreter is implemented in Java. See an article about using it on Android. Here's another .
Here's an example:
public void runScript() {
// Get the JavaScript in previous section
String source = getScriptFromServer();
String functionName = "hello";
Object[] functionParams = new Object[] { "Android" };
// Every Rhino VM begins with the enter()
// This Context is not Android's Context
Context rhino = Context.enter();
// Turn off optimization to make Rhino Android compatible
rhino.setOptimizationLevel(-1);
try {
Scriptable scope = rhino.initStandardObjects();
// This line set the javaContext variable in JavaScript
ScriptableObject.putProperty(scope, "javaContext", Context.javaToJS(androidContextObject, scope));
// Note the forth argument is 1, which means the JavaScript source has
// been compressed to only one line using something like YUI
rhino.evaluateString(scope, RHINO_LOG + source, "ScriptAPI", 1, null);
// We get the hello function defined in JavaScript
Function function = (Function) scope.get(functionName, scope);
// Call the hello function with params
NativeObject result = (NativeObject) function.call(rhino, scope, scope, functionParams));
// After the hello function is invoked, you will see logcat output
// Finally we want to print the result of hello function
String foo = (String) Context.jsToJava(result.get("foo", result), String.class);
log(foo);
} finally {
// We must exit the Rhino VM
Context.exit();
}
}
Java Expression Language (JEXL)
JEXL is a library that implements a JSTL-based expression language, similar to what we have in JSPs.
Example:
// Assuming we have a JexlEngine instance initialized in our class named 'jexl':
// Create an expression object for our calculation
String calculateTax = taxManager.getTaxCalc(); //e.g. "((G1 + G2 + G3) * 0.1) + G4";
Expression e = jexl.createExpression( calculateTax );
// populate the context
JexlContext context = new MapContext();
context.set("G1", businessObject.getTotalSales());
context.set("G2", taxManager.getTaxCredit(businessObject.getYear()));
context.set("G3", businessObject.getIntercompanyPayments());
context.set("G4", -taxManager.getAllowances());
// ...
// work it out
Float result = (Float)e.evaluate(context);
Velocity
Apache Velocity is a template library, but can also be used to run expressions and snippets of code in a special syntax
p>
The documentation says how you can use it within a Java application, and provide a language reference .
Example of how to run Velocity:
/* first, we init the runtime engine. Defaults are fine. */
Velocity.init();
/* lets make a Context and put data into it */
VelocityContext context = new VelocityContext();
context.put("name", "Velocity");
context.put("project", "Jakarta");
/* lets render a template */
StringWriter w = new StringWriter();
Velocity.mergeTemplate("testtemplate.vm", context, w );
System.out.println(" template : " + w );
/* lets make our own string to render */
String s = "We are using $project $name to render this.";
w = new StringWriter();
Velocity.evaluate( context, w, "mystring", s );
System.out.println(" string : " + w );
MVEL
The Apache MVEL is another expression language library.
You can learn about language syntax in documentation , as well as include it to your program easily .
Example:
String expression = "foobar > 99";
Map vars = new HashMap();
vars.put("foobar", new Integer(100));
// We know this expression should return a boolean.
Boolean result = (Boolean) MVEL.eval(expression, vars);
if (result.booleanValue()) {
System.out.println("It works!");
}
MVEL allows you to "compile" the expression for better performance if reused and also force checking of variable types to avoid errors during execution.