feat(muscript): is* methods for dynamic to replace fragile instanceof checks for multi-representational values
ci/woodpecker/push/woodpecker Pipeline was successful Details

This commit is contained in:
Johannes Frohnmeyer 2023-08-14 16:12:08 +02:00
parent 935d6f9cf6
commit b41019c89d
Signed by: Johannes
GPG Key ID: E76429612C2929F4
8 changed files with 92 additions and 10 deletions

View File

@ -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) {

View File

@ -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);

View File

@ -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;
}

View File

@ -53,31 +53,55 @@ public sealed interface Dynamic<T> 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);

View File

@ -14,6 +14,11 @@ public record DCallableObject(Map<String, ? extends Dynamic<?>> value, DCallable
return value;
}
@Override
public boolean isCallable() {
return true;
}
@Override
public DCallable asCallable() {
return callable;

View File

@ -24,11 +24,21 @@ public record DDate(Supplier<LocalDate> 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());

View File

@ -37,16 +37,31 @@ public record DEnum(Map<String, ? extends Dynamic<?>> 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<String, ? extends Dynamic<?>> 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);

View File

@ -24,11 +24,21 @@ public record DTime(Supplier<LocalTime> 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());