Skip to content

Commit

Permalink
docs: update docs for bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
yusshu committed Jul 10, 2024
1 parent b3d0401 commit 496e4f5
Showing 1 changed file with 3 additions and 60 deletions.
63 changes: 3 additions & 60 deletions docs/bindings.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,7 @@
## Bindings

There are two ways to bind a external function/property to the Mocha environment so that
it can be used from the used expressions.

### 1. Function interface

The way is faster for interpreted expressions, but slower for compiled expressions.

<!--@formatter:off-->
```java
MochaEngine<?> mocha = MochaEngine.createStandard();

// query.get_age()
mocha.scope().query().set("get_age", (ctx, args) -> {
return NumberValue.of(18);
});

mocha.eval("query.get_age()"); // evaluates to 18
```
<!--@formatter:on-->

### 2. Java methods

This way is faster for compiled expressions, since they can directly call the methods, but
it is a lot slower for interpreted expressions, since they have to use reflection to call
them.
You can bind functions by creating a holder class with static methods and
annotating everything with `@Binding`, see the example below

<!--@formatter:off-->
```java
Expand All @@ -40,44 +17,10 @@ public class RandomBinding {
// ...
MochaEngine<?> mocha = MochaEngine.createStandard();

mocha.scope().forceSet("random", JavaObjectBinding.of(RandomBinding.class, new RandomBinding()));
mocha.bind(RandomBinding.class);

mocha.compile("random.select(1, 2)").evaluate(); // evaluates to either 1 or 2
// generates the following code:
// return RandomBinding.select(1, 2);
```
<!--@formatter:on-->

### 3. Use both

Mocha allows you to use both approaches so that you can use the best of both worlds.
With this approach, compiled expressions will prefer the Java methods, while interpreted
expressions will prefer the function interfaces.

<!--@formatter:off-->
```java
@Binding("random")
public class RandomBinding implements ObjectValue {
// random.select(a, b)
@Binding("select")
public static double select(double a, double b) {
return Math.random() < 0.5 ? a : b;
}

@Override
public @NotNull Value get(String name) {
if (name.equals("select")) {
return (Function<?>) (ctx, args) ->
NumberValue.of(select(args[0].asDouble(), args[1].asDouble()));
}
return Value.nil();
}
}

mocha.scope().forceSet("random", JavaObjectBinding.of(RandomBinding.class, new RandomBinding()));

mocha.compile("random.select(1, 2)").evaluate(); // uses Java method

mocha.evaluate("random.select(1, 2)"); // uses Function
```
<!--@formatter:on-->

0 comments on commit 496e4f5

Please sign in to comment.