GWTJep JavaScript mathematical expression parser/evaluator.

GWTExpose - Jep functions exposed to JavaScript

The GWTExpose module exposes a limited set of Jep functionality so that it can be called directly from JavaScript.

Basic functionality

To use the GWTExpose functionality a page needs the following JavaScript

<script type="text/javascript">
    var pageType = "Expose";
    window.jepModuleLoaded = function() {
	    console.log("jepModuleLoaded - run after Jep module loaded");
    }
</script>

<script type="text/javascript" src="gwtjep/gwtjep.nocache.js"></script>

This creates an Object Jep or equivalently window.Jep with various methods. For example

    node1 = Jep.parse("y = 2 x+3");

The value can be set with

    Jep.setVariable("x",5)

Which can then be evaluated with

    result1 = Jep.evaluate(node1);
    alert(result1);

And the variable value retrieved with

    result2 = Jep.getVariableValue("y")	
    alert(result2);
    

How exposing Jep code to JavaScript works

First an empty JavaScript Jep object is created.

var jep = new Object();
window.jep = jep;

When the GWT code is loaded it then populates this object with methods using GWT's ability to embed JavaScript in the java as native methods.

@Override
Jep jep;

/** 
 * Standard GWT method called when module loaded.
 */
public void onModuleLoad() {
	jep = new Jep(new StandardConfigurableParser());
	onModLoad();	
}

/**
 * Native JavaScript method.
 * Adds methods to the JavaScript jep object.
 */
public static native void onModLoad() /*-{
    $wnd.jep.parse =
          $entry(@com.singsurf.gwtjep.client.GWTExpose::parse(Ljava/lang/String;));
    $wnd.jep.evaluateD =
          $entry(@com.singsurf.gwtjep.client.GWTExpose::evaluateD());
}-*/;

These in turn call some Java wrapper functions

public static Node parse(String S) {
    errorMsg="";
    Node res;
    try {
         res = jep.parse(S);
    } catch (ParseException e) {
        errorMsg = e.toString();
        rootLogger.warning(errorMsg);
        return null;
    }
    return res;
}

public static double evaluateD() {
     errorMsg="";
     double res;
     try {
         res = jep.evaluateD();
     } catch (EvaluationException e) {
         errorMsg = e.toString();
         return Double.NaN;
     }
     return res;
}
which call the actual Jep code.

This then means its possible to call jep functions in JavaScript.

	var inF = document.getElementById('InputField');
	var outF = document.getElementById('OutputField');
	var inT = inF.value;
	var node = jep.parse(inT);
	if(node==null) {
		var err = jep.getErrMsg();
		console.log(err);
		outF.value = err;
		return;
	}
	var res = jep.evaluateD(node);
	if(isNaN(res)) {
		var err = jep.getErrMsg();
		if(err=="") { // no error message means its a genuine NaN
			console.log(res);
			outF.value = res;
		} else {
			console.log(err);
			outF.value = err;
		}
	}
	else {
		console.log(res);
		outF.value = res;
	}	

Exposed methods

Currently only a limited portion of the Jep functionality is exposed to JavaScript. This could easily be extended.

Jep.parse(expression)
Parse a expression.
Input: a string representing the equation.
Output: an object representing the parsed expression.
Throws an exception if there is an error in the expressions
Jep.parseNE(expression)
Parse a expression.
Input: a string representing the equation.
Output: an object representing the parsed expression.
Does not throw exception on error, instead returns null if there is an error.
Jep.evaluateD()
Evaluates the last expression parsed.
Output: a numerical value.
Returns NaN if there is an error.
Jep.evaluate(node)
Evaluates a parsed expression.
Input: the result of a previous call to jep.parse(expression)
Output: a numerical value, a string or an object depending on the result of the calculation.
Jep.evaluateNE(node)
Evaluates a parsed expression, does not throw exception on error, instead returns null if there is an error.
Jep.getVariableValue(name)
Gets the value of a variable, assumes its an numeric value.
Input: the name of the variable, a string
Output: A numerical value.
Returns NaN on error.
Jep.setVariable(name,value)
Sets the value of a variable.
Input: the name of the variable, and its value. This can be either a numeric type or string.
Output: A reference to the variable object.
Throws and exception on error.
Jep.setVariableNE(name,value)
Sets the value of a variable.
Input: the name of the variable, and its value. This can be either a numeric type or string.
Output: A reference to the variable object.
Does not throw exception on error, instead returns null if there is an error.
Jep.getErrMsg()
Gets the error message of the last operation.
Output: A string with the error message, can be the empty string if the last operation was successful.
Jep.toString(node)
Returns a string representation of the node.

Experimental features:

Jep.getNChildren(node)
Get the number of children of a node
Jep.getChild(node,index)
Gets the i-th child of a node
Jep.nodeType(node)
The type of node: 2 = operator, 3 = variable, 4 = function, 5 = constant value
Jep.getOperator(node)
Gets the operator associated with a node
Jep.getNodeName(node)
Gets name of a variable, function or operator node
Jep.getNodeValue(node)
Gets the numerical value associated with a constant or variable node
Jep.getOpPrec(op)
Get the precedence of an operator
Jep.getOpSymbol(op)
Gets the symbol of an operator
Jep.nf.buildVarNode(name)
Build a variable node
Jep.nf.buildConstantNode(val)
Builds a constant node with a given value
Jep.nf.buildBinaryOpNode(op,left,right)
Builds a binary operator node