Creating a java interpreter for android?

7

I'm developing an android application where you can write a java code and run it ... something like visualg . so I did something different than most of the tutorials on compilers and pseudocodes would say ... where would that have to be generated a machine code written in assembly, or maybe just a java bytecode ... in the pc: (text -> intermediate code -> machine code -> Execute)
in android: (*. java -> java.class -> classes.dex -> ART interprets -> Execute)

But as the creation of a compiler of this type is too complex I decided to make an interpreter at runtime, and what it does is compile the text in "micro-operations", as for example, Sum, Subtraction , Multiplication, Println, etc ... then it does the following:
(text - > creates microperations -> runs every microperation)

The interpreter structure looks like this: nowIwantedtoknowifthereisawaytooptimizethiscode,doingsometestingwiththeemulator,Isawthatitispossibletorunupto79millionmicro-operationsin1second,whichisabout12timesslowerthanareal1.0gigahertzprocessor.butIwantedtofindoutifthewayIputitalltogetherisreallysomethingneworifthereareinterpretedlanguagesthatworkinasimilarwaytothisone(theyshouldconsumelotsofRAM)Homeanysuggestionsonhowtoimprove/optimizethisproject?
exampleofoneoftheexecutableclasses(allothersarethesameonlychangesthetypeandtheoperator)

publicfinalclassSomarDoublesextendsExecutavel{finalWDoublea;finalWDoubleb;finalWDoublec;publicSomarDoubles(WDoublea,WDoubleb,WDoublec){this.a=a;this.b=b;this.c=c;}@OverridefinalpublicvoidExecutar(){c.valor=a.valor+b.valor;}}

exampleofatypeclass(samething,justchangethevaluecontained):

publicfinalclassWByteextendsValor{bytevalor=0;publicWByte(bytev){this.valor=v;}//métodosdecasting:@OverridefinalpublicshortShort(){returnvalor;}@OverridefinalpubliccharChar(){return(char)valor;}//etc...}

andthecodeatthetimeofexecution(thecompilationisdonebeforeandsendsthearrayandinstructions)

publicclassExecutarextendsThread{privatefinalExecutavel[]instrucoes;privatefinalintlength;publicstaticinti=0;publicExecutar(Executavel[]instrucoes){super();this.instrucoes=instrucoes;length=instrucoes.length;}@Overridefinalpublicvoidrun(){i=0;longdelay=System.nanoTime();longk=0;try{while(i<length){instrucoes[i++].Executar();k++;}}catch(Exceptione){e.printStackTrace();}longagora=System.nanoTime();doubletempo=(agora-delay);System.out.println("emulado : executou "+k+" instrucoes em "+tempo/1000000.0d+" milisegundos ("+tempo/1000000000.0d+" segundos), o que d� \n"
        + " aproximadamente "+tempo/k+" nanosegundos por instrucao");

}
}
    
asked by anonymous 07.04.2015 / 04:14

1 answer

5

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.

        
    07.04.2015 / 17:34