Package com.CompPad.model

Source Code of com.CompPad.model.GroovyEngine

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package com.CompPad.model;

import com.CompPad.model.operators.Operator;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Closure;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.List;

/**
* This class encapsulates everything related to the groovy shell which will be
* common to all implementations of comppad - whether as a document, or
* a console application.
* @author trule
*/
public class GroovyEngine {
    /* static variables for evaluating postfix operators */
    public static final int IGNORE=100;
    public static final int PREFIX=1;
    public static final int INFIX=2;
    public static final int POSTFIX=3;
    public static final int LEFTPARENTHESIS = 4;
    public static final int RIGHTPARENTHESIS = 5;
    public static final int LISTSEPARATOR=6; /* eg a comma. */

        /* Make these static so there's only one copy of these hashtables */
    public  static Hashtable<String,Integer> Types=new Hashtable(); /* */
    public  static Hashtable<String, Integer> Numargs=new Hashtable(); /* */
    public  static Hashtable<String,String> Convert=new Hashtable(); /* operator to convert to */
    public  static Hashtable<String,Integer> Precedence=new Hashtable(); /* Operator Precedence */
    public static Hashtable<String,String> Replace=new Hashtable();


    private Binding groovyBinding;
    private GroovyShell groovyShell;
    public  GroovyEngine() throws java.lang.Exception {


                /* Initialize parameters for postfix conversion and translation to JAVA
         * string. Constructor must be non-static to initialize non-static fields */
       Replace.put("Symbol_pi","ops.pi()");
       Replace.put("e","ops.e()");
        /* May want to separate out these initializations into a separate method?
         * or at least move to "CompPad"  class */
       Types.put("(", LEFTPARENTHESIS);
       Convert.put("(","(");
       Precedence.put("(", -1000);
       Numargs.put("(",0);

       Types.put("[", LEFTPARENTHESIS);
        Convert.put("[","(");
        Precedence.put("[", -1000);
       Numargs.put("[",0);

       Types.put("{", LEFTPARENTHESIS);
       Convert.put("{","(");
       Precedence.put("{", -1000);
       Numargs.put("{",0);

       Types.put(")", RIGHTPARENTHESIS);
       Convert.put(")",")");

       Types.put("]", RIGHTPARENTHESIS);
       Convert.put("]",")");

       Types.put("}", RIGHTPARENTHESIS);
       Convert.put("}",")");

       Types.put("right",IGNORE); /* Used to indicate right parenthesis */
       Types.put("left",IGNORE); /* Unsed to indicate left parentheses */

       Types.put("COMPPAD_OPERATOR_OBJECT",POSTFIX);
       Numargs.put("COMPPAD_OPERATOR_OBJECT",1);
       Convert.put("COMPPAD_OPERATOR_OBJECT","COMPPAD_OPERATOR_OBJECT");
       Precedence.put("COMPPAD_OPERATOR_OBJECT",4); //  precedence higher than mult, lower than prefix ops.

       /* Note that if the keys don't match on these four items,
        * IT CAN DRIVE YOU CRAZY trying to find the problem.
        * There must be a better way...*/
       Types.put("elwise",POSTFIX);
       Numargs.put("elwise",1);
       Convert.put("elwise","ops.elwise");
       Precedence.put("elwise ",2); //  precedence higher than mult, lower than prefix ops.

       Types.put("over",INFIX);
       Numargs.put("over",2);
       Convert.put("over","ops.div");
       Precedence.put("over",1);

       Types.put("/", INFIX);
       Numargs.put("/",2);
       Convert.put("/","ops.div");
       Precedence.put("/",1);

       Types.put("div",INFIX);
       Numargs.put("div",2);
       Convert.put("div","ops.div");
       Precedence.put("div",1);

       Types.put("times",INFIX);
       Numargs.put("times",2);
       Convert.put("times","ops.mult");
       Precedence.put("times",1);

       Types.put("*",INFIX);
       Numargs.put("*",2);
       Convert.put("*","ops.mult");
       Precedence.put("*",1);

       Types.put("cdot",INFIX);
       Numargs.put("cdot",2);
       Convert.put("cdot","ops.mult");
       Precedence.put("cdot",1);

       Types.put("^",INFIX);
       Numargs.put("^",2);
       Convert.put("^","ops.pow");
       Precedence.put("^",4);

       Types.put("nroot",PREFIX);
       Numargs.put("nroot",2);
       Convert.put("nroot","ops.nroot");
       Precedence.put("nroot",3);

       Types.put("+",INFIX);
       Numargs.put("+",2);
       Convert.put("+","ops.add");
       Precedence.put("+",0);

       Types.put("-",INFIX);
       Numargs.put("-",2);
       Convert.put("-","ops.sub");
       Precedence.put("-",0);

       Types.put("-",INFIX);
       Numargs.put("-",2);
       Convert.put("-","ops.sub");
       Precedence.put("-",0);

       Types.put("neg",PREFIX);
       Numargs.put("neg",1);
       Convert.put("neg","ops.not");
       Precedence.put("not",3);

       Types.put("negative",PREFIX);
       Numargs.put("negative",1);
       Convert.put("negative","ops.negative");
       Precedence.put("negative",3);

       Types.put("<",INFIX);
       Numargs.put("<",2);
       Convert.put("<", "ops.lt");
       Precedence.put("<",-1);

       Types.put(">",INFIX);
       Numargs.put(">",2);
       Convert.put(">", "ops.gt");
       Precedence.put(">",-1);

//       Types.put("<=",INFIX);
//       Numargs.put("<=",2);
//       Convert.put("<=", "ops.lte");
//       Precedence.put("<=",-1);

       Types.put("COMPPAD_LTE",INFIX);
       Numargs.put("COMPPAD_LTE",2);
       Convert.put("COMPPAD_LTE", "ops.lte");
       Precedence.put("COMPPAD_LTE",-1);

//       Types.put(">=",INFIX);
//       Numargs.put(">=",2);
//       Convert.put(">=", "ops.gte");
//       Precedence.put(">=",-1);

       Types.put("COMPPAD_GTE",INFIX);
       Numargs.put("COMPPAD_GTE",2);
       Convert.put("COMPPAD_GTE", "ops.gte");
       Precedence.put("COMPPAD_GTE",-1);

//       Types.put("<>",INFIX);
//       Numargs.put("<>",2);
//       Convert.put("<>", "ops.neq");
//       Precedence.put("<>",-2);

       Types.put("COMPPAD_NEQ",INFIX);
       Numargs.put("COMPPAD_NEQ",2);
       Convert.put("COMPPAD_NEQ", "ops.neq");
       Precedence.put("COMPPAD_NEQ",-2);

       Types.put("=",INFIX);
       Numargs.put("=",2);
       Convert.put("=", "ops.eq");
       Precedence.put("=",-2);

       Types.put("and",INFIX);
       Numargs.put("and",2);
       Convert.put("and","ops.and");
       Precedence.put("and",-6);

       Types.put("or",INFIX);
       Numargs.put("or",2);
       Convert.put("or","ops.or");
       Precedence.put("or",-7);

       Types.put(":=",INFIX);
       Numargs.put(":=",2);
       Convert.put(":=","ops.assign");
       Precedence.put(":=",-1000);

       Types.put("sqrt", PREFIX);
       Numargs.put("sqrt",1);
       Convert.put("sqrt","ops.sqrt");
       Precedence.put("sqrt",3);

       Types.put("sin",PREFIX);
       Numargs.put("sin",1);
       Convert.put("sin","ops.sin");
       Precedence.put("sin",3);

       Types.put("sin2",PREFIX);
       Numargs.put("sin2",1);
       Convert.put("sin2","ops.sin2");
       Precedence.put("sin2",3);

       Types.put("cos",PREFIX);
       Numargs.put("cos",1);
       Convert.put("cos","ops.cos");
       Precedence.put("cos",2);

       Types.put("cos2",PREFIX);
       Numargs.put("cos2",1);
       Convert.put("cos2","ops.cos2");
       Precedence.put("cos2",2);

       Types.put("tan",PREFIX);
       Numargs.put("tan",1);
       Convert.put("tan","ops.tan");
       Precedence.put("tan",3);

       Types.put("tan2",PREFIX);
       Numargs.put("tan2",1);
       Convert.put("tan2","ops.tan2");
       Precedence.put("tan2",3);

       Types.put("sec",PREFIX);
       Numargs.put("sec",1);
       Convert.put("sec","ops.sec");
       Precedence.put("sec",3);

       Types.put("sec2",PREFIX);
       Numargs.put("sec2",1);
       Convert.put("sec2","ops.sec2");
       Precedence.put("sec2",3);

       Types.put("csc",PREFIX);
       Numargs.put("csc",1);
       Convert.put("csc","ops.csc");
       Precedence.put("csc",3);

       Types.put("csc2",PREFIX);
       Numargs.put("csc2",1);
       Convert.put("csc2","ops.csc2");
       Precedence.put("csc2",3);

       Types.put("cot",PREFIX);
       Numargs.put("cot",1);
       Convert.put("cot","ops.cot");
       Precedence.put("cot",3);

       Types.put("cot2",PREFIX);
       Numargs.put("cot2",1);
       Convert.put("cot2","ops.cot2");
       Precedence.put("cot2",3);

       Types.put("asin",PREFIX);
       Numargs.put("asin",1);
       Convert.put("asin","ops.asin");
       Precedence.put("asin",3);

       Types.put("acos",PREFIX);
       Numargs.put("acos",1);
       Convert.put("acos","ops.acos");
       Precedence.put("acos",3);

       Types.put("atan",PREFIX);
       Numargs.put("atan",1);
       Convert.put("atan","ops.atan");
       Precedence.put("atan",3);

       Types.put("asec",PREFIX);
       Numargs.put("asec",1);
       Convert.put("asec","ops.asec");
       Precedence.put("asec",3);

       Types.put("acsc",PREFIX);
       Numargs.put("acsc",1);
       Convert.put("acsc","ops.acsc");
       Precedence.put("acsc",3);

       Types.put("acot",PREFIX);
       Numargs.put("acot",1);
       Convert.put("acot","ops.acot");
       Precedence.put("acot",3);

       /* ISO math notation */
       Types.put("ln",PREFIX);
       Numargs.put("ln",1);
       Convert.put("ln", "ops.log");
       Precedence.put("ln",3);

       Types.put("log_10",PREFIX);
       Numargs.put("log_10",1);
       Convert.put("log_10","ops.log10");
       Precedence.put("log_10",3);

       Types.put("round",PREFIX);
       Numargs.put("round",2);
       Convert.put("round","ops.round");
       Precedence.put("round",3);

       Types.put("ceil",PREFIX);
       Numargs.put("ceil",2);
       Convert.put("ceil","ops.ceil");
       Precedence.put("ceil",3);

       Types.put("floor",PREFIX);
       Numargs.put("floor",2);
       Convert.put("floor","ops.floor");
       Precedence.put("floor",3);

       Types.put("rand",PREFIX);
       Numargs.put("rand",2);
       Convert.put("rand","ops.rand");
       Precedence.put("rand",3);

       Types.put("zeros",PREFIX);
       Numargs.put("zeros",2);
       Convert.put("zeros","ops.zeros");
       Precedence.put("zeros",3);

       Types.put("ones",PREFIX);
       Numargs.put("ones",2);
       Convert.put("ones","ops.ones");
       Precedence.put("ones",3);

       Types.put("Re",PREFIX);
       Numargs.put("Re",1);
       Convert.put("Re", "ops.real");
       Precedence.put("Re",3);

       Types.put("Im",PREFIX);
       Numargs.put("Im",1);
       Convert.put("Im", "ops.imaginary");
       Precedence.put("Im",3);

       Types.put("sgn",PREFIX);
       Numargs.put("sgn",1);
       Convert.put("sgn", "ops.signum");
       Precedence.put("sgn",3);

       Types.put("arg",PREFIX);
       Numargs.put("arg",1);
       Convert.put("arg", "ops.argument");
       Precedence.put("arg",3);

       Types.put("COMPPAD_CONJUGATE",POSTFIX);
       Numargs.put("COMPPAD_CONJUGATE",1);
       Convert.put("COMPPAD_CONJUGATE", "ops.conjugate");
       Precedence.put("COMPPAD_CONJUGATE",3);

       Types.put("COMPPAD_TRANSPOSE", POSTFIX);
       Numargs.put("COMPPAD_TRANSPOSE", 1);
       Convert.put("COMPPAD_TRANSPOSE","ops.transpose");
       Precedence.put("COMPPAD_TRANSPOSE",3);

       Types.put("max",PREFIX);
       Numargs.put("max",1);
       Convert.put("max","ops.max");
       Precedence.put("max",3);

       Types.put("min",PREFIX);
       Numargs.put("min",1);
       Convert.put("min","ops.min");
       Precedence.put("min",3);

       Types.put("sum",PREFIX);
       Numargs.put("sum",1);
       Convert.put("sum","ops.sum");
       Precedence.put("sum",3);

       Types.put("prod",PREFIX);
       Numargs.put("prod",1);
       Convert.put("prod","ops.prod");
       Precedence.put("prod",3);

       Types.put("rows",PREFIX);
       Numargs.put("rows",1);
       Convert.put("rows","ops.rows");
       Precedence.put("rows",3);

       Types.put("columns",PREFIX);
       Numargs.put("columns",1);
       Convert.put("columns","ops.columns");
       Precedence.put("columns",3);

       Types.put("size",PREFIX);
       Numargs.put("size",1);
       Convert.put("size","ops.size");
       Precedence.put("size",3);

       Types.put("dotslow",INFIX);
       Numargs.put("dotslow",2);
       Convert.put("dotslow","ops.range");
       Precedence.put("dotslow",0);

       Types.put("CompPad_Literal",POSTFIX);
       Numargs.put("CompPad_Literal",1);
       Convert.put("CompPad_Literal","ops.literal"); /* Ignore for now */
       Precedence.put("CompPad_Literal",4);

       Types.put("COMPPAD_ABS",PREFIX);
       Numargs.put("COMPPAD_ABS",1);
       Convert.put("COMPPAD_ABS","ops.abs");
       Precedence.put("COMPPAD_ABS",3);

       Types.put("SIGFIGS",PREFIX);
       Numargs.put("SIGFIGS",1);
       Convert.put("SIGFIGS","ops.setSigFigs");
       Precedence.put("SIGFIGS",3);

       Types.put("setDecimalSeparator",PREFIX);
       Numargs.put("setDecimalSeparator",1);
       Convert.put("setDecimalSeparator","ops.setDecimalSeparator");
       Precedence.put("setDecimalSeparator",1);

//       Types.put("unitValueOf",PREFIX);
//       Numargs.put("unitValueOf",2);
//       Convert.put("unitValueOf","ops.unitValueOf");
//       Precedence.put("unitValueOf",2);
//
//       Types.put("unitSI",PREFIX);
//       Numargs.put("unitSI", 1);
//       Convert.put("unitSI", "ops.unitSI");
//       Precedence.put("unitSI",2);
//
//       Types.put("unitNonSI",PREFIX);
//       Numargs.put("unitNonSI", 1);
//       Convert.put("unitNonSI", "ops.unitNonSI");
//       Precedence.put("unitNonSI",2);

       Types.put("units",PREFIX);
       Numargs.put("units",1);
       Convert.put("units","ops.units");
       Precedence.put("units",3);

       Types.put(",",INFIX);
       Numargs.put(",", 2);
       Convert.put(",", "ops.addColumn");
       Precedence.put(",",-10);

       Types.put("##",INFIX);
       Numargs.put("##",2);
       Convert.put("##", "ops.addRow");
       Precedence.put("##", -11);

       /* AddColumn needs to bind tighter than addRow, when used with the
        * "matrix" keyword */
       Types.put("#",INFIX);
       Numargs.put("#",2);
       Convert.put("#","ops.addColumn");
       Precedence.put("#", -10);

       Types.put("matrix",PREFIX);
       Numargs.put("matrix",1);
       Convert.put("matrix","");
       Precedence.put("matrix", 3);

       /* Subscript array indices */
       Types.put("sub",INFIX);
       Numargs.put("sub",2);
       Convert.put("sub","ops.subscript");
       Precedence.put("sub",4);

       Types.put("plotxy",PREFIX);
       Numargs.put("plotxy",1);
       Convert.put("plotxy","ops.plotxy");
       Precedence.put("plotxy",3);





        groovyBinding = new groovy.lang.Binding();
        groovyShell=new GroovyShell(groovyBinding);
        groovyShell.evaluate(
            "import com.CompPad.model.Operators;ops=Operators;");

        List<Field> unitFields = new ArrayList();
        javax.measure.unit.SI unitSI = javax.measure.unit.SI.getInstance();
        javax.measure.unit.NonSI unitNonSI = javax.measure.unit.NonSI.getInstance();
        unitFields = Arrays.asList(javax.measure.unit.SI.class.getFields());
        for (Field field:unitFields){
            groovyShell.setVariable(field.getName().replace("_", "x"), Operators.units(field.getName()));
        }
        unitFields=Arrays.asList(javax.measure.unit.NonSI.class.getFields());
        for (Field field:unitFields){
            groovyShell.setVariable(field.getName().replace("_", "x"), Operators.units(field.getName()));
        }

    }
    //

   
    public Object getVariable(String name){
        try{
            return groovyBinding.getVariable(name);
        }
        catch(Exception e){
            return null;
        }
    }
    public  void setVariable(String name, Object object){
        groovyBinding.setVariable(name, object);
    }
    private java.util.Set getVariableNames(){
    return groovyBinding.getVariables().keySet();
    }
    public boolean hasVariable(String name, Class type){
        try{
            return groovyBinding.getVariable(name).getClass().getSuperclass()
                == type;
        }
        catch (Exception e){
            return false;
        }
    }

    public void evaluate(String s){
        groovyShell.evaluate(s);
    }
    public boolean hasOperator(String name){
        // First check if it's in the Types map.
        // All these operators will eventually be transitioned to "Operator" classes.
        if (name==null){
            return false;
        }
        else if (Types.containsKey(name)){
            return true;
        }
        else if (this.hasVariable(name, Operator.class)){
            return true;
        }
        else if (this.hasVariable(name,Closure.class)){
            return true;
        }
        else{
            return false;
        }
    }
//    public boolean hasOperator(String name, Class type){
//
//    }
    public Integer getType(String name){
        if (Types.containsKey(name)){
            return Types.get(name);
        }
        else if (this.hasVariable(name,Closure.class)){
            // closures will be treated as prefix (for now)
            // although it would be cool to define new infix operators ...
            return PREFIX;
        }
        else{
            return null;
        }
    }
    public Integer getNumArgs(String name){
        if (Numargs.containsKey(name)){
            return Numargs.get(name);
        }
        else if (this.hasVariable(name,Closure.class)){
            return ( (Closure) this.getVariable(name) ).getMaximumNumberOfParameters();
        }
        else{
            return null;
        }
    }
    public Integer getPrecedence(String name){
        if (Precedence.containsKey(name)){
            return Precedence.get(name);
        }
        else if (this.hasVariable(name,Closure.class)){
            // precedence of prefix operators is null;
            return 3;
        }
        else{
            return null;
        }
    }
    public String getReplacement(String name){
        if (Replace.containsKey(name)){
            return Replace.get(name);
        }
        else{
            return null;
        }
    }
    public String getConvert(String name){
        if (Convert.containsKey(name)){
            return Convert.get(name);
        }
        else if (this.hasVariable(name,Closure.class)){
            // precedence of prefix operators is null;
            return name;
        }
        else{
            return null;
        }
    }
}
TOP

Related Classes of com.CompPad.model.GroovyEngine

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.