[muscript] implement basic AST optimization. Completely untested, of course
This commit is contained in:
parent
62ab9e930d
commit
f84bdd2a02
|
@ -20,7 +20,7 @@ public class Parser {
|
|||
private final TokenData current = new TokenData();
|
||||
|
||||
public static Expr<?> parse(String source) {
|
||||
return new Parser(new Lexer(source)).parse();
|
||||
return new Parser(new Lexer(source)).parse().optimize();
|
||||
}
|
||||
|
||||
public Parser(Lexer lexer) {
|
||||
|
@ -33,7 +33,6 @@ public class Parser {
|
|||
}
|
||||
|
||||
// Expressions
|
||||
|
||||
private Expr<?> expression() {
|
||||
try {
|
||||
return conditional();
|
||||
|
|
|
@ -13,6 +13,9 @@ public abstract non-sealed class BoolExpr extends Expr<Boolean> {
|
|||
return Type.Boolean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract BoolExpr optimize();
|
||||
|
||||
@Override
|
||||
public DynamicExpr asDynamicExpr() {
|
||||
return new DynamicCoerce(character, this);
|
||||
|
|
|
@ -14,6 +14,9 @@ public abstract non-sealed class DynamicExpr extends Expr<Dynamic<?>> {
|
|||
return Type.Dynamic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract DynamicExpr optimize();
|
||||
|
||||
@Override
|
||||
public BoolExpr asBoolExpr() {
|
||||
return new BoolUnpack(character, this);
|
||||
|
|
|
@ -15,6 +15,7 @@ public sealed abstract class Expr<T> permits BoolExpr, DynamicExpr, NullLiteral,
|
|||
|
||||
public abstract Type getResultType();
|
||||
public abstract T get(Dynamic<?> dataRoot);
|
||||
public abstract Expr<T> optimize();
|
||||
public final int character;
|
||||
|
||||
public BoolExpr asBoolExpr() {
|
||||
|
|
|
@ -23,6 +23,11 @@ public final class NullLiteral extends Expr<Object> {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NullLiteral optimize() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicExpr asDynamicExpr() {
|
||||
return new DynamicLiteral<>(character, new DNull());
|
||||
|
@ -42,4 +47,9 @@ public final class NullLiteral extends Expr<Object> {
|
|||
public BoolExpr asBoolExpr() {
|
||||
throw new LocationalException(character, "Attempted to convert null to a boolean");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof NullLiteral;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,9 @@ public abstract non-sealed class NumberExpr extends Expr<Double> {
|
|||
return Type.Number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract NumberExpr optimize();
|
||||
|
||||
@Override
|
||||
public DynamicExpr asDynamicExpr() {
|
||||
return new DynamicCoerce(character, this);
|
||||
|
|
|
@ -13,6 +13,9 @@ public abstract non-sealed class StringExpr extends Expr<String> {
|
|||
return Type.String;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract StringExpr optimize();
|
||||
|
||||
@Override
|
||||
public DynamicExpr asDynamicExpr() {
|
||||
return new DynamicCoerce(character, this);
|
||||
|
|
|
@ -2,6 +2,8 @@ package io.gitlab.jfronny.muscript.compiler.expr.bool;
|
|||
|
||||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.BoolExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.Expr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.BoolLiteral;
|
||||
|
||||
public class And extends BoolExpr {
|
||||
private final BoolExpr left;
|
||||
|
@ -17,4 +19,18 @@ public class And extends BoolExpr {
|
|||
public Boolean get(Dynamic<?> dataRoot) {
|
||||
return left.get(dataRoot) && right.get(dataRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoolExpr optimize() {
|
||||
BoolExpr left = this.left.optimize();
|
||||
BoolExpr right = this.right.optimize();
|
||||
if (left instanceof BoolLiteral literal) return literal.value ? right : Expr.literal(character, false);
|
||||
if (right instanceof BoolLiteral literal) return literal.value ? left : Expr.literal(character, false);
|
||||
return new And(character, left, right);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof And and && left.equals(and.left) && right.equals(and.right);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ package io.gitlab.jfronny.muscript.compiler.expr.bool;
|
|||
|
||||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.BoolExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.Expr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.BoolLiteral;
|
||||
|
||||
public class Not extends BoolExpr {
|
||||
private final BoolExpr inner;
|
||||
|
@ -15,4 +17,17 @@ public class Not extends BoolExpr {
|
|||
public Boolean get(Dynamic<?> dataRoot) {
|
||||
return !inner.get(dataRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoolExpr optimize() {
|
||||
BoolExpr inner = this.inner.optimize();
|
||||
if (inner instanceof Not not) return not.inner;
|
||||
if (inner instanceof BoolLiteral literal) return Expr.literal(character, !literal.value);
|
||||
return new Not(character, inner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Not not && inner.equals(not.inner);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ package io.gitlab.jfronny.muscript.compiler.expr.bool;
|
|||
|
||||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.BoolExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.Expr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.BoolLiteral;
|
||||
|
||||
public class Or extends BoolExpr {
|
||||
private final BoolExpr left;
|
||||
|
@ -17,4 +19,18 @@ public class Or extends BoolExpr {
|
|||
public Boolean get(Dynamic<?> dataRoot) {
|
||||
return left.get(dataRoot) || right.get(dataRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoolExpr optimize() {
|
||||
BoolExpr left = this.left.optimize();
|
||||
BoolExpr right = this.right.optimize();
|
||||
if (left instanceof BoolLiteral literal) return literal.value ? Expr.literal(character, true) : right;
|
||||
if (right instanceof BoolLiteral literal) return literal.value ? Expr.literal(character, true) : left;
|
||||
return new Or(character, left, right);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Or or && left.equals(or.left) && right.equals(or.right);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,4 +25,17 @@ public class Equal extends BoolExpr {
|
|||
if (o instanceof Dynamic<?> a) return unwrap(a.getValue());
|
||||
return o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoolExpr optimize() {
|
||||
Expr<?> left = this.left.optimize();
|
||||
Expr<?> right = this.right.optimize();
|
||||
if (left.equals(right)) return Expr.literal(character, true);
|
||||
return new Equal(character, left, right);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Equal equal && left.equals(equal.left) && right.equals(equal.right);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.gitlab.jfronny.muscript.compiler.expr.common.conditional;
|
|||
|
||||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.BoolExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.BoolLiteral;
|
||||
|
||||
public class BoolConditional extends BoolExpr {
|
||||
public final BoolExpr condition;
|
||||
|
@ -19,4 +20,22 @@ public class BoolConditional extends BoolExpr {
|
|||
public Boolean get(Dynamic<?> dataRoot) {
|
||||
return condition.get(dataRoot) ? trueExpr.get(dataRoot) : falseExpr.get(dataRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoolExpr optimize() {
|
||||
BoolExpr condition = this.condition.optimize();
|
||||
BoolExpr trueExpr = this.trueExpr.optimize();
|
||||
BoolExpr falseExpr = this.falseExpr.optimize();
|
||||
if (condition instanceof BoolLiteral literal) return literal.value ? trueExpr : falseExpr;
|
||||
if (trueExpr.equals(falseExpr)) return trueExpr;
|
||||
return new BoolConditional(character, condition, trueExpr, falseExpr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof BoolConditional conditional
|
||||
&& condition.equals(conditional.condition)
|
||||
&& trueExpr.equals(conditional.trueExpr)
|
||||
&& falseExpr.equals(conditional.falseExpr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.gitlab.jfronny.muscript.compiler.expr.common.conditional;
|
|||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.BoolExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.DynamicExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.BoolLiteral;
|
||||
import io.gitlab.jfronny.muscript.error.TypeMismatchException;
|
||||
|
||||
public class DynamicConditional extends DynamicExpr {
|
||||
|
@ -10,7 +11,7 @@ public class DynamicConditional extends DynamicExpr {
|
|||
public final DynamicExpr trueExpr;
|
||||
public final DynamicExpr falseExpr;
|
||||
|
||||
public DynamicConditional(int character, BoolExpr condition, DynamicExpr trueExpr, DynamicExpr falseExpr) throws TypeMismatchException {
|
||||
public DynamicConditional(int character, BoolExpr condition, DynamicExpr trueExpr, DynamicExpr falseExpr) {
|
||||
super(character);
|
||||
this.condition = condition;
|
||||
this.trueExpr = trueExpr;
|
||||
|
@ -18,7 +19,25 @@ public class DynamicConditional extends DynamicExpr {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Dynamic get(Dynamic<?> dataRoot) {
|
||||
public Dynamic<?> get(Dynamic<?> dataRoot) {
|
||||
return condition.get(dataRoot) ? trueExpr.get(dataRoot) : falseExpr.get(dataRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicExpr optimize() {
|
||||
BoolExpr condition = this.condition.optimize();
|
||||
DynamicExpr trueExpr = this.trueExpr.optimize();
|
||||
DynamicExpr falseExpr = this.falseExpr.optimize();
|
||||
if (condition instanceof BoolLiteral literal) return literal.value ? trueExpr : falseExpr;
|
||||
if (trueExpr.equals(falseExpr)) return trueExpr;
|
||||
return new DynamicConditional(character, condition, trueExpr, falseExpr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof DynamicConditional conditional
|
||||
&& condition.equals(conditional.condition)
|
||||
&& trueExpr.equals(conditional.trueExpr)
|
||||
&& falseExpr.equals(conditional.falseExpr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package io.gitlab.jfronny.muscript.compiler.expr.common.conditional;
|
||||
|
||||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.BoolExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.NumberExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.BoolLiteral;
|
||||
|
||||
public class NumberConditional extends NumberExpr {
|
||||
public final BoolExpr condition;
|
||||
|
@ -20,4 +20,22 @@ public class NumberConditional extends NumberExpr {
|
|||
public Double get(Dynamic<?> dataRoot) {
|
||||
return condition.get(dataRoot) ? trueExpr.get(dataRoot) : falseExpr.get(dataRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NumberExpr optimize() {
|
||||
BoolExpr condition = this.condition.optimize();
|
||||
NumberExpr trueExpr = this.trueExpr.optimize();
|
||||
NumberExpr falseExpr = this.falseExpr.optimize();
|
||||
if (condition instanceof BoolLiteral literal) return literal.value ? trueExpr : falseExpr;
|
||||
if (trueExpr.equals(falseExpr)) return trueExpr;
|
||||
return new NumberConditional(character, condition, trueExpr, falseExpr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof NumberConditional conditional
|
||||
&& condition.equals(conditional.condition)
|
||||
&& trueExpr.equals(conditional.trueExpr)
|
||||
&& falseExpr.equals(conditional.falseExpr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package io.gitlab.jfronny.muscript.compiler.expr.common.conditional;
|
||||
|
||||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.BoolExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.StringExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.BoolLiteral;
|
||||
|
||||
public class StringConditional extends StringExpr {
|
||||
public final BoolExpr condition;
|
||||
|
@ -20,4 +20,22 @@ public class StringConditional extends StringExpr {
|
|||
public String get(Dynamic<?> dataRoot) {
|
||||
return condition.get(dataRoot) ? trueExpr.get(dataRoot) : falseExpr.get(dataRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringExpr optimize() {
|
||||
BoolExpr condition = this.condition.optimize();
|
||||
StringExpr trueExpr = this.trueExpr.optimize();
|
||||
StringExpr falseExpr = this.falseExpr.optimize();
|
||||
if (condition instanceof BoolLiteral literal) return literal.value ? trueExpr : falseExpr;
|
||||
if (trueExpr.equals(falseExpr)) return trueExpr;
|
||||
return new StringConditional(character, condition, trueExpr, falseExpr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof StringConditional conditional
|
||||
&& condition.equals(conditional.condition)
|
||||
&& trueExpr.equals(conditional.trueExpr)
|
||||
&& falseExpr.equals(conditional.falseExpr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
|||
import io.gitlab.jfronny.muscript.compiler.expr.BoolExpr;
|
||||
|
||||
public final class BoolLiteral extends BoolExpr {
|
||||
private final boolean value;
|
||||
public final boolean value;
|
||||
|
||||
public BoolLiteral(int character, boolean value) {
|
||||
super(character);
|
||||
|
@ -15,4 +15,14 @@ public final class BoolLiteral extends BoolExpr {
|
|||
public Boolean get(Dynamic<?> dataRoot) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoolExpr optimize() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof BoolLiteral literal && value == literal.value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,4 +15,14 @@ public final class DynamicLiteral<T> extends DynamicExpr {
|
|||
public Dynamic<T> get(Dynamic<?> dataRoot) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicExpr optimize() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof DynamicLiteral<?> literal && value.equals(literal.value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
|||
import io.gitlab.jfronny.muscript.compiler.expr.NumberExpr;
|
||||
|
||||
public final class NumberLiteral extends NumberExpr {
|
||||
private final double value;
|
||||
public final double value;
|
||||
|
||||
public NumberLiteral(int character, double value) {
|
||||
super(character);
|
||||
|
@ -15,4 +15,14 @@ public final class NumberLiteral extends NumberExpr {
|
|||
public Double get(Dynamic<?> dataRoot) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NumberExpr optimize() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof NumberLiteral literal && value == literal.value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
|||
import io.gitlab.jfronny.muscript.compiler.expr.StringExpr;
|
||||
|
||||
public final class StringLiteral extends StringExpr {
|
||||
private final String value;
|
||||
public final String value;
|
||||
|
||||
public StringLiteral(int character, String value) {
|
||||
super(character);
|
||||
|
@ -15,4 +15,14 @@ public final class StringLiteral extends StringExpr {
|
|||
public String get(Dynamic<?> dataRoot) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringExpr optimize() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof StringLiteral literal && value.equals(literal.value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import io.gitlab.jfronny.muscript.compiler.expr.*;
|
|||
import io.gitlab.jfronny.muscript.compiler.expr.annotations.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@CanThrow @UncheckedDynamic
|
||||
public class Call extends DynamicExpr {
|
||||
|
@ -25,4 +26,17 @@ public class Call extends DynamicExpr {
|
|||
throw e.locational(character);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicExpr optimize() {
|
||||
DynamicExpr left = this.left.optimize();
|
||||
List<DynamicExpr> args = new ArrayList<>();
|
||||
for (DynamicExpr arg : this.args) args.add(arg.optimize());
|
||||
return new Call(character, left, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Call call && left.equals(call.left) && args.equals(call.args);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,10 @@ package io.gitlab.jfronny.muscript.compiler.expr.dynamic;
|
|||
|
||||
import io.gitlab.jfronny.commons.data.dynamic.*;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.dynamic.unpack.*;
|
||||
|
||||
public class DynamicCoerce extends DynamicExpr {
|
||||
private final Expr<?> inner;
|
||||
public final Expr<?> inner;
|
||||
|
||||
public DynamicCoerce(int character, Expr<?> inner) {
|
||||
super(character);
|
||||
|
@ -27,4 +28,18 @@ public class DynamicCoerce extends DynamicExpr {
|
|||
if (inner instanceof NullLiteral) return new DNull();
|
||||
throw new IllegalStateException("The inner expression of DynamicCoerce should never be of undefined type");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicExpr optimize() {
|
||||
Expr<?> inner = this.inner.optimize();
|
||||
if (inner instanceof BoolUnpack unpack) return unpack.inner;
|
||||
if (inner instanceof NumberUnpack unpack) return unpack.inner;
|
||||
if (inner instanceof StringUnpack unpack) return unpack.inner;
|
||||
return new DynamicCoerce(character, inner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof DynamicCoerce coerce && inner.equals(coerce.inner);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,4 +32,16 @@ public class Get extends DynamicExpr {
|
|||
}
|
||||
throw new DynamicTypeConversionException("object or list").locational(character);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicExpr optimize() {
|
||||
DynamicExpr left = this.left.optimize();
|
||||
Expr<?> name = this.name.optimize();
|
||||
return new Get(character, left, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Get get && left.equals(get.left) && name.equals(get.name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,4 +29,14 @@ public class Variable extends DynamicExpr {
|
|||
return res;
|
||||
} else throw new LocationalException(character, "This object doesn't contain that name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicExpr optimize() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Variable variable && name.equals(variable.name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,12 @@ package io.gitlab.jfronny.muscript.compiler.expr.dynamic.unpack;
|
|||
import io.gitlab.jfronny.commons.data.dynamic.*;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.annotations.*;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.dynamic.DynamicCoerce;
|
||||
|
||||
@CanThrow
|
||||
@UncheckedDynamic
|
||||
public class BoolUnpack extends BoolExpr {
|
||||
private final DynamicExpr inner;
|
||||
public final DynamicExpr inner;
|
||||
|
||||
public BoolUnpack(int character, DynamicExpr inner) {
|
||||
super(character);
|
||||
|
@ -22,4 +23,16 @@ public class BoolUnpack extends BoolExpr {
|
|||
throw e.locational(character);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoolExpr optimize() {
|
||||
DynamicExpr inner = this.inner.optimize();
|
||||
if (inner instanceof DynamicCoerce coerce) return coerce.inner.asBoolExpr();
|
||||
return new BoolUnpack(character, inner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof BoolUnpack unpack && inner.equals(unpack.inner);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,11 +5,12 @@ import io.gitlab.jfronny.commons.data.dynamic.DynamicTypeConversionException;
|
|||
import io.gitlab.jfronny.muscript.compiler.expr.DynamicExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.NumberExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.annotations.*;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.dynamic.DynamicCoerce;
|
||||
|
||||
@CanThrow
|
||||
@UncheckedDynamic
|
||||
public class NumberUnpack extends NumberExpr {
|
||||
private final DynamicExpr inner;
|
||||
public final DynamicExpr inner;
|
||||
|
||||
public NumberUnpack(int character, DynamicExpr inner) {
|
||||
super(character);
|
||||
|
@ -24,4 +25,16 @@ public class NumberUnpack extends NumberExpr {
|
|||
throw e.locational(character);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NumberExpr optimize() {
|
||||
DynamicExpr inner = this.inner.optimize();
|
||||
if (inner instanceof DynamicCoerce coerce) return coerce.inner.asNumberExpr();
|
||||
return new NumberUnpack(character, inner.optimize());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof NumberUnpack unpack && inner.equals(unpack.inner);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,11 +6,12 @@ import io.gitlab.jfronny.muscript.compiler.expr.DynamicExpr;
|
|||
import io.gitlab.jfronny.muscript.compiler.expr.StringExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.annotations.CanThrow;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.annotations.UncheckedDynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.dynamic.DynamicCoerce;
|
||||
|
||||
@CanThrow
|
||||
@UncheckedDynamic
|
||||
public class StringUnpack extends StringExpr {
|
||||
private final DynamicExpr inner;
|
||||
public final DynamicExpr inner;
|
||||
|
||||
public StringUnpack(int character, DynamicExpr inner) {
|
||||
super(character);
|
||||
|
@ -25,4 +26,16 @@ public class StringUnpack extends StringExpr {
|
|||
throw e.locational(character);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringExpr optimize() {
|
||||
DynamicExpr inner = this.inner.optimize();
|
||||
if (inner instanceof DynamicCoerce coerce) return coerce.inner.asStringExpr();
|
||||
return new StringUnpack(character, inner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof StringUnpack unpack && inner.equals(unpack.inner);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package io.gitlab.jfronny.muscript.compiler.expr.number.compare;
|
||||
|
||||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.BoolExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.NumberExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.bool.Not;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.NumberLiteral;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.number.math.*;
|
||||
|
||||
public class Greater extends BoolExpr {
|
||||
private final NumberExpr left;
|
||||
|
@ -18,4 +20,24 @@ public class Greater extends BoolExpr {
|
|||
public Boolean get(Dynamic<?> dataRoot) {
|
||||
return left.get(dataRoot) > right.get(dataRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoolExpr optimize() {
|
||||
NumberExpr left = this.left.optimize();
|
||||
NumberExpr right = this.right.optimize();
|
||||
if (left instanceof NumberLiteral litL && right instanceof NumberLiteral litR) return Expr.literal(character, litL.value > litR.value);
|
||||
if (left instanceof Divide divide) return new Greater(character, divide.dividend, new Multiply(divide.character, right, divide.divisor)).optimize();
|
||||
if (left instanceof Invert invert) return new Less(character, invert.inner, new Invert(right.character, right)).optimize();
|
||||
if (left instanceof Minus minus) return new Greater(character, minus.minuend, new Plus(minus.character, minus.subtrahend, right)).optimize();
|
||||
// Modulo is left out because it is too complicated for this naive impl
|
||||
// Multiply is left out since it would transform into a division and may be 0
|
||||
if (left instanceof Plus plus) return new Greater(character, plus.augend, new Minus(plus.character, plus.addend, right)).optimize();
|
||||
// Power is left out because it can't be transformed cleanly either
|
||||
return new Greater(character, left, right);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Greater greater && left.equals(greater.left) && right.equals(greater.right);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package io.gitlab.jfronny.muscript.compiler.expr.number.compare;
|
||||
|
||||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.BoolExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.NumberExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.NumberLiteral;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.number.math.*;
|
||||
|
||||
public class Less extends BoolExpr {
|
||||
private final NumberExpr left;
|
||||
|
@ -18,4 +19,24 @@ public class Less extends BoolExpr {
|
|||
public Boolean get(Dynamic<?> dataRoot) {
|
||||
return left.get(dataRoot) < right.get(dataRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoolExpr optimize() {
|
||||
NumberExpr left = this.left.optimize();
|
||||
NumberExpr right = this.right.optimize();
|
||||
if (left instanceof NumberLiteral litL && right instanceof NumberLiteral litR) return Expr.literal(character, litL.value < litR.value);
|
||||
if (left instanceof Divide divide) return new Less(character, divide.dividend, new Multiply(divide.character, divide.divisor, right)).optimize();
|
||||
if (left instanceof Invert invert) return new Greater(character, invert.inner, new Invert(right.character, right)).optimize();
|
||||
if (left instanceof Minus minus) return new Less(character, minus.minuend, new Plus(minus.character, minus.subtrahend, right)).optimize();
|
||||
// Modulo is left out because it is too complicated for this naive impl
|
||||
// Multiply is left out since it would transform into a division and may be 0
|
||||
if (left instanceof Plus plus) return new Less(character, plus.augend, new Minus(plus.character, plus.addend, right)).optimize();
|
||||
// Power is left out because it can't be transformed cleanly either
|
||||
return new Less(character, left, right);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Less less && left.equals(less.left) && right.equals(less.right);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package io.gitlab.jfronny.muscript.compiler.expr.number.math;
|
||||
|
||||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.Expr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.NumberExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.NumberLiteral;
|
||||
|
||||
public class Divide extends NumberExpr {
|
||||
private final NumberExpr dividend;
|
||||
private final NumberExpr divisor;
|
||||
public final NumberExpr dividend;
|
||||
public final NumberExpr divisor;
|
||||
|
||||
public Divide(int character, NumberExpr dividend, NumberExpr divisor) {
|
||||
super(character);
|
||||
|
@ -17,4 +19,18 @@ public class Divide extends NumberExpr {
|
|||
public Double get(Dynamic<?> dataRoot) {
|
||||
return dividend.get(dataRoot) / divisor.get(dataRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NumberExpr optimize() {
|
||||
NumberExpr dividend = this.dividend.optimize();
|
||||
NumberExpr divisor = this.divisor.optimize();
|
||||
if (dividend instanceof NumberLiteral litL && divisor instanceof NumberLiteral litR) return Expr.literal(character, litL.value / litR.value);
|
||||
if (dividend instanceof Divide divide && divide.dividend instanceof NumberLiteral literal) return new Divide(character, divide.dividend, new Multiply(divide.character, divisor, literal)).optimize();
|
||||
return new Divide(character, dividend, divisor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Divide divide && dividend.equals(divide.dividend) && divisor.equals(divide.divisor);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package io.gitlab.jfronny.muscript.compiler.expr.number.math;
|
||||
|
||||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.Expr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.NumberExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.NumberLiteral;
|
||||
|
||||
public class Invert extends NumberExpr {
|
||||
private final NumberExpr inner;
|
||||
public final NumberExpr inner;
|
||||
|
||||
public Invert(int character, NumberExpr inner) {
|
||||
super(character);
|
||||
|
@ -15,4 +17,17 @@ public class Invert extends NumberExpr {
|
|||
public Double get(Dynamic<?> dataRoot) {
|
||||
return -inner.get(dataRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NumberExpr optimize() {
|
||||
NumberExpr inner = this.inner.optimize();
|
||||
if (inner instanceof Invert invert) return invert.inner;
|
||||
if (inner instanceof NumberLiteral literal) return Expr.literal(character, -literal.value);
|
||||
return new Invert(character, inner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Invert invert && inner.equals(invert.inner);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package io.gitlab.jfronny.muscript.compiler.expr.number.math;
|
||||
|
||||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.Expr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.NumberExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.NumberLiteral;
|
||||
|
||||
public class Minus extends NumberExpr {
|
||||
private final NumberExpr minuend;
|
||||
private final NumberExpr subtrahend;
|
||||
public final NumberExpr minuend;
|
||||
public final NumberExpr subtrahend;
|
||||
|
||||
public Minus(int character, NumberExpr minuend, NumberExpr subtrahend) {
|
||||
super(character);
|
||||
|
@ -17,4 +19,18 @@ public class Minus extends NumberExpr {
|
|||
public Double get(Dynamic<?> dataRoot) {
|
||||
return minuend.get(dataRoot) - subtrahend.get(dataRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NumberExpr optimize() {
|
||||
NumberExpr minuend = this.minuend.optimize();
|
||||
NumberExpr subtrahend = this.subtrahend.optimize();
|
||||
if (minuend instanceof NumberLiteral litM && subtrahend instanceof NumberLiteral litS) return Expr.literal(character, litM.value - litS.value);
|
||||
if (minuend instanceof Minus minus) return new Minus(character, minus.minuend, new Plus(minus.character, minus.subtrahend, subtrahend)).optimize();
|
||||
return new Minus(character, minuend, subtrahend);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Minus minus && minuend.equals(minus.minuend) && subtrahend.equals(minus.subtrahend);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package io.gitlab.jfronny.muscript.compiler.expr.number.math;
|
||||
|
||||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.Expr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.NumberExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.NumberLiteral;
|
||||
|
||||
public class Modulo extends NumberExpr {
|
||||
private final NumberExpr dividend;
|
||||
|
@ -17,4 +19,17 @@ public class Modulo extends NumberExpr {
|
|||
public Double get(Dynamic<?> dataRoot) {
|
||||
return dividend.get(dataRoot) % divisor.get(dataRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NumberExpr optimize() {
|
||||
NumberExpr dividend = this.dividend.optimize();
|
||||
NumberExpr divisor = this.divisor.optimize();
|
||||
if (dividend instanceof NumberLiteral litD && divisor instanceof NumberLiteral litS) return Expr.literal(character, litD.value % litS.value);
|
||||
return new Modulo(character, dividend, divisor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Modulo modulo && dividend.equals(modulo.dividend) && divisor.equals(modulo.divisor);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package io.gitlab.jfronny.muscript.compiler.expr.number.math;
|
||||
|
||||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.Expr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.NumberExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.NumberLiteral;
|
||||
|
||||
public class Multiply extends NumberExpr {
|
||||
private final NumberExpr multiplier;
|
||||
private final NumberExpr multiplicand;
|
||||
public final NumberExpr multiplier;
|
||||
public final NumberExpr multiplicand;
|
||||
|
||||
public Multiply(int character, NumberExpr multiplier, NumberExpr multiplicand) {
|
||||
super(character);
|
||||
|
@ -17,4 +19,17 @@ public class Multiply extends NumberExpr {
|
|||
public Double get(Dynamic<?> dataRoot) {
|
||||
return multiplier.get(dataRoot) * multiplicand.get(dataRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NumberExpr optimize() {
|
||||
NumberExpr multiplier = this.multiplier.optimize();
|
||||
NumberExpr multiplicand = this.multiplicand.optimize();
|
||||
if (multiplier instanceof NumberLiteral litEr && multiplicand instanceof NumberLiteral litAnd) return Expr.literal(character, litEr.value * litAnd.value);
|
||||
return new Modulo(character, multiplier, multiplicand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Multiply multiply && multiplier.equals(multiply.multiplier) && multiplicand.equals(multiply.multiplicand);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package io.gitlab.jfronny.muscript.compiler.expr.number.math;
|
||||
|
||||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.Expr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.NumberExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.NumberLiteral;
|
||||
|
||||
public class Plus extends NumberExpr {
|
||||
private final NumberExpr augend;
|
||||
private final NumberExpr addend;
|
||||
public final NumberExpr augend;
|
||||
public final NumberExpr addend;
|
||||
|
||||
public Plus(int character, NumberExpr augend, NumberExpr addend) {
|
||||
super(character);
|
||||
|
@ -17,4 +19,17 @@ public class Plus extends NumberExpr {
|
|||
public Double get(Dynamic<?> dataRoot) {
|
||||
return augend.get(dataRoot) + addend.get(dataRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NumberExpr optimize() {
|
||||
NumberExpr augend = this.augend.optimize();
|
||||
NumberExpr addend = this.addend.optimize();
|
||||
if (augend instanceof NumberLiteral litU && addend instanceof NumberLiteral litD) return Expr.literal(character, litU.value + litD.value);
|
||||
return new Plus(character, augend, addend);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Plus plus && augend.equals(plus.augend) && addend.equals(plus.addend);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package io.gitlab.jfronny.muscript.compiler.expr.number.math;
|
||||
|
||||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.Expr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.NumberExpr;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.NumberLiteral;
|
||||
|
||||
public class Power extends NumberExpr {
|
||||
private final NumberExpr base;
|
||||
|
@ -17,4 +19,27 @@ public class Power extends NumberExpr {
|
|||
public Double get(Dynamic<?> dataRoot) {
|
||||
return Math.pow(base.get(dataRoot), exponent.get(dataRoot));
|
||||
}
|
||||
|
||||
@Override
|
||||
public NumberExpr optimize() {
|
||||
NumberExpr base = this.base.optimize();
|
||||
NumberExpr exponent = this.exponent.optimize();
|
||||
if (base instanceof NumberLiteral litB && exponent instanceof NumberLiteral litE) return Expr.literal(character, Math.pow(litB.value, litE.value));
|
||||
if (exponent instanceof NumberLiteral exp && base instanceof Multiply multiply) {
|
||||
if (multiply.multiplier instanceof NumberLiteral literal)
|
||||
return new Multiply(multiply.character,
|
||||
Expr.literal(character, Math.pow(literal.value, exp.value)),
|
||||
new Power(character, multiply.multiplicand, exp));
|
||||
if (multiply.multiplicand instanceof NumberLiteral literal)
|
||||
return new Multiply(multiply.character,
|
||||
Expr.literal(character, Math.pow(literal.value, exp.value)),
|
||||
new Power(character, multiply.multiplier, exp));
|
||||
}
|
||||
return new Power(character, base, exponent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Power power && base.equals(power.base) && exponent.equals(power.exponent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.gitlab.jfronny.muscript.compiler.expr.string;
|
|||
|
||||
import io.gitlab.jfronny.commons.data.dynamic.Dynamic;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.StringLiteral;
|
||||
|
||||
public class Concatenate extends StringExpr {
|
||||
private final StringExpr left;
|
||||
|
@ -17,4 +18,23 @@ public class Concatenate extends StringExpr {
|
|||
public String get(Dynamic<?> dataRoot) {
|
||||
return left.get(dataRoot) + right.get(dataRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringExpr optimize() {
|
||||
StringExpr left = this.left.optimize();
|
||||
StringExpr right = this.right.optimize();
|
||||
if (left instanceof StringLiteral litL && right instanceof StringLiteral litR) return Expr.literal(character, litL.value + litR.value);
|
||||
if (right instanceof StringLiteral litR && left instanceof Concatenate concatenate && concatenate.right instanceof StringLiteral litL) {
|
||||
return new Concatenate(character, concatenate.left, Expr.literal(concatenate.character, litL.value + litR.value));
|
||||
}
|
||||
if (left instanceof StringLiteral litL && right instanceof Concatenate concatenate && concatenate.left instanceof StringLiteral litR) {
|
||||
return new Concatenate(character, Expr.literal(concatenate.character, litL.value + litR.value), concatenate.right);
|
||||
}
|
||||
return new Concatenate(character, left, right);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Concatenate concatenate && left.equals(concatenate.left) && right.equals(concatenate.right);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,4 +17,16 @@ public class StringCoerce extends StringExpr {
|
|||
public String get(Dynamic<?> dataRoot) {
|
||||
return StringFormatter.toString(inner.get(dataRoot));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringExpr optimize() {
|
||||
Expr<?> inner = this.inner.optimize();
|
||||
if (inner instanceof StringExpr expr) return expr;
|
||||
return new StringCoerce(character, inner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof StringCoerce coerce && inner.equals(coerce.inner);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import io.gitlab.jfronny.muscript.compiler.Type;
|
|||
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.annotations.CanThrow;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.common.conditional.*;
|
||||
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.BoolLiteral;
|
||||
|
||||
@CanThrow
|
||||
public class UnresolvedConditional extends DynamicExpr {
|
||||
|
@ -25,7 +26,17 @@ public class UnresolvedConditional extends DynamicExpr {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Dynamic get(Dynamic dataRoot) {
|
||||
public DynamicExpr optimize() {
|
||||
BoolExpr condition = this.condition.optimize();
|
||||
Expr<?> trueExpr = this.trueExpr.optimize();
|
||||
Expr<?> falseExpr = this.falseExpr.optimize();
|
||||
if (condition instanceof BoolLiteral literal) return literal.value ? trueExpr.asDynamicExpr() : falseExpr.asDynamicExpr();
|
||||
if (trueExpr.equals(falseExpr)) return trueExpr.asDynamicExpr();
|
||||
return new UnresolvedConditional(character, condition, trueExpr, falseExpr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dynamic<?> get(Dynamic<?> dataRoot) {
|
||||
throw new UnsupportedOperationException("Conditional was kept unresolved. This is not supported!");
|
||||
}
|
||||
|
||||
|
@ -48,4 +59,12 @@ public class UnresolvedConditional extends DynamicExpr {
|
|||
public NumberExpr asNumberExpr() {
|
||||
return new NumberConditional(character, condition, trueExpr.asNumberExpr(), falseExpr.asNumberExpr());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof UnresolvedConditional conditional
|
||||
&& condition.equals(conditional.condition)
|
||||
&& trueExpr.equals(conditional.trueExpr)
|
||||
&& falseExpr.equals(conditional.falseExpr);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue