feat(muscript): additional data
This commit is contained in:
parent
55b3b4cbe0
commit
933a642dc3
|
@ -0,0 +1,33 @@
|
|||
import io.gitlab.jfronny.scripts.*
|
||||
|
||||
plugins {
|
||||
commons.library
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.commons)
|
||||
api(projects.muscriptCore)
|
||||
api(projects.muscriptDataDynamic)
|
||||
api(projects.muscriptAst)
|
||||
|
||||
testImplementation(libs.junit.jupiter.api)
|
||||
testRuntimeOnly(libs.junit.jupiter.engine)
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
create<MavenPublication>("maven") {
|
||||
groupId = "io.gitlab.jfronny"
|
||||
artifactId = "muscript-data-additional"
|
||||
|
||||
from(components["java"])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.javadoc {
|
||||
linksOffline("https://maven.frohnmeyer-wds.de/javadoc/artifacts/io/gitlab/jfronny/commons/$version/raw", projects.commons)
|
||||
linksOffline("https://maven.frohnmeyer-wds.de/javadoc/artifacts/io/gitlab/jfronny/muscript-core/$version/raw", projects.muscriptCore)
|
||||
linksOffline("https://maven.frohnmeyer-wds.de/javadoc/artifacts/io/gitlab/jfronny/muscript-data-dynamic/$version/raw", projects.muscriptDataDynamic)
|
||||
linksOffline("https://maven.frohnmeyer-wds.de/javadoc/artifacts/io/gitlab/jfronny/muscript-ast/$version/raw", projects.muscriptAst)
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package io.gitlab.jfronny.muscript.data.additional;
|
||||
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.DCallable;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.DObject;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.context.DynamicSerializer;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.lens.DCallableLens;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.type.DType;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.type.DTypeAnd;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.type.DTypeObject;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public record DCallableObject(Map<String, ? extends Dynamic> value, DTypeObject objectSignature, DCallable callable) implements DObject {
|
||||
public DCallableObject(Map<String, ? extends Dynamic> value, DCallable callable) {
|
||||
this(value, new DTypeObject(null), callable);
|
||||
}
|
||||
|
||||
public DCallableObject {
|
||||
Objects.requireNonNull(value);
|
||||
Objects.requireNonNull(objectSignature);
|
||||
Objects.requireNonNull(callable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ? extends Dynamic> getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCallable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DCallable asCallable() {
|
||||
return new DCallableLens(this, callable::getValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DType getSignature() {
|
||||
return new DTypeAnd(Set.of(objectSignature, callable.getSignature()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return DynamicSerializer.INSTANCE.serialize(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package io.gitlab.jfronny.muscript.data.additional;
|
||||
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.DynamicBase;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.context.DynamicSerializer;
|
||||
|
||||
public abstract class DContainer<T> implements DynamicBase {
|
||||
private T value;
|
||||
|
||||
@Override
|
||||
public T getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public T setValue(T value) {
|
||||
if (value != null)
|
||||
this.value = value;
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return DynamicSerializer.INSTANCE.serialize(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package io.gitlab.jfronny.muscript.data.additional;
|
||||
|
||||
import io.gitlab.jfronny.muscript.ast.DynamicExpr;
|
||||
import io.gitlab.jfronny.muscript.ast.dynamic.Call;
|
||||
import io.gitlab.jfronny.muscript.ast.dynamic.Variable;
|
||||
import io.gitlab.jfronny.muscript.ast.number.NumberLiteral;
|
||||
import io.gitlab.jfronny.muscript.core.CodeLocation;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.DNumber;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.DObject;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.DString;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.lens.DNumberLens;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.lens.DStringLens;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.type.DType;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static io.gitlab.jfronny.muscript.ast.context.ExprUtils.asDynamic;
|
||||
import static io.gitlab.jfronny.muscript.data.dynamic.type.DSL.*;
|
||||
|
||||
public record DDate(Supplier<LocalDate> date) implements DObject {
|
||||
public static final DType SIGNATURE = object(NUMBER).or(STRING).or(NUMBER);
|
||||
|
||||
@Override
|
||||
public Map<String, Dynamic> getValue() {
|
||||
return Map.of(
|
||||
"year", DFinal.of(date.get().getYear()),
|
||||
"month", DFinal.of(date.get().getMonthValue()),
|
||||
"day", DFinal.of(date.get().getDayOfMonth())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isString() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DString asString() {
|
||||
return new DStringLens(this, this::toString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNumber() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DNumber asNumber() {
|
||||
return new DNumberLens(this, () -> date.get().toEpochDay());
|
||||
}
|
||||
|
||||
public DynamicExpr toExpr() {
|
||||
return new Call(CodeLocation.NONE, new Variable(CodeLocation.NONE, "date"), List.of(
|
||||
new Call.Argument(asDynamic(new NumberLiteral(CodeLocation.NONE, date.get().getYear())), false),
|
||||
new Call.Argument(asDynamic(new NumberLiteral(CodeLocation.NONE, date.get().getMonthValue())), false),
|
||||
new Call.Argument(asDynamic(new NumberLiteral(CodeLocation.NONE, date.get().getDayOfMonth())), false)
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DType getSignature() {
|
||||
return SIGNATURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return date.get().toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package io.gitlab.jfronny.muscript.data.additional;
|
||||
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.DList;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.DObject;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.lens.DListLens;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public enum DEmpty implements DObject {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ? extends Dynamic> getValue() {
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isList() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DList asList() {
|
||||
return new DListLens(this, List::of);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
package io.gitlab.jfronny.muscript.data.additional;
|
||||
|
||||
import io.gitlab.jfronny.commons.StringFormatter;
|
||||
import io.gitlab.jfronny.commons.data.ImmCollection;
|
||||
import io.gitlab.jfronny.muscript.ast.DynamicExpr;
|
||||
import io.gitlab.jfronny.muscript.ast.dynamic.Call;
|
||||
import io.gitlab.jfronny.muscript.ast.dynamic.Variable;
|
||||
import io.gitlab.jfronny.muscript.ast.string.StringLiteral;
|
||||
import io.gitlab.jfronny.muscript.core.CodeLocation;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.*;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.lens.DBoolLens;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.lens.DListLens;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.lens.DNumberLens;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.lens.DStringLens;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.type.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An enum represented as an OObject.
|
||||
* May also have a selected value with automatic conversions to a number (index) and string
|
||||
*/
|
||||
public record DEnum(Map<String, ? extends Dynamic> values, @Nullable DEnumEntry value, @Nullable DType valueSignature) implements DObject {
|
||||
public DEnum(Map<String, ? extends Dynamic> values) {
|
||||
this(null, values);
|
||||
}
|
||||
|
||||
public DEnum(DType valueSignature, Map<String, ? extends Dynamic> values) {
|
||||
this(values, null, valueSignature);
|
||||
}
|
||||
|
||||
public DEnum(Map<String, ? extends Dynamic> values, @Nullable String value) {
|
||||
this(null, values, value);
|
||||
}
|
||||
|
||||
public DEnum(DType valueSignature, Map<String, ? extends Dynamic> values, @Nullable String value) {
|
||||
this(values, value == null ? null : new DEnumEntry(value, values.keySet().stream().toList().indexOf(value), true), valueSignature);
|
||||
}
|
||||
|
||||
public DEnum(List<String> values, String value) {
|
||||
this(createMap(values, value), value == null ? null : new DEnumEntry(value, values.indexOf(value), true), DTypePrimitive.STRING);
|
||||
}
|
||||
|
||||
public DEnum(List<String> values) {
|
||||
this(values, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ? extends Dynamic> getValue() {
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isList() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DList asList() {
|
||||
return new DListLens(this, () -> List.copyOf(values.values()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isString() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DString asString() {
|
||||
return value != null ? value : new DStringLens(this, () -> StringFormatter.toString(values));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNumber() {
|
||||
return value != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DNumber asNumber() {
|
||||
return value != null ? new DNumberLens(this, value::index) : DObject.super.asNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DType getSignature() {
|
||||
Set<DType> types = new HashSet<>();
|
||||
types.add(new DTypeObject(valueSignature));
|
||||
types.add(new DTypeList(valueSignature));
|
||||
types.add(DTypePrimitive.STRING);
|
||||
if (value != null) types.add(DTypePrimitive.NUMBER);
|
||||
return new DTypeAnd(types);
|
||||
}
|
||||
|
||||
private static Map<String, Dynamic> createMap(List<String> values, String value) {
|
||||
Map<String, Dynamic> result = new LinkedHashMap<>();
|
||||
DEnumEntry v = new DEnumEntry(value, values.indexOf(value), true);
|
||||
result.put("value", v);
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
result.put(values.get(i), new DEnumEntry(values.get(i), i, values.get(i).equals(value)));
|
||||
}
|
||||
return ImmCollection.of(result);
|
||||
}
|
||||
|
||||
public record DEnumEntry(String value, int index, boolean selected) implements DString {
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNumber() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DNumber asNumber() {
|
||||
return new DNumberLens(this, this::index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBool() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DBool asBool() {
|
||||
return new DBoolLens(this, this::selected);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
package io.gitlab.jfronny.muscript.data.additional;
|
||||
|
||||
import io.gitlab.jfronny.commons.LazySupplier;
|
||||
import io.gitlab.jfronny.commons.StringFormatter;
|
||||
import io.gitlab.jfronny.commons.data.ImmCollection;
|
||||
import io.gitlab.jfronny.muscript.ast.Expr;
|
||||
import io.gitlab.jfronny.muscript.ast.context.IExprParser;
|
||||
import io.gitlab.jfronny.muscript.ast.dynamic.Variable;
|
||||
import io.gitlab.jfronny.muscript.core.CodeLocation;
|
||||
import io.gitlab.jfronny.muscript.data.additional.context.DynamicBasePlus;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.*;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.context.DynamicSerializer;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.type.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class DFinal {
|
||||
public static DBool of(boolean b) {
|
||||
return new FBool(b);
|
||||
}
|
||||
|
||||
public static DNumber of(double b) {
|
||||
return new FNumber(b);
|
||||
}
|
||||
|
||||
public static DString of(String b) {
|
||||
return new FString(b);
|
||||
}
|
||||
|
||||
public static DObject of(Map<String, ? extends Dynamic> b) {
|
||||
return of(new DTypeObject(null), b);
|
||||
}
|
||||
|
||||
public static DObject of(DTypeObject signature, Map<String, ? extends Dynamic> b) {
|
||||
return new FObject(ImmCollection.copyOf((Map<String, Dynamic>) b), Objects.requireNonNull(signature));
|
||||
}
|
||||
|
||||
public static DList of(Dynamic... b) {
|
||||
return of(new DTypeList(null), b);
|
||||
}
|
||||
|
||||
public static DList of(DTypeList signature, Dynamic... b) {
|
||||
return new FList(List.of(b), Objects.requireNonNull(signature));
|
||||
}
|
||||
|
||||
public static DList of(List<? extends Dynamic> b) {
|
||||
return of(new DTypeList(null), b);
|
||||
}
|
||||
|
||||
public static DList of(DTypeList signature, List<? extends Dynamic> b) {
|
||||
return new FList(ImmCollection.copyOf((List<Dynamic>) b), Objects.requireNonNull(signature));
|
||||
}
|
||||
|
||||
public static DCallable of(Function<DList, ? extends Dynamic> b, Supplier<String> serialized) {
|
||||
return of(new DTypeCallable(null, null), b, Objects.requireNonNull(serialized));
|
||||
}
|
||||
|
||||
public static DCallable of(DType signature, Function<DList, ? extends Dynamic> b, Supplier<String> serialized) {
|
||||
return of(Objects.requireNonNull(signature), b, serialized, null);
|
||||
}
|
||||
|
||||
public static DCallable of(Function<DList, ? extends Dynamic> b, String name) {
|
||||
return of(new DTypeCallable(null, null), b, name);
|
||||
}
|
||||
|
||||
public static DCallable of(DType signature, Function<DList, ? extends Dynamic> b, String name) {
|
||||
return of(Objects.requireNonNull(signature), name, b, () -> new Variable(CodeLocation.NONE, name));
|
||||
}
|
||||
|
||||
public static DCallable of(Function<DList, ? extends Dynamic> b, Supplier<String> serialized, String name) {
|
||||
return of(new DTypeCallable(null, null), b, serialized, name);
|
||||
}
|
||||
|
||||
public static DCallable of(DType signature, Function<DList, ? extends Dynamic> b, Supplier<String> serialized, String name) {
|
||||
return of(Objects.requireNonNull(signature), name, b, () -> IExprParser.INSTANCE.parse(serialized.get()));
|
||||
}
|
||||
|
||||
public static DCallable of(String name, Function<DList, ? extends Dynamic> b, Supplier<Expr> serialized) {
|
||||
return of(new DTypeCallable(null, null), name, b, serialized);
|
||||
}
|
||||
|
||||
public static DCallable of(DType signature, String name, Function<DList, ? extends Dynamic> b, Supplier<Expr> serialized) {
|
||||
return new FCallable((Function<DList, Dynamic>) b, new LazySupplier<>(serialized), name, Objects.requireNonNull(signature));
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks all DFinal implementation classes. Use this in instanceof checks
|
||||
*/
|
||||
public sealed interface FImpl {
|
||||
}
|
||||
|
||||
private record FBool(boolean value) implements DBool, FImpl {
|
||||
@Override
|
||||
public Boolean getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return StringFormatter.toString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DType getSignature() {
|
||||
return DTypePrimitive.BOOL;
|
||||
}
|
||||
}
|
||||
|
||||
private record FNumber(double value) implements DNumber, FImpl {
|
||||
@Override
|
||||
public Double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return StringFormatter.toStringPrecise(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DType getSignature() {
|
||||
return DTypePrimitive.NUMBER;
|
||||
}
|
||||
}
|
||||
|
||||
private record FString(String value) implements DString, FImpl {
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return DynamicSerializer.INSTANCE.serialize(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DType getSignature() {
|
||||
return DTypePrimitive.STRING;
|
||||
}
|
||||
}
|
||||
|
||||
private record FObject(Map<String, Dynamic> value, DTypeObject signature) implements DObject, FImpl {
|
||||
@Override
|
||||
public Map<String, Dynamic> getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return DynamicSerializer.INSTANCE.serialize(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DType getSignature() {
|
||||
return signature;
|
||||
}
|
||||
}
|
||||
|
||||
private record FList(List<Dynamic> value, DTypeList signature) implements DList, FImpl {
|
||||
@Override
|
||||
public List<Dynamic> getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DType getSignature() {
|
||||
return signature;
|
||||
}
|
||||
}
|
||||
|
||||
private record FCallable(Function<DList, Dynamic> value, Supplier<Expr> gen, String name, DType signature) implements DCallable, FImpl, DynamicBasePlus {
|
||||
@Override
|
||||
public Expr toExpr() {
|
||||
return gen.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function<DList, Dynamic> getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toExpr().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name == null ? DCallable.super.getName() : name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DCallable named(String name) {
|
||||
return new FCallable(value, gen, name, signature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DType getSignature() {
|
||||
return signature;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package io.gitlab.jfronny.muscript.data.additional;
|
||||
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.DNumber;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.DObject;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.DString;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.lens.DNumberLens;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.lens.DStringLens;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.type.DType;
|
||||
|
||||
import java.time.LocalTime;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static io.gitlab.jfronny.muscript.data.dynamic.type.DSL.*;
|
||||
|
||||
public record DTime(Supplier<LocalTime> time) implements DObject {
|
||||
public static final DType SIGNATURE = object(NUMBER).or(STRING).or(NUMBER);
|
||||
|
||||
@Override
|
||||
public Map<String, Dynamic> getValue() {
|
||||
return Map.of(
|
||||
"hour", DFinal.of(time.get().getHour()),
|
||||
"minute", DFinal.of(time.get().getMinute()),
|
||||
"second", DFinal.of(time.get().getSecond())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isString() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DString asString() {
|
||||
return new DStringLens(this, this::toString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNumber() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DNumber asNumber() {
|
||||
return new DNumberLens(this, () -> time.get().toSecondOfDay());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DType getSignature() {
|
||||
return SIGNATURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return time.get().toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package io.gitlab.jfronny.muscript.data.additional;
|
||||
|
||||
import io.gitlab.jfronny.muscript.ast.Expr;
|
||||
import io.gitlab.jfronny.muscript.data.additional.impl.DataExprMappingDefault;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.Dynamic;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class DataExprMapper {
|
||||
public static @Nullable Expr map(Dynamic dynamic) {
|
||||
for (Mapping mapping : Mapping.MAPPINGS) {
|
||||
Expr expr = mapping.map(dynamic);
|
||||
if (expr != null) {
|
||||
return expr;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public interface Mapping {
|
||||
List<Mapping> MAPPINGS = Stream.concat(
|
||||
ServiceLoader.load(Mapping.class).stream().map(ServiceLoader.Provider::get),
|
||||
Stream.of(new DataExprMappingDefault())
|
||||
).toList();
|
||||
|
||||
@Nullable Expr map(Dynamic dynamic);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package io.gitlab.jfronny.muscript.data.additional;
|
||||
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.*;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.type.DType;
|
||||
|
||||
public interface DelegateDynamic extends DynamicBase {
|
||||
Dynamic getDelegate();
|
||||
|
||||
@Override
|
||||
default Object getValue() {
|
||||
return getDelegate().getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isBool() {
|
||||
return getDelegate().isBool();
|
||||
}
|
||||
|
||||
@Override
|
||||
default DBool asBool() {
|
||||
return getDelegate().asBool();
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isNumber() {
|
||||
return getDelegate().isNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
default DNumber asNumber() {
|
||||
return getDelegate().asNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isString() {
|
||||
return getDelegate().isString();
|
||||
}
|
||||
|
||||
@Override
|
||||
default DString asString() {
|
||||
return getDelegate().asString();
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isObject() {
|
||||
return getDelegate().isObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
default DObject asObject() {
|
||||
return getDelegate().asObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isList() {
|
||||
return getDelegate().isList();
|
||||
}
|
||||
|
||||
@Override
|
||||
default DList asList() {
|
||||
return getDelegate().asList();
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isCallable() {
|
||||
return getDelegate().isCallable();
|
||||
}
|
||||
|
||||
@Override
|
||||
default DCallable asCallable() {
|
||||
return getDelegate().asCallable();
|
||||
}
|
||||
|
||||
@Override
|
||||
default DType getSignature() {
|
||||
return getDelegate().getSignature();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package io.gitlab.jfronny.muscript.data.additional.context;
|
||||
|
||||
import io.gitlab.jfronny.muscript.ast.Expr;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.DynamicBase;
|
||||
|
||||
public interface DynamicBasePlus extends DynamicBase {
|
||||
Expr toExpr();
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package io.gitlab.jfronny.muscript.data.additional.impl;
|
||||
|
||||
import io.gitlab.jfronny.muscript.ast.DynamicExpr;
|
||||
import io.gitlab.jfronny.muscript.ast.Expr;
|
||||
import io.gitlab.jfronny.muscript.ast.NullLiteral;
|
||||
import io.gitlab.jfronny.muscript.ast.bool.BoolLiteral;
|
||||
import io.gitlab.jfronny.muscript.ast.dynamic.Bind;
|
||||
import io.gitlab.jfronny.muscript.ast.dynamic.Call;
|
||||
import io.gitlab.jfronny.muscript.ast.dynamic.ObjectLiteral;
|
||||
import io.gitlab.jfronny.muscript.ast.dynamic.Variable;
|
||||
import io.gitlab.jfronny.muscript.ast.number.NumberLiteral;
|
||||
import io.gitlab.jfronny.muscript.ast.string.StringLiteral;
|
||||
import io.gitlab.jfronny.muscript.core.CodeLocation;
|
||||
import io.gitlab.jfronny.muscript.data.additional.*;
|
||||
import io.gitlab.jfronny.muscript.data.additional.context.DynamicBasePlus;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.*;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.lens.DLens;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static io.gitlab.jfronny.muscript.ast.context.ExprUtils.asDynamic;
|
||||
import static io.gitlab.jfronny.muscript.data.additional.DataExprMapper.*;
|
||||
|
||||
public class DataExprMappingDefault implements Mapping {
|
||||
@Override
|
||||
public @Nullable Expr map(Dynamic dynamic) {
|
||||
return switch (dynamic) {
|
||||
case DynamicBasePlus base -> base.toExpr();
|
||||
case DLens lens -> DataExprMapper.map(lens.getSource());
|
||||
case DCallableObject dco -> new Call(CodeLocation.NONE, new Bind(CodeLocation.NONE, new Variable(CodeLocation.NONE, "callableObject"), convertObjectSimple(dco)), List.of(new Call.Argument(asDynamic(DataExprMapper.map(dco.callable())), false)));
|
||||
case DDate date -> new Call(CodeLocation.NONE, new Variable(CodeLocation.NONE, "date"), List.of(
|
||||
new Call.Argument(asDynamic(new NumberLiteral(CodeLocation.NONE, date.date().get().getYear())), false),
|
||||
new Call.Argument(asDynamic(new NumberLiteral(CodeLocation.NONE, date.date().get().getMonthValue())), false),
|
||||
new Call.Argument(asDynamic(new NumberLiteral(CodeLocation.NONE, date.date().get().getDayOfMonth())), false)
|
||||
));
|
||||
case DTime time -> new Call(CodeLocation.NONE, new Variable(CodeLocation.NONE, "time"), List.of(
|
||||
new Call.Argument(asDynamic(new NumberLiteral(CodeLocation.NONE, time.time().get().getHour())), false),
|
||||
new Call.Argument(asDynamic(new NumberLiteral(CodeLocation.NONE, time.time().get().getMinute())), false),
|
||||
new Call.Argument(asDynamic(new NumberLiteral(CodeLocation.NONE, time.time().get().getSecond())), false)
|
||||
));
|
||||
case DEnum enm -> convertEnum(enm);
|
||||
case NamedDCallable(var inner, var name) -> DataExprMapper.map(inner);
|
||||
case DelegateDynamic delegate -> DataExprMapper.map(delegate.getDelegate());
|
||||
case DBool bool -> new BoolLiteral(CodeLocation.NONE, bool.getValue());
|
||||
case DList list -> new Call(CodeLocation.NONE, new Variable(CodeLocation.NONE, "listOf"), list.getValue().stream().map(s -> new Call.Argument(asDynamic(DataExprMapper.map(s)), false)).toList());
|
||||
case DNull nul -> new NullLiteral(CodeLocation.NONE);
|
||||
case DNumber number -> new NumberLiteral(CodeLocation.NONE, number.getValue());
|
||||
case DObject object -> convertObjectSimple(object);
|
||||
case DString string -> new StringLiteral(CodeLocation.NONE, string.getValue());
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
private static DynamicExpr convertObjectSimple(DObject object) {
|
||||
return new ObjectLiteral(CodeLocation.NONE, object.getValue().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, s -> asDynamic(DataExprMapper.map(s.getValue())))));
|
||||
}
|
||||
|
||||
private static DynamicExpr convertEnum(DEnum enm) {
|
||||
List<Call.Argument> args = new LinkedList<>();
|
||||
args.add(new Call.Argument(convertObjectSimple(enm), false));
|
||||
if (enm.value() != null) args.add(new Call.Argument(asDynamic(new StringLiteral(CodeLocation.NONE, enm.value().value())), false));
|
||||
return new Call(CodeLocation.NONE, new Variable(CodeLocation.NONE, "enum"), args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package io.gitlab.jfronny.muscript.data.additional.impl;
|
||||
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.Dynamic;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collection;
|
||||
|
||||
public class ObjectGraphPrinter {
|
||||
public static String printGraph(Object o) throws IllegalAccessException {
|
||||
if (o == null) return "null";
|
||||
StringBuilder builder = new StringBuilder();
|
||||
IndentingWriter writer = new IndentingWriter(builder, "");
|
||||
writer.writeLine("[" + o.getClass().getSimpleName() + "]");
|
||||
printGraph(writer.level(), o, o.getClass());
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private static void printGraph(IndentingWriter writer, Object o, Class<?> klazz) throws IllegalAccessException {
|
||||
for (Field field : klazz.getDeclaredFields()) {
|
||||
if (Modifier.isStatic(field.getModifiers())) continue;
|
||||
field.setAccessible(true);
|
||||
Object fo = field.get(o);
|
||||
if (fo == null) {
|
||||
writer.writeLine(field.getName() + " [" + field.getType().getSimpleName() + "]: null");
|
||||
continue;
|
||||
}
|
||||
Class<?> kz = fo.getClass();
|
||||
String name = field.getName() + " [" + kz.getSimpleName() + "]";
|
||||
if (kz.isEnum()) {
|
||||
writer.writeLine(name + " = " + fo);
|
||||
} else if (kz.isAssignableFrom(String.class)) {
|
||||
writer.writeLine(name + " = \"" + fo + "\"");
|
||||
} else if (kz.isAssignableFrom(Double.class)) {
|
||||
writer.writeLine(name + " = " + fo);
|
||||
} else if (kz.isAssignableFrom(Dynamic.class)) {
|
||||
writer.writeLine(name + " = " + fo);
|
||||
} else if (kz.isAssignableFrom(Collection.class)) {
|
||||
writer.writeLine(name + ":");
|
||||
for (Object element : (Collection<?>) fo) {
|
||||
printGraph(writer.level(), element, element.getClass());
|
||||
}
|
||||
} else {
|
||||
writer.writeLine(name + ":");
|
||||
printGraph(writer.level(), fo, fo.getClass());
|
||||
}
|
||||
}
|
||||
klazz = klazz.getSuperclass();
|
||||
if (klazz != null) printGraph(writer, o, klazz);
|
||||
}
|
||||
|
||||
private record IndentingWriter(StringBuilder out, String indentation) {
|
||||
public void writeLine(String text) {
|
||||
out.append(indentation).append(text.replace("\n", "\\n")).append('\n');
|
||||
}
|
||||
|
||||
public IndentingWriter level() {
|
||||
return new IndentingWriter(out, indentation + " ");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package io.gitlab.jfronny.muscript.data.additional.impl;
|
||||
|
||||
import io.gitlab.jfronny.muscript.data.additional.DFinal;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.DList;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.DString;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.data.dynamic.context.ISimpleDynamic;
|
||||
|
||||
public class SimpleDynamicImpl implements ISimpleDynamic {
|
||||
@Override
|
||||
public DString of(String value) {
|
||||
return DFinal.of(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DList of(Dynamic... values) {
|
||||
return DFinal.of(values);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
module io.gitlab.jfronny.commons.muscript.data.additional {
|
||||
uses io.gitlab.jfronny.muscript.data.additional.DataExprMapper.Mapping;
|
||||
requires io.gitlab.jfronny.commons;
|
||||
requires static org.jetbrains.annotations;
|
||||
requires io.gitlab.jfronny.commons.muscript.data;
|
||||
requires io.gitlab.jfronny.commons.muscript.ast;
|
||||
requires io.gitlab.jfronny.commons.muscript.core;
|
||||
exports io.gitlab.jfronny.muscript.data.additional;
|
||||
exports io.gitlab.jfronny.muscript.data.additional.impl;
|
||||
exports io.gitlab.jfronny.muscript.data.additional.context;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
io.gitlab.jfronny.muscript.data.additional.impl.SimpleDynamicImpl
|
Loading…
Reference in New Issue