From 71096c7c46178bc23d6e6467b86c05d92fc87cd7 Mon Sep 17 00:00:00 2001 From: MEFRREEX Date: Sat, 4 Jan 2025 10:31:22 +0200 Subject: [PATCH 1/3] docs: added more usage examples --- docs/examples/functions_and_constants.md | 51 ++++++++++++++++++++++ docs/examples/{ => scripts}/file_system.md | 0 docs/examples/using_scriptify.md | 30 +++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 docs/examples/functions_and_constants.md rename docs/examples/{ => scripts}/file_system.md (100%) create mode 100644 docs/examples/using_scriptify.md diff --git a/docs/examples/functions_and_constants.md b/docs/examples/functions_and_constants.md new file mode 100644 index 0000000..e88a137 --- /dev/null +++ b/docs/examples/functions_and_constants.md @@ -0,0 +1,51 @@ +# Custom functions and consultants + +You can register a custom function or constant and then use it in your script + +___ + +Registration of custom functions: +```java +script.getFunctionManager().register(new ScriptFunction() { + @Override + public String getName() { + return "yourFunction"; + } + + @Override + public Object invoke(Script script, Object[] args) { + System.out.println("Invoked custom function with arguments: " + Arrays.toString(args)); + return null; + } +}); +``` + +Registration of custom constants: +```java +script.getConstantManager().register(ScriptConstant.of("yourConstant", "Hello world!")); +``` +or: +```java +script.getConstantManager().register(new ScriptConstant() { + @Override + public String getName() { + return "yourConstant"; + } + + @Override + public Object getValue() { + return "Hello world!"; + } +}); +``` + +___ + +Using custom functions or constants: +```java +yourFunction(yourConstant); +``` +Result: +``` +Invoked custom function with arguments: [Hello world!] +``` \ No newline at end of file diff --git a/docs/examples/file_system.md b/docs/examples/scripts/file_system.md similarity index 100% rename from docs/examples/file_system.md rename to docs/examples/scripts/file_system.md diff --git a/docs/examples/using_scriptify.md b/docs/examples/using_scriptify.md new file mode 100644 index 0000000..fa74a6c --- /dev/null +++ b/docs/examples/using_scriptify.md @@ -0,0 +1,30 @@ +# Using Scriptify + +___ + +### Using JS with GraalVM +```kotlin +implementation "com.instancify.scriptify:script-js-graalvm:1.2.0-SNAPSHOT" +``` +### Using JS with Rhino +```kotlin +implementation "com.instancify.scriptify:script-js-rhino:1.2.0-SNAPSHOT" +``` +___ + +Running the script: +```java +import com.instancify.scriptify.script.JsScript; +import com.instancify.scriptify.core.script.constant.StandardConstantManager; +import com.instancify.scriptify.core.script.function.StandardFunctionManager; + +JsScript script = new JsScript(); +script.setFunctionManager(new StandardFunctionManager()); +script.setConstantManager(new StandardConstantManager()); +script.eval("print('Hello world from JS!')"); +``` + +Running a script from a file: +```java +script.eval(Files.readString(Path.of("./script.js"))); +``` \ No newline at end of file From cc0d978ae0b00258ecffd692c59ad3f659aefab6 Mon Sep 17 00:00:00 2001 From: MEFRREEX Date: Sat, 4 Jan 2025 10:53:03 +0200 Subject: [PATCH 2/3] docs: added docs for creating custom runtime --- docs/examples/custom_script_runtime.md | 117 +++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 docs/examples/custom_script_runtime.md diff --git a/docs/examples/custom_script_runtime.md b/docs/examples/custom_script_runtime.md new file mode 100644 index 0000000..e4200c2 --- /dev/null +++ b/docs/examples/custom_script_runtime.md @@ -0,0 +1,117 @@ +# Custom script runtime + +You can register your script runtime as you do with Rhino or GraalVM + +___ + +### Registration of custom runtime on the example of GraalVM + +Let's create our script: +```java +import com.instancify.scriptify.api.script.Script; +import com.instancify.scriptify.api.script.constant.ScriptConstant; +import com.instancify.scriptify.api.script.constant.ScriptConstantManager; +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.ScriptFunctionManager; +import org.graalvm.polyglot.*; + +public class JsScript implements Script { + + /** + * Creating the runtime engine itself + */ + private final Context context = Context.create(); + + private ScriptFunctionManager functionManager; + private ScriptConstantManager constantManager; + + // Getters and setters for function and constant managers + + @Override + public ScriptFunctionManager getFunctionManager() { + return functionManager; + } + + @Override + public void setFunctionManager(ScriptFunctionManager functionManager) { + this.functionManager = functionManager; + } + + @Override + public ScriptConstantManager getConstantManager() { + return constantManager; + } + + @Override + public void setConstantManager(ScriptConstantManager constantManager) { + this.constantManager = constantManager; + } + + /** + * Function that is called when the script is evaluated. + * + * @param script Script code itself + */ + @Override + public void eval(String script) { + Value bindings = context.getBindings("js"); + + // Add all custom functions and constants to our script. + // It is important to check that the function and constant managers are set, + // because the user may not specify them and then we will get an error when trying to evaluate the script. + + if (functionManager != null) { + for (ScriptFunction function : functionManager.getFunctions().values()) { + bindings.putMember(function.getName(), new JsFunction(this, function)); + } + } + + if (constantManager != null) { + for (ScriptConstant constant : constantManager.getConstants().values()) { + bindings.putMember(constant.getName(), constant.getValue()); + } + } + + // Finally evaluating our script. + context.eval("js", script); + } +} +``` + +Now let's create a function: +```java +import com.instancify.scriptify.api.exception.ScriptFunctionException; +import com.instancify.scriptify.api.script.Script; +import com.instancify.scriptify.api.script.function.ScriptFunction; +import org.graalvm.polyglot.proxy.ProxyExecutable; +import org.graalvm.polyglot.Value; + +public class JsFunction implements ProxyExecutable { + + private final Script script; + private final ScriptFunction function; + + public JsFunction(Script script, ScriptFunction function) { + this.script = script; + this.function = function; + } + + @Override + public Object execute(Value... arguments) { + // Convert Value... into Object[] so that we could pass arguments to our function: + Object[] args = new Object[arguments.length]; + for (int i = 0; i < arguments.length; i++) { + args[i] = arguments[i].as(Object.class); + } + + // Now let's call the function with arguments and handle possible exceptions: + try { + return function.invoke(script, args); + } catch (ScriptFunctionException e) { + throw new RuntimeException(e); + } + } +} +``` + +That's it! We have created JS scripts implementation using GraalVM. You can also write an implementation for any other language you want. \ No newline at end of file From 66d93d065cdd2218939b1b2a49b21d09c313a8df Mon Sep 17 00:00:00 2001 From: MEFRREEX Date: Sat, 4 Jan 2025 12:54:44 +0200 Subject: [PATCH 3/3] docs: update docs for latest api --- docs/examples/custom_script_runtime.md | 4 ++-- docs/examples/functions_and_constants.md | 2 +- docs/examples/using_scriptify.md | 11 ++++++++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/examples/custom_script_runtime.md b/docs/examples/custom_script_runtime.md index e4200c2..64a98a5 100644 --- a/docs/examples/custom_script_runtime.md +++ b/docs/examples/custom_script_runtime.md @@ -99,9 +99,9 @@ public class JsFunction implements ProxyExecutable { @Override public Object execute(Value... arguments) { // Convert Value... into Object[] so that we could pass arguments to our function: - Object[] args = new Object[arguments.length]; + ScriptFunctionArgument[] args = new ScriptFunctionArgument[arguments.length]; for (int i = 0; i < arguments.length; i++) { - args[i] = arguments[i].as(Object.class); + args[i] = ScriptFunctionArgument.of(arguments[i].as(Object.class)); } // Now let's call the function with arguments and handle possible exceptions: diff --git a/docs/examples/functions_and_constants.md b/docs/examples/functions_and_constants.md index e88a137..3831969 100644 --- a/docs/examples/functions_and_constants.md +++ b/docs/examples/functions_and_constants.md @@ -13,7 +13,7 @@ script.getFunctionManager().register(new ScriptFunction() { } @Override - public Object invoke(Script script, Object[] args) { + public Object invoke(Script script, ScriptFunctionArgument[] args) { System.out.println("Invoked custom function with arguments: " + Arrays.toString(args)); return null; } diff --git a/docs/examples/using_scriptify.md b/docs/examples/using_scriptify.md index fa74a6c..ca4451c 100644 --- a/docs/examples/using_scriptify.md +++ b/docs/examples/using_scriptify.md @@ -4,11 +4,11 @@ ___ ### Using JS with GraalVM ```kotlin -implementation "com.instancify.scriptify:script-js-graalvm:1.2.0-SNAPSHOT" +implementation "com.instancify.scriptify:script-js-graalvm:1.3.0-SNAPSHOT" ``` ### Using JS with Rhino ```kotlin -implementation "com.instancify.scriptify:script-js-rhino:1.2.0-SNAPSHOT" +implementation "com.instancify.scriptify:script-js-rhino:1.3.0-SNAPSHOT" ``` ___ @@ -17,11 +17,16 @@ Running the script: import com.instancify.scriptify.script.JsScript; import com.instancify.scriptify.core.script.constant.StandardConstantManager; import com.instancify.scriptify.core.script.function.StandardFunctionManager; +import com.instancify.scriptify.api.exception.ScriptException; JsScript script = new JsScript(); script.setFunctionManager(new StandardFunctionManager()); script.setConstantManager(new StandardConstantManager()); -script.eval("print('Hello world from JS!')"); +try { + script.eval("print('Hello world from JS!')"); +} catch(ScriptException e) { + throw new RuntimeException(e); +} ``` Running a script from a file: