diff --git a/muscript/README.md b/muscript/README.md index cb47309..5264e26 100644 --- a/muscript/README.md +++ b/muscript/README.md @@ -89,7 +89,7 @@ one by calling `as(Bool|String|Number|Dynamic)Expr`. This process may throw a ParseException. You may also use `Parser.parseScript(String script)` for multi-expression scripts. You can call `get(Dynamic dataRoot)` on the result to execute the script on the provided data, which should be a -`Scope` on which you called `StandardLib.addTo()` to add standard methods. +`Scope` which you created with `StandardLib.createScope()` to add standard methods. This is also where you can add custom data to be accessed by your script. The execution of a script can throw a LocationalException which may be converted to a LocationalError for printing using the source of the expression if available. @@ -98,32 +98,36 @@ You may also call `StarScriptIngester.starScriptToMu()` to generate μScript cod A full example could look as follows: ```java -String source = args[0]; -Expr parsed; -try { - parsed = Parser.parse(source); // or Parser.parse(StarScriptIngester.starScriptToMu(source)) -} catch (Parser.ParseException e) { // Could not parse - System.err.println(e.error); - return; +public class Example { + public static void main(String[] args) { + String source = String.join(" ", args); + Expr parsed; + try { + parsed = Parser.parse(source); // or Parser.parse(StarScriptIngester.starScriptToMu(source)) + } catch (Parser.ParseException e) { // Could not parse + System.err.println(e.error); + return; + } + BoolExpr typed; + try { + typed = parsed.asBoolExpr(); + } catch (LocationalException e) { + System.err.println(e.asPrintable(source)); + return; + } + Scope scope = StandardLib.createScope() + .set("someValue", 15) + .set("someOther", Map.of( + "subValue", DFinal.of(true) + )); + boolean result; + try { + result = typed.get(parameter); + } catch (LocationalException e) { + System.err.println(e.asPrintable(source)); + return; + } + System.out.println("Result: " + result); + } } -BoolExpr typed; -try { - typed = parsed.asBoolExpr(); -} catch (LocationalException e) { - System.err.println(e.asPrintable(source)); - return; -} -Scope scope = StandardLib.addTo(new Scope()) - .set("someValue", DFinal.of(15)) - .set("someOther", DFinal.of(Map.of( - "subValue", DFinal.of(true) - ))); -boolean result; -try { - result = typed.get(parameter); -} catch (LocationalException e) { - System.err.println(e.asPrintable(source)); - return; -} -System.out.println("Result: " + result); ``` diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/StandardLib.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/StandardLib.java index 01d9c95..1450136 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/StandardLib.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/StandardLib.java @@ -15,24 +15,28 @@ public class StandardLib { public static final SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm"); public static final SimpleDateFormat dateFormat = new SimpleDateFormat("dd. MM. yyyy"); + public static Scope createScope() { + return addTo(new Scope()); + } + public static Scope addTo(Scope scope) { return scope - .set("PI", of(Math.PI)) - .set("time", of(timeFormat.format(new Date()))) - .set("date", of(dateFormat.format(new Date()))) + .set("PI", Math.PI) + .set("time", timeFormat.format(new Date())) + .set("date", dateFormat.format(new Date())) - .set("round", of(StandardLib::round)) - .set("floor", of(StandardLib::floor)) - .set("ceil", of(StandardLib::ceil)) - .set("abs", of(StandardLib::abs)) - .set("random", of(StandardLib::random)) + .set("round", StandardLib::round) + .set("floor", StandardLib::floor) + .set("ceil", StandardLib::ceil) + .set("abs", StandardLib::abs) + .set("random", StandardLib::random) - .set("toUpper", of(StandardLib::toUpper)) - .set("toLower", of(StandardLib::toLower)) - .set("contains", of(StandardLib::contains)) - .set("replace", of(StandardLib::replace)) + .set("toUpper", StandardLib::toUpper) + .set("toLower", StandardLib::toLower) + .set("contains", StandardLib::contains) + .set("replace", StandardLib::replace) - .set("listOf", of(StandardLib::listOf)); + .set("listOf", StandardLib::listOf); } // Numbers diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Closure.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Closure.java index 6e87922..801961b 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Closure.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Closure.java @@ -39,9 +39,9 @@ public class Closure extends DynamicExpr { Scope fork = dataRoot.fork(); for (int i = 0; i < ae; i++) fork.set(boundArgs.get(i), args.get(i)); if (variadic) { - fork.set(boundArgs.get(boundArgs.size() - 1), DFinal.of(IntStream.range(ae, ac) - .mapToObj(args::get) - .toArray(Dynamic[]::new))); + fork.set(boundArgs.get(boundArgs.size() - 1), IntStream.range(ae, ac) + .>mapToObj(args::get) + .toList()); } for (Expr step : steps) { step.get(fork); diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/data/Scope.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/data/Scope.java index ecc7d0e..96395ac 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/data/Scope.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/data/Scope.java @@ -3,8 +3,8 @@ package io.gitlab.jfronny.muscript.data; import io.gitlab.jfronny.commons.data.ImmCollection; import io.gitlab.jfronny.muscript.data.dynamic.*; -import java.util.HashMap; -import java.util.Map; +import java.util.*; +import java.util.function.Function; public class Scope implements DObject { private final DObject source; @@ -25,11 +25,39 @@ public class Scope implements DObject { return ImmCollection.of(map); } + /** + * @deprecated Using the convenience methods is recommended wherever possible. + */ + @Deprecated(forRemoval = false) public Scope set(String key, Dynamic value) { override.put(key, value); return this; } + public Scope set(String key, boolean value) { + return set(key, DFinal.of(value)); + } + + public Scope set(String key, double value) { + return set(key, DFinal.of(value)); + } + + public Scope set(String key, String value) { + return set(key, DFinal.of(value)); + } + + public Scope set(String key, Map> value) { + return set(key, DFinal.of(value)); + } + + public Scope set(String key, List> value) { + return set(key, DFinal.of(value)); + } + + public Scope set(String key, Function> value) { + return set(key, DFinal.of(value)); + } + public Scope fork() { return new Scope(this); } diff --git a/muscript/src/test/java/io/gitlab/jfronny/muscript/test/util/MuTestUtil.java b/muscript/src/test/java/io/gitlab/jfronny/muscript/test/util/MuTestUtil.java index 92d3ffb..02ae955 100644 --- a/muscript/src/test/java/io/gitlab/jfronny/muscript/test/util/MuTestUtil.java +++ b/muscript/src/test/java/io/gitlab/jfronny/muscript/test/util/MuTestUtil.java @@ -2,8 +2,6 @@ package io.gitlab.jfronny.muscript.test.util; import io.gitlab.jfronny.muscript.StandardLib; import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.DObject; -import io.gitlab.jfronny.muscript.data.dynamic.Dynamic; import io.gitlab.jfronny.muscript.compiler.Parser; import io.gitlab.jfronny.muscript.ast.Expr; import io.gitlab.jfronny.muscript.debug.ObjectGraphPrinter; @@ -36,25 +34,24 @@ public class MuTestUtil { } public static Scope makeArgs() { - return StandardLib.addTo(new Scope(of(Map.of( - "boolean", of(true), - "number", of(15), - "string", of("Value"), - "object", of(Map.of( + return StandardLib.createScope() + .set("boolean", true) + .set("number", 15) + .set("string", "Value") + .set("object", Map.of( "subvalue", of(1024), "subfunc", of(v -> of(v.get(1).asNumber().getValue() * v.size())), "1", of("One") - )), - "object2", of(Map.of( + )) + .set("object2", Map.of( "valuename", of("subvalue"), "sub", of(Map.of( "val", of(10) )), "stringfunc", of(v -> of(v.get(0).asString().getValue())) - )), - "list", of(of(true), of(2), of("3")), - "function", of(v -> of(Math.pow(v.get(0).asNumber().getValue(), v.get(1).asNumber().getValue()))), - "repeatArgs", of(v -> makeArgs()) - )))); + )) + .set("list", of(of(true), of(2), of("3"))) + .set("function", v -> of(Math.pow(v.get(0).asNumber().getValue(), v.get(1).asNumber().getValue()))) + .set("repeatArgs", v -> makeArgs()); } }