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 961cd26..3944d7a 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/StandardLib.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/StandardLib.java @@ -136,9 +136,13 @@ public class StandardLib { public static DBool contains(DList args) { if (args.size() != 2) throw new IllegalArgumentException("Invalid number of arguments for contains: expected 2 but got " + args.size()); - if (args.get(0) instanceof DList list) return of(list.getValue().contains(args.get(1))); - if (args.get(0) instanceof DObject object) return of(object.getValue().containsKey(args.get(1).asString().getValue())); - else return of(args.get(0).asString().getValue().contains(args.get(1).asString().getValue())); + Dynamic arg0 = args.get(0); + Dynamic arg1 = args.get(1); + boolean contained = false; + contained |= arg0.isList() && arg0.asList().getValue().contains(arg1); + contained |= arg0.isObject() && arg0.asObject().getValue().containsKey(arg1.asString().getValue()); + contained |= arg0.isString() && arg0.asString().getValue().contains(arg1.asString().getValue()); + return of(contained); } public static DString replace(DList args) { @@ -153,15 +157,17 @@ public class StandardLib { public static DNumber len(DList args) { if (args.size() != 1) throw new IllegalArgumentException("Invalid number of arguments for len: expected 1 but got " + args.size()); - if (args.get(0) instanceof DString string) return of(string.getValue().length()); - if (args.get(0) instanceof DObject object) return of(object.getValue().size()); + Dynamic arg0 = args.get(0); + if (arg0.isString()) return of(arg0.asString().getValue().length()); + if (arg0.isObject()) return of(arg0.asObject().getValue().size()); return of(args.get(0).asList().size()); } public static DBool isEmpty(DList args) { if (args.size() != 1) throw new IllegalArgumentException("Invalid number of arguments for isEmpty: expected 1 but got " + args.size()); - if (args.get(0) instanceof DObject object) return of(object.getValue().isEmpty()); - return of(args.get(0).asList().isEmpty()); + Dynamic arg0 = args.get(0); + if (arg0.isObject()) return of(arg0.asObject().getValue().isEmpty()); + return of(arg0.asList().isEmpty()); } public static DList concat(DList args) { diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Get.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Get.java index d9b1a92..de8517f 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Get.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Get.java @@ -32,11 +32,13 @@ public class Get extends DynamicExpr { public Dynamic get(Scope dataRoot) { Dynamic left = this.left.get(dataRoot); if (Dynamic.isNull(left)) throw new LocationalException(location, "Could not get \"" + name.asStringExpr().get(dataRoot) + "\" because left is null"); - if (left instanceof DObject o) { + if (left.isObject()) { + DObject o = left.asObject(); var n = name.asStringExpr().get(dataRoot); if (!o.has(n)) throw new LocationalException(location, "Object does not contain \"" + n + "\""); return o.get(name.asStringExpr().get(dataRoot)); - } else if (left instanceof DList l) { + } else if (left.isList()) { + DList l = left.asList(); int idx = name.asNumberExpr().get(dataRoot).intValue(); if (idx < 0 || idx >= l.size()) throw new LocationalException(location, "Index " + idx + " is out of range for list with size " + l.size()); return l.get(idx); diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/assign/DynamicAssign.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/assign/DynamicAssign.java index 19d1c96..9c2dd6f 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/assign/DynamicAssign.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/assign/DynamicAssign.java @@ -23,7 +23,7 @@ public class DynamicAssign extends DynamicExpr { @Override public Dynamic get(Scope dataRoot) { Dynamic data = value.get(dataRoot); - dataRoot.set(name, data instanceof DCallable callable ? callable.named(name) : data); + dataRoot.set(name, data.isCallable() ? data.asCallable().named(name) : data); return data; } diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/Dynamic.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/Dynamic.java index 9cfca9a..893e201 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/Dynamic.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/Dynamic.java @@ -53,31 +53,55 @@ public sealed interface Dynamic permits DBool, DCallable, DList, DNull, DNumb Expr toExpr(); T getValue(); + default boolean isBool() { + return this instanceof DBool; + } + default DBool asBool() { if (this instanceof DBool bool) return bool; else throw new DynamicTypeConversionException("bool", this); } + default boolean isNumber() { + return this instanceof DNumber; + } + default DNumber asNumber() { if (this instanceof DNumber number) return number; else throw new DynamicTypeConversionException("number", this); } + default boolean isString() { + return this instanceof DString; + } + default DString asString() { if (this instanceof DString string) return string; else return DFinal.of(StringFormatter.toString(getValue())); } + default boolean isObject() { + return this instanceof DObject; + } + default DObject asObject() { if (this instanceof DObject object) return object; else throw new DynamicTypeConversionException("object", this); } + default boolean isList() { + return this instanceof DList; + } + default DList asList() { if (this instanceof DList list) return list; else throw new DynamicTypeConversionException("list", this); } + default boolean isCallable() { + return this instanceof DCallable; + } + default DCallable asCallable() { if (this instanceof DCallable callable) return callable; else throw new DynamicTypeConversionException("callable", this); diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/additional/DCallableObject.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/additional/DCallableObject.java index 1370673..f4c1353 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/additional/DCallableObject.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/additional/DCallableObject.java @@ -14,6 +14,11 @@ public record DCallableObject(Map> value, DCallable return value; } + @Override + public boolean isCallable() { + return true; + } + @Override public DCallable asCallable() { return callable; diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/additional/DDate.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/additional/DDate.java index f05644c..2e48972 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/additional/DDate.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/additional/DDate.java @@ -24,11 +24,21 @@ public record DDate(Supplier date) implements DObject { ); } + @Override + public boolean isString() { + return true; + } + @Override public DString asString() { return DFinal.of(toString()); } + @Override + public boolean isNumber() { + return true; + } + @Override public DNumber asNumber() { return DFinal.of(date.get().toEpochDay()); diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/additional/DEnum.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/additional/DEnum.java index 0b39bd1..c76a9d6 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/additional/DEnum.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/additional/DEnum.java @@ -37,16 +37,31 @@ public record DEnum(Map> values, @Nullable DEnumEnt return values; } + @Override + public boolean isList() { + return true; + } + @Override public DList asList() { return DFinal.of(List.copyOf(values.values())); } + @Override + public boolean isString() { + return true; + } + @Override public DString asString() { return value != null ? value : DFinal.of(StringFormatter.toString(values)); } + @Override + public boolean isNumber() { + return true; + } + @Override public DNumber asNumber() { return value != null ? value.asNumber() : DObject.super.asNumber(); @@ -76,11 +91,21 @@ public record DEnum(Map> values, @Nullable DEnumEnt return value; } + @Override + public boolean isNumber() { + return true; + } + @Override public DNumber asNumber() { return DFinal.of(index); } + @Override + public boolean isBool() { + return true; + } + @Override public DBool asBool() { return DFinal.of(selected); diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/additional/DTime.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/additional/DTime.java index 52ad5b9..33dfc1f 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/additional/DTime.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/data/dynamic/additional/DTime.java @@ -24,11 +24,21 @@ public record DTime(Supplier time) implements DObject { ); } + @Override + public boolean isString() { + return true; + } + @Override public DString asString() { return DFinal.of(toString()); } + @Override + public boolean isNumber() { + return true; + } + @Override public DNumber asNumber() { return DFinal.of(time.get().toSecondOfDay());