-
-
Notifications
You must be signed in to change notification settings - Fork 88
Functions preprocessor
- Extend keywords in AST2Expr
- Generate files
- Implementing new functions
- Integrating your own Java library with the WXF format
To add new predefined constants or function symbols you have to extend the following String
arrays in org.matheclipse.core.convert.AST2Expr
-
UPPERCASE_SYMBOL_STRINGS
- symbols which are exactly one uppercase constant or function -
DOLLAR_STRINGS
- symbols starting with a '$' character -
SYMBOL_STRINGS
- constant identifiers, which are not used as a function identifier -
FUNCTION_STRINGS
- function identifiers
We can for example add a new user function MyFunction
to the FUNCTION_STRINGS
array.
If the AST2Expr
definitions have changed these two programs can generate new sources in the Eclipse console output:
- the FunctionIDGenerator.java program is used to generate the file org.matheclipse.core.expression.ID
- the BuiltinGenerator.java program is used to generate the predefined
IBuiltInSymbol
's in file org.matheclipse.core.expression.F
A new function is implemented in the package org.matheclipse.core.builtin
A typical "template" for an example built-in function MyFunction
is implemented like this. The evaluation of MyFunction({a,b,c})
should return the first argument {a,b,c}
if the first argument is a list.
package org.matheclipse.core.builtin;
import org.matheclipse.core.eval.EvalEngine;
import org.matheclipse.core.eval.exception.Validate;
import org.matheclipse.core.eval.interfaces.AbstractEvaluator;
import org.matheclipse.core.expression.F;
import org.matheclipse.core.interfaces.IAST;
import org.matheclipse.core.interfaces.IExpr;
public class UserFunctions {
static {
F.MyFunction.setEvaluator(new MyFunction());
}
private static class MyFunction extends AbstractEvaluator {
@Override
public IExpr evaluate(final IAST ast, EvalEngine engine) {
// test if only 1 argument is allowed:
Validate.checkRange(ast, 2);
if (ast.arg1().isList()) {
return ast.arg1();
}
return F.NIL;
}
}
private final static UserFunctions CONST = new UserFunctions();
public static UserFunctions initialize() {
return CONST;
}
private UserFunctions() {
}
}
It must be initialized in the F.class static block:
...
static {
Thread INIT_THREAD = null;
...
VectorAnalysisFunctions.initialize();
QuantityFunctions.initialize();
FinancialFunctions.initialize();
WXFFunctions.initialize();
WindowFunctions.initialize();
UserFunctions.initialize();
...
}
...
Now the evaluation of MyFunction({a,b,c})
returns the first argument {a,b,c}
. And the evaluation of MyFunction(test)
returns unevaluated as MyFunction(test)
.
For creating a quick prototype which can use Symja functions to call your own library, you should consider implementing functions similar to the BinarySerialize, BinaryDeserialize functions with the WXF format: https://reference.wolfram.com/language/tutorial/WXFFormatDescription.html
The implementation whic is use in Symja can be found here:
- https://github.com/axkr/symja_android_library/blob/master/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/expression/WL.java
- https://github.com/axkr/symja_android_library/blob/master/symja_android_library/matheclipse-io/src/test/java/org/matheclipse/io/system/WXFTestCase.java