[muscript] No more inner-classes for expressions
This commit is contained in:
parent
4f3fdbb9fd
commit
5447174c90
@ -1,185 +0,0 @@
|
|||||||
package io.gitlab.jfronny.muscript.compiler;
|
|
||||||
|
|
||||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
|
||||||
import io.gitlab.jfronny.commons.StringFormatter;
|
|
||||||
|
|
||||||
public abstract class Expr<T> {
|
|
||||||
public abstract Type getResultType();
|
|
||||||
public abstract T get(Dynamic<?> branch, Dynamic<?> dataRoot);
|
|
||||||
|
|
||||||
public T get(Dynamic<?> branch) {
|
|
||||||
return get(branch, branch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BoolExpr asBoolExpr() {
|
|
||||||
if (this instanceof BoolExpr e) return e;
|
|
||||||
throw new IllegalArgumentException("Expected boolean but is " + getResultType());
|
|
||||||
}
|
|
||||||
|
|
||||||
public StringExpr asStringExpr() {
|
|
||||||
if (this instanceof StringExpr e) return e;
|
|
||||||
return new StringExpr() {
|
|
||||||
@Override
|
|
||||||
public String get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
return StringFormatter.toString(Expr.this.get(branch, dataRoot));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public NumberExpr asNumberExpr() {
|
|
||||||
if (this instanceof NumberExpr e) return e;
|
|
||||||
throw new IllegalArgumentException("Expected number but is " + getResultType());
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract DynamicExpr asDynamicExpr();
|
|
||||||
|
|
||||||
public boolean isNull() {
|
|
||||||
return this instanceof NullExpr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static abstract class BoolExpr extends Expr<Boolean> {
|
|
||||||
@Override
|
|
||||||
public Type getResultType() {
|
|
||||||
return Type.Boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DynamicExpr asDynamicExpr() {
|
|
||||||
return new DynamicExpr() {
|
|
||||||
@Override
|
|
||||||
public Dynamic<?> get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
return DFinal.of(BoolExpr.this.get(branch, dataRoot));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static abstract class StringExpr extends Expr<String> {
|
|
||||||
@Override
|
|
||||||
public Type getResultType() {
|
|
||||||
return Type.String;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DynamicExpr asDynamicExpr() {
|
|
||||||
return new DynamicExpr() {
|
|
||||||
@Override
|
|
||||||
public Dynamic<?> get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
return DFinal.of(StringExpr.this.get(branch, dataRoot));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static abstract class NumberExpr extends Expr<Double> {
|
|
||||||
@Override
|
|
||||||
public Type getResultType() {
|
|
||||||
return Type.Number;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DynamicExpr asDynamicExpr() {
|
|
||||||
return new DynamicExpr() {
|
|
||||||
@Override
|
|
||||||
public Dynamic<?> get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
return DFinal.of(NumberExpr.this.get(branch, dataRoot));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static abstract class DynamicExpr extends Expr<Dynamic<?>> {
|
|
||||||
@Override
|
|
||||||
public Type getResultType() {
|
|
||||||
return Type.Dynamic;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BoolExpr asBoolExpr() {
|
|
||||||
return new BoolExpr() {
|
|
||||||
@Override
|
|
||||||
public Boolean get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
return DynamicExpr.this.get(branch, dataRoot).asBool().getValue();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public StringExpr asStringExpr() {
|
|
||||||
return new StringExpr() {
|
|
||||||
@Override
|
|
||||||
public String get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
return DynamicExpr.this.get(branch, dataRoot).asString().getValue();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NumberExpr asNumberExpr() {
|
|
||||||
return new NumberExpr() {
|
|
||||||
@Override
|
|
||||||
public Double get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
return DynamicExpr.this.get(branch, dataRoot).asNumber().getValue();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DynamicExpr asDynamicExpr() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class NullExpr extends Expr<Object> {
|
|
||||||
@Override
|
|
||||||
public Type getResultType() {
|
|
||||||
return Type.Dynamic;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DynamicExpr asDynamicExpr() {
|
|
||||||
return new DynamicExpr() {
|
|
||||||
@Override
|
|
||||||
public Dynamic<?> get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
return new DNull();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BoolExpr literal(boolean bool) {
|
|
||||||
return new BoolExpr() {
|
|
||||||
@Override
|
|
||||||
public Boolean get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
return bool;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static StringExpr literal(String string) {
|
|
||||||
return new StringExpr() {
|
|
||||||
@Override
|
|
||||||
public String get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static NumberExpr literal(double number) {
|
|
||||||
return new NumberExpr() {
|
|
||||||
@Override
|
|
||||||
public Double get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
return number;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Expr<?> literalNull() {
|
|
||||||
return new NullExpr();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,13 @@
|
|||||||
package io.gitlab.jfronny.muscript.compiler;
|
package io.gitlab.jfronny.muscript.compiler;
|
||||||
|
|
||||||
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.bool.*;
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.common.*;
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.dynamic.*;
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.number.compare.*;
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.number.math.*;
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.string.*;
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.unresolved.*;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@ -41,7 +48,7 @@ public class Parser {
|
|||||||
Expr<?> trueExpr = expression();
|
Expr<?> trueExpr = expression();
|
||||||
consume(Token.Colon, "Expected ':' after first part of condition.");
|
consume(Token.Colon, "Expected ':' after first part of condition.");
|
||||||
Expr<?> falseExpr = expression();
|
Expr<?> falseExpr = expression();
|
||||||
expr = new Conditional(expr.asBoolExpr(), trueExpr, falseExpr);
|
expr = new UnresolvedConditional(expr.asBoolExpr(), trueExpr, falseExpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
@ -52,7 +59,7 @@ public class Parser {
|
|||||||
|
|
||||||
while (match(Token.And)) {
|
while (match(Token.And)) {
|
||||||
Expr<?> right = or();
|
Expr<?> right = or();
|
||||||
expr = new LogicBiExpr(expr.asBoolExpr(), right.asBoolExpr(), Token.And);
|
expr = new And(expr.asBoolExpr(), right.asBoolExpr());
|
||||||
}
|
}
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
@ -63,7 +70,7 @@ public class Parser {
|
|||||||
|
|
||||||
while (match(Token.Or)) {
|
while (match(Token.Or)) {
|
||||||
Expr<?> right = equality();
|
Expr<?> right = equality();
|
||||||
expr = new LogicBiExpr(expr.asBoolExpr(), right.asBoolExpr(), Token.Or);
|
expr = new Or(expr.asBoolExpr(), right.asBoolExpr());
|
||||||
}
|
}
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
@ -75,7 +82,7 @@ public class Parser {
|
|||||||
while (match(Token.EqualEqual, Token.BangEqual)) {
|
while (match(Token.EqualEqual, Token.BangEqual)) {
|
||||||
Token op = previous.token;
|
Token op = previous.token;
|
||||||
Expr<?> right = concat();
|
Expr<?> right = concat();
|
||||||
Expr.BoolExpr e = new Equal(expr, right);
|
BoolExpr e = new Equal(expr, right);
|
||||||
if (op == Token.BangEqual) e = new Not(e);
|
if (op == Token.BangEqual) e = new Not(e);
|
||||||
expr = e;
|
expr = e;
|
||||||
}
|
}
|
||||||
@ -87,7 +94,6 @@ public class Parser {
|
|||||||
Expr<?> expr = comparison();
|
Expr<?> expr = comparison();
|
||||||
|
|
||||||
while (match(Token.Concat)) {
|
while (match(Token.Concat)) {
|
||||||
Token op = previous.token;
|
|
||||||
Expr<?> right = comparison();
|
Expr<?> right = comparison();
|
||||||
expr = new Concatenate(expr.asStringExpr(), right.asStringExpr());
|
expr = new Concatenate(expr.asStringExpr(), right.asStringExpr());
|
||||||
}
|
}
|
||||||
@ -100,8 +106,14 @@ public class Parser {
|
|||||||
|
|
||||||
while (match(Token.Greater, Token.GreaterEqual, Token.Less, Token.LessEqual)) {
|
while (match(Token.Greater, Token.GreaterEqual, Token.Less, Token.LessEqual)) {
|
||||||
Token op = previous.token;
|
Token op = previous.token;
|
||||||
Expr<?> right = term();
|
NumberExpr right = term().asNumberExpr();
|
||||||
expr = new Compare(expr.asNumberExpr(), right.asNumberExpr(), op);
|
expr = switch (op) {
|
||||||
|
case Greater -> new Greater(expr.asNumberExpr(), right);
|
||||||
|
case GreaterEqual -> new Not(new Less(expr.asNumberExpr(), right));
|
||||||
|
case Less -> new Less(expr.asNumberExpr(), right);
|
||||||
|
case LessEqual -> new Not(new Greater(expr.asNumberExpr(), right));
|
||||||
|
default -> throw new IllegalStateException();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
@ -112,8 +124,12 @@ public class Parser {
|
|||||||
|
|
||||||
while (match(Token.Plus, Token.Minus)) {
|
while (match(Token.Plus, Token.Minus)) {
|
||||||
Token op = previous.token;
|
Token op = previous.token;
|
||||||
Expr<?> right = factor();
|
NumberExpr right = factor().asNumberExpr();
|
||||||
expr = new MathBiExpr(expr.asNumberExpr(), right.asNumberExpr(), op);
|
expr = switch (op) {
|
||||||
|
case Plus -> new Plus(expr.asNumberExpr(), right);
|
||||||
|
case Minus -> new Minus(expr.asNumberExpr(), right);
|
||||||
|
default -> throw new IllegalStateException();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
@ -122,10 +138,15 @@ public class Parser {
|
|||||||
private Expr<?> factor() {
|
private Expr<?> factor() {
|
||||||
Expr<?> expr = exp();
|
Expr<?> expr = exp();
|
||||||
|
|
||||||
while (match(Token.Star, Token.Slash, Token.Percentage, Token.UpArrow)) {
|
while (match(Token.Star, Token.Slash, Token.Percentage)) {
|
||||||
Token op = previous.token;
|
Token op = previous.token;
|
||||||
Expr<?> right = exp();
|
NumberExpr right = exp().asNumberExpr();
|
||||||
expr = new MathBiExpr(expr.asNumberExpr(), right.asNumberExpr(), op);
|
expr = switch (op) {
|
||||||
|
case Star -> new Multiply(expr.asNumberExpr(), right);
|
||||||
|
case Slash -> new Divide(expr.asNumberExpr(), right);
|
||||||
|
case Percentage -> new Modulo(expr.asNumberExpr(), right);
|
||||||
|
default -> throw new IllegalStateException();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
@ -135,9 +156,8 @@ public class Parser {
|
|||||||
Expr<?> expr = unary();
|
Expr<?> expr = unary();
|
||||||
|
|
||||||
while (match(Token.UpArrow)) {
|
while (match(Token.UpArrow)) {
|
||||||
Token op = previous.token;
|
NumberExpr right = unary().asNumberExpr();
|
||||||
Expr<?> right = unary();
|
expr = new Power(expr.asNumberExpr(), right);
|
||||||
expr = new MathBiExpr(expr.asNumberExpr(), right.asNumberExpr(), op);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
@ -147,7 +167,11 @@ public class Parser {
|
|||||||
if (match(Token.Bang, Token.Minus)) {
|
if (match(Token.Bang, Token.Minus)) {
|
||||||
Token op = previous.token;
|
Token op = previous.token;
|
||||||
Expr<?> right = unary();
|
Expr<?> right = unary();
|
||||||
return op == Token.Bang ? new Not(right.asBoolExpr()) : new Invert(right.asNumberExpr());
|
return switch (op) {
|
||||||
|
case Bang -> new Not(right.asBoolExpr());
|
||||||
|
case Minus -> new Invert(right.asNumberExpr());
|
||||||
|
default -> throw new IllegalStateException();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return call();
|
return call();
|
||||||
@ -156,28 +180,27 @@ public class Parser {
|
|||||||
private Expr<?> call() {
|
private Expr<?> call() {
|
||||||
Expr<?> expr = primary();
|
Expr<?> expr = primary();
|
||||||
|
|
||||||
while (true) {
|
while (match(Token.LeftParen, Token.Dot, Token.LeftBracket)) {
|
||||||
if (match(Token.LeftParen)) {
|
expr = switch (previous.token) {
|
||||||
expr = finishCall(expr);
|
case LeftParen -> finishCall(expr);
|
||||||
}
|
case Dot -> {
|
||||||
else if (match(Token.Dot)) {
|
TokenData name = consume(Token.Identifier, "Expected field name after '.'.");
|
||||||
TokenData name = consume(Token.Identifier, "Expected field name after '.'.");
|
yield new Get(expr.asDynamicExpr(), Expr.literal(name.lexeme));
|
||||||
expr = new Get(expr.asDynamicExpr(), Expr.literal(name.lexeme));
|
}
|
||||||
}
|
case LeftBracket -> {
|
||||||
else if (match(Token.LeftBracket)) {
|
expr = new Get(expr.asDynamicExpr(), expression());
|
||||||
expr = new Get(expr.asDynamicExpr(), expression());
|
consume(Token.RightBracket, "Expected closing bracket");
|
||||||
consume(Token.RightBracket, "Expected closing bracket");
|
yield expr;
|
||||||
}
|
}
|
||||||
else {
|
default -> throw new IllegalStateException();
|
||||||
break;
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Expr<?> finishCall(Expr<?> callee) {
|
private Expr<?> finishCall(Expr<?> callee) {
|
||||||
List<Expr.DynamicExpr> args = new ArrayList<>(2);
|
List<DynamicExpr> args = new ArrayList<>(2);
|
||||||
|
|
||||||
if (!check(Token.RightParen)) {
|
if (!check(Token.RightParen)) {
|
||||||
do {
|
do {
|
||||||
@ -199,7 +222,7 @@ public class Parser {
|
|||||||
if (match(Token.LeftParen)) {
|
if (match(Token.LeftParen)) {
|
||||||
Expr<?> expr = expression();
|
Expr<?> expr = expression();
|
||||||
consume(Token.RightParen, "Expected ')' after expression.");
|
consume(Token.RightParen, "Expected ')' after expression.");
|
||||||
return new Group(expr);
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw error("Expected expression.");
|
throw error("Expected expression.");
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.*;
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.dynamic.*;
|
||||||
|
|
||||||
|
public abstract non-sealed class BoolExpr extends Expr<Boolean> {
|
||||||
|
@Override
|
||||||
|
public Type getResultType() {
|
||||||
|
return Type.Boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DynamicExpr asDynamicExpr() {
|
||||||
|
return new DynamicCoerce(this);
|
||||||
|
}
|
||||||
|
}
|
@ -1,31 +0,0 @@
|
|||||||
package io.gitlab.jfronny.muscript.compiler.expr;
|
|
||||||
|
|
||||||
import io.gitlab.jfronny.muscript.compiler.*;
|
|
||||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
|
||||||
|
|
||||||
public class Compare extends Expr.BoolExpr {
|
|
||||||
private final NumberExpr left;
|
|
||||||
private final NumberExpr right;
|
|
||||||
private final Token comparator;
|
|
||||||
|
|
||||||
public Compare(NumberExpr left, NumberExpr right, Token comparator) {
|
|
||||||
this.left = left;
|
|
||||||
this.right = right;
|
|
||||||
this.comparator = comparator;
|
|
||||||
if (comparator != Token.Greater && comparator != Token.GreaterEqual && comparator != Token.Less && comparator != Token.LessEqual)
|
|
||||||
throw new IllegalArgumentException("Compare only supports > >= < <= operators");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
double left = this.left.get(branch, dataRoot);
|
|
||||||
double right = this.right.get(branch, dataRoot);
|
|
||||||
return switch (comparator) {
|
|
||||||
case Greater -> left > right;
|
|
||||||
case GreaterEqual -> left >= right;
|
|
||||||
case Less -> left < right;
|
|
||||||
case LessEqual -> left <= right;
|
|
||||||
default -> throw new IllegalArgumentException();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,76 +0,0 @@
|
|||||||
package io.gitlab.jfronny.muscript.compiler.expr;
|
|
||||||
|
|
||||||
import io.gitlab.jfronny.muscript.compiler.*;
|
|
||||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
|
||||||
|
|
||||||
public class Conditional extends Expr {
|
|
||||||
public final BoolExpr condition;
|
|
||||||
public final Expr<?> trueExpr;
|
|
||||||
public final Expr<?> falseExpr;
|
|
||||||
|
|
||||||
public Conditional(BoolExpr condition, Expr<?> trueExpr, Expr<?> falseExpr) {
|
|
||||||
this.condition = condition;
|
|
||||||
this.trueExpr = trueExpr;
|
|
||||||
this.falseExpr = falseExpr;
|
|
||||||
if (trueExpr.getResultType() != falseExpr.getResultType())
|
|
||||||
throw new IllegalArgumentException("Values used in conditional operator must be of the same type");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getResultType() {
|
|
||||||
return trueExpr.getResultType();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object get(Dynamic branch, Dynamic dataRoot) {
|
|
||||||
return condition.get(branch, dataRoot) ? trueExpr.get(branch, dataRoot) : falseExpr.get(branch, dataRoot);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BoolExpr asBoolExpr() {
|
|
||||||
BoolExpr trueExpr = this.trueExpr.asBoolExpr();
|
|
||||||
BoolExpr falseExpr = this.falseExpr.asBoolExpr();
|
|
||||||
return new BoolExpr() {
|
|
||||||
@Override
|
|
||||||
public Boolean get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
return condition.get(branch, dataRoot) ? trueExpr.get(branch, dataRoot) : falseExpr.get(branch, dataRoot);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public StringExpr asStringExpr() {
|
|
||||||
StringExpr trueExpr = this.trueExpr.asStringExpr();
|
|
||||||
StringExpr falseExpr = this.falseExpr.asStringExpr();
|
|
||||||
return new StringExpr() {
|
|
||||||
@Override
|
|
||||||
public String get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
return condition.get(branch, dataRoot) ? trueExpr.get(branch, dataRoot) : falseExpr.get(branch, dataRoot);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NumberExpr asNumberExpr() {
|
|
||||||
NumberExpr trueExpr = this.trueExpr.asNumberExpr();
|
|
||||||
NumberExpr falseExpr = this.falseExpr.asNumberExpr();
|
|
||||||
return new NumberExpr() {
|
|
||||||
@Override
|
|
||||||
public Double get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
return condition.get(branch, dataRoot) ? trueExpr.get(branch, dataRoot) : falseExpr.get(branch, dataRoot);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DynamicExpr asDynamicExpr() {
|
|
||||||
DynamicExpr trueExpr = this.trueExpr.asDynamicExpr();
|
|
||||||
DynamicExpr falseExpr = this.falseExpr.asDynamicExpr();
|
|
||||||
return new DynamicExpr() {
|
|
||||||
@Override
|
|
||||||
public Dynamic<?> get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
return condition.get(branch, dataRoot) ? trueExpr.get(branch, dataRoot) : falseExpr.get(branch, dataRoot);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +1,32 @@
|
|||||||
package io.gitlab.jfronny.muscript.compiler.expr;
|
package io.gitlab.jfronny.muscript.compiler.expr;
|
||||||
|
|
||||||
import io.gitlab.jfronny.muscript.compiler.*;
|
import io.gitlab.jfronny.muscript.compiler.*;
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.dynamic.unpack.*;
|
||||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
public class Group extends Expr {
|
public abstract non-sealed class DynamicExpr extends Expr<Dynamic<?>> {
|
||||||
public final Expr expr;
|
|
||||||
|
|
||||||
public Group(Expr expr) {
|
|
||||||
this.expr = expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Type getResultType() {
|
public Type getResultType() {
|
||||||
return expr.getResultType();
|
return Type.Dynamic;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object get(Dynamic branch, Dynamic dataRoot) {
|
|
||||||
return expr.get(branch, dataRoot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BoolExpr asBoolExpr() {
|
public BoolExpr asBoolExpr() {
|
||||||
return expr.asBoolExpr();
|
return new BoolUnpack(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StringExpr asStringExpr() {
|
public StringExpr asStringExpr() {
|
||||||
return expr.asStringExpr();
|
return new StringUnpack(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NumberExpr asNumberExpr() {
|
public NumberExpr asNumberExpr() {
|
||||||
return expr.asNumberExpr();
|
return new NumberUnpack(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DynamicExpr asDynamicExpr() {
|
public DynamicExpr asDynamicExpr() {
|
||||||
return expr.asDynamicExpr();
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.*;
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.*;
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.string.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public sealed abstract class Expr<T> permits BoolExpr, DynamicExpr, NullLiteral, NumberExpr, StringExpr {
|
||||||
|
public abstract Type getResultType();
|
||||||
|
public abstract T get(Dynamic<?> branch, Dynamic<?> dataRoot);
|
||||||
|
|
||||||
|
public T get(Dynamic<?> branch) {
|
||||||
|
return get(branch, branch);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoolExpr asBoolExpr() {
|
||||||
|
if (this instanceof BoolExpr e) return e;
|
||||||
|
throw new IllegalArgumentException("Expected boolean but is " + getResultType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringExpr asStringExpr() {
|
||||||
|
if (this instanceof StringExpr e) return e;
|
||||||
|
return new StringCoerce(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NumberExpr asNumberExpr() {
|
||||||
|
if (this instanceof NumberExpr e) return e;
|
||||||
|
throw new IllegalArgumentException("Expected number but is " + getResultType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract DynamicExpr asDynamicExpr();
|
||||||
|
|
||||||
|
public boolean isNull() {
|
||||||
|
return this instanceof NullLiteral;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BoolExpr literal(boolean bool) {
|
||||||
|
return new BoolLiteral(bool);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StringExpr literal(String string) {
|
||||||
|
return new StringLiteral(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NumberExpr literal(double number) {
|
||||||
|
return new NumberLiteral(number);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Expr<?> literalNull() {
|
||||||
|
return new NullLiteral();
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +0,0 @@
|
|||||||
package io.gitlab.jfronny.muscript.compiler.expr;
|
|
||||||
|
|
||||||
import io.gitlab.jfronny.muscript.compiler.*;
|
|
||||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
|
||||||
|
|
||||||
public class Invert extends Expr.NumberExpr {
|
|
||||||
private final Expr.NumberExpr inner;
|
|
||||||
|
|
||||||
public Invert(Expr.NumberExpr inner) {
|
|
||||||
this.inner = inner;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Double get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
return -inner.get(branch, dataRoot);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
package io.gitlab.jfronny.muscript.compiler.expr;
|
|
||||||
|
|
||||||
import io.gitlab.jfronny.muscript.compiler.*;
|
|
||||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
|
||||||
|
|
||||||
public class LogicBiExpr extends Expr.BoolExpr {
|
|
||||||
private final Expr.BoolExpr left;
|
|
||||||
private final Expr.BoolExpr right;
|
|
||||||
private final Token comparator;
|
|
||||||
|
|
||||||
public LogicBiExpr(Expr.BoolExpr left, Expr.BoolExpr right, Token fnc) {
|
|
||||||
this.left = left;
|
|
||||||
this.right = right;
|
|
||||||
this.comparator = fnc;
|
|
||||||
if (fnc != Token.And && fnc != Token.Or && fnc != Token.UpArrow)
|
|
||||||
throw new IllegalArgumentException("Logic only supports & | ^ operators");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
boolean left = this.left.get(branch, dataRoot);
|
|
||||||
boolean right = this.right.get(branch, dataRoot);
|
|
||||||
return switch (comparator) {
|
|
||||||
case And -> left & right;
|
|
||||||
case Or -> left | right;
|
|
||||||
case UpArrow -> left ^ right;
|
|
||||||
default -> throw new IllegalArgumentException();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package io.gitlab.jfronny.muscript.compiler.expr;
|
|
||||||
|
|
||||||
import io.gitlab.jfronny.muscript.compiler.*;
|
|
||||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
|
||||||
|
|
||||||
public class MathBiExpr extends Expr.NumberExpr {
|
|
||||||
private final NumberExpr left;
|
|
||||||
private final NumberExpr right;
|
|
||||||
private final Token comparator;
|
|
||||||
|
|
||||||
public MathBiExpr(NumberExpr left, NumberExpr right, Token fnc) {
|
|
||||||
this.left = left;
|
|
||||||
this.right = right;
|
|
||||||
this.comparator = fnc;
|
|
||||||
if (fnc != Token.Plus && fnc != Token.Minus && fnc != Token.Star && fnc != Token.Slash && fnc != Token.UpArrow && fnc != Token.Percentage)
|
|
||||||
throw new IllegalArgumentException("Math only supports + - * / operators");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Double get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
|
||||||
double left = this.left.get(branch, dataRoot);
|
|
||||||
double right = this.right.get(branch, dataRoot);
|
|
||||||
return switch (comparator) {
|
|
||||||
case Plus -> left + right;
|
|
||||||
case Minus -> left - right;
|
|
||||||
case Star -> left * right;
|
|
||||||
case Slash -> left / right;
|
|
||||||
case UpArrow -> Math.pow(left, right);
|
|
||||||
case Percentage -> left % right;
|
|
||||||
default -> throw new IllegalArgumentException();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,22 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.*;
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.common.literal.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public final class NullLiteral extends Expr<Object> {
|
||||||
|
@Override
|
||||||
|
public Type getResultType() {
|
||||||
|
return Type.Dynamic;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DynamicExpr asDynamicExpr() {
|
||||||
|
return new DynamicLiteral<>(new DNull());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.*;
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.dynamic.*;
|
||||||
|
|
||||||
|
public abstract non-sealed class NumberExpr extends Expr<Double> {
|
||||||
|
@Override
|
||||||
|
public Type getResultType() {
|
||||||
|
return Type.Number;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DynamicExpr asDynamicExpr() {
|
||||||
|
return new DynamicCoerce(this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.*;
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.dynamic.*;
|
||||||
|
|
||||||
|
public abstract non-sealed class StringExpr extends Expr<String> {
|
||||||
|
@Override
|
||||||
|
public Type getResultType() {
|
||||||
|
return Type.String;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DynamicExpr asDynamicExpr() {
|
||||||
|
return new DynamicCoerce(this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.bool;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class And extends BoolExpr {
|
||||||
|
private final BoolExpr left;
|
||||||
|
private final BoolExpr right;
|
||||||
|
|
||||||
|
public And(BoolExpr left, BoolExpr right) {
|
||||||
|
this.left = left;
|
||||||
|
this.right = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return left.get(branch, dataRoot) && right.get(branch, dataRoot);
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
package io.gitlab.jfronny.muscript.compiler.expr;
|
package io.gitlab.jfronny.muscript.compiler.expr.bool;
|
||||||
|
|
||||||
import io.gitlab.jfronny.muscript.compiler.*;
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
public class Not extends Expr.BoolExpr {
|
public class Not extends BoolExpr {
|
||||||
private final BoolExpr inner;
|
private final BoolExpr inner;
|
||||||
|
|
||||||
public Not(BoolExpr inner) {
|
public Not(BoolExpr inner) {
|
@ -0,0 +1,19 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.bool;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class Or extends BoolExpr {
|
||||||
|
private final BoolExpr left;
|
||||||
|
private final BoolExpr right;
|
||||||
|
|
||||||
|
public Or(BoolExpr left, BoolExpr right) {
|
||||||
|
this.left = left;
|
||||||
|
this.right = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return left.get(branch, dataRoot) || right.get(branch, dataRoot);
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,11 @@
|
|||||||
package io.gitlab.jfronny.muscript.compiler.expr;
|
package io.gitlab.jfronny.muscript.compiler.expr.common;
|
||||||
|
|
||||||
import io.gitlab.jfronny.muscript.compiler.*;
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class Equal extends Expr.BoolExpr {
|
public class Equal extends BoolExpr {
|
||||||
private final Expr<?> left;
|
private final Expr<?> left;
|
||||||
private final Expr<?> right;
|
private final Expr<?> right;
|
||||||
|
|
@ -0,0 +1,23 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.common.conditional;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class BoolConditional extends BoolExpr {
|
||||||
|
public final BoolExpr condition;
|
||||||
|
public final BoolExpr trueExpr;
|
||||||
|
public final BoolExpr falseExpr;
|
||||||
|
|
||||||
|
public BoolConditional(BoolExpr condition, BoolExpr trueExpr, BoolExpr falseExpr) {
|
||||||
|
this.condition = condition;
|
||||||
|
this.trueExpr = trueExpr;
|
||||||
|
this.falseExpr = falseExpr;
|
||||||
|
if (trueExpr.getResultType() != falseExpr.getResultType())
|
||||||
|
throw new IllegalArgumentException("Values used in conditional operator must be of the same type");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return condition.get(branch, dataRoot) ? trueExpr.get(branch, dataRoot) : falseExpr.get(branch, dataRoot);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.common.conditional;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class DynamicConditional extends DynamicExpr {
|
||||||
|
public final BoolExpr condition;
|
||||||
|
public final DynamicExpr trueExpr;
|
||||||
|
public final DynamicExpr falseExpr;
|
||||||
|
|
||||||
|
public DynamicConditional(BoolExpr condition, DynamicExpr trueExpr, DynamicExpr falseExpr) {
|
||||||
|
this.condition = condition;
|
||||||
|
this.trueExpr = trueExpr;
|
||||||
|
this.falseExpr = falseExpr;
|
||||||
|
if (trueExpr.getResultType() != falseExpr.getResultType())
|
||||||
|
throw new IllegalArgumentException("Values used in conditional operator must be of the same type");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dynamic get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return condition.get(branch, dataRoot) ? trueExpr.get(branch, dataRoot) : falseExpr.get(branch, dataRoot);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.common.conditional;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class NumberConditional extends NumberExpr {
|
||||||
|
public final BoolExpr condition;
|
||||||
|
public final NumberExpr trueExpr;
|
||||||
|
public final NumberExpr falseExpr;
|
||||||
|
|
||||||
|
public NumberConditional(BoolExpr condition, NumberExpr trueExpr, NumberExpr falseExpr) {
|
||||||
|
this.condition = condition;
|
||||||
|
this.trueExpr = trueExpr;
|
||||||
|
this.falseExpr = falseExpr;
|
||||||
|
if (trueExpr.getResultType() != falseExpr.getResultType())
|
||||||
|
throw new IllegalArgumentException("Values used in conditional operator must be of the same type");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Double get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return condition.get(branch, dataRoot) ? trueExpr.get(branch, dataRoot) : falseExpr.get(branch, dataRoot);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.common.conditional;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class StringConditional extends StringExpr {
|
||||||
|
public final BoolExpr condition;
|
||||||
|
public final StringExpr trueExpr;
|
||||||
|
public final StringExpr falseExpr;
|
||||||
|
|
||||||
|
public StringConditional(BoolExpr condition, StringExpr trueExpr, StringExpr falseExpr) {
|
||||||
|
this.condition = condition;
|
||||||
|
this.trueExpr = trueExpr;
|
||||||
|
this.falseExpr = falseExpr;
|
||||||
|
if (trueExpr.getResultType() != falseExpr.getResultType())
|
||||||
|
throw new IllegalArgumentException("Values used in conditional operator must be of the same type");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return condition.get(branch, dataRoot) ? trueExpr.get(branch, dataRoot) : falseExpr.get(branch, dataRoot);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.common.literal;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public final class BoolLiteral extends BoolExpr {
|
||||||
|
private final boolean value;
|
||||||
|
|
||||||
|
public BoolLiteral(boolean value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.common.literal;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public final class DynamicLiteral<T> extends DynamicExpr {
|
||||||
|
private final Dynamic<T> value;
|
||||||
|
|
||||||
|
public DynamicLiteral(Dynamic<T> value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dynamic<T> get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.common.literal;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public final class NumberLiteral extends NumberExpr {
|
||||||
|
private final double value;
|
||||||
|
|
||||||
|
public NumberLiteral(double value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Double get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.common.literal;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public final class StringLiteral extends StringExpr {
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
public StringLiteral(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,11 @@
|
|||||||
package io.gitlab.jfronny.muscript.compiler.expr;
|
package io.gitlab.jfronny.muscript.compiler.expr.dynamic;
|
||||||
|
|
||||||
import io.gitlab.jfronny.muscript.compiler.*;
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class Call extends Expr.DynamicExpr {
|
public class Call extends DynamicExpr {
|
||||||
private final DynamicExpr left;
|
private final DynamicExpr left;
|
||||||
private final List<DynamicExpr> args;
|
private final List<DynamicExpr> args;
|
||||||
|
|
@ -0,0 +1,27 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.dynamic;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class DynamicCoerce extends DynamicExpr {
|
||||||
|
private final Expr<?> inner;
|
||||||
|
|
||||||
|
public DynamicCoerce(Expr<?> inner) {
|
||||||
|
this.inner = inner;
|
||||||
|
if (!(inner instanceof DynamicExpr)
|
||||||
|
&& !(inner instanceof BoolExpr)
|
||||||
|
&& !(inner instanceof StringExpr)
|
||||||
|
&& !(inner instanceof NumberExpr)) {
|
||||||
|
throw new IllegalArgumentException("A DynamicCoerce can only be created with a well-defined expression type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dynamic<?> get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
if (inner instanceof DynamicExpr e) return e.get(branch, dataRoot);
|
||||||
|
if (inner instanceof BoolExpr e) return DFinal.of(e.get(branch, dataRoot));
|
||||||
|
if (inner instanceof StringExpr e) return DFinal.of(e.get(branch, dataRoot));
|
||||||
|
if (inner instanceof NumberExpr e) return DFinal.of(e.get(branch, dataRoot));
|
||||||
|
throw new IllegalStateException("The inner expression of DynamicCoerce should never be of undefined type");
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,10 @@
|
|||||||
package io.gitlab.jfronny.muscript.compiler.expr;
|
package io.gitlab.jfronny.muscript.compiler.expr.dynamic;
|
||||||
|
|
||||||
import io.gitlab.jfronny.muscript.compiler.*;
|
import io.gitlab.jfronny.muscript.compiler.*;
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
public class Get extends Expr.DynamicExpr {
|
public class Get extends DynamicExpr {
|
||||||
private final DynamicExpr left;
|
private final DynamicExpr left;
|
||||||
private final Expr<?> name;
|
private final Expr<?> name;
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
package io.gitlab.jfronny.muscript.compiler.expr;
|
package io.gitlab.jfronny.muscript.compiler.expr.dynamic;
|
||||||
|
|
||||||
import io.gitlab.jfronny.muscript.compiler.*;
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
public class Variable extends Expr.DynamicExpr {
|
public class Variable extends DynamicExpr {
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
public Variable(String name) {
|
public Variable(String name) {
|
@ -0,0 +1,17 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.dynamic.unpack;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class BoolUnpack extends BoolExpr {
|
||||||
|
private final DynamicExpr inner;
|
||||||
|
|
||||||
|
public BoolUnpack(DynamicExpr inner) {
|
||||||
|
this.inner = inner;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return inner.get(branch, dataRoot).asBool().getValue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.dynamic.unpack;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class NumberUnpack extends NumberExpr {
|
||||||
|
private final DynamicExpr inner;
|
||||||
|
|
||||||
|
public NumberUnpack(DynamicExpr inner) {
|
||||||
|
this.inner = inner;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Double get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return inner.get(branch, dataRoot).asNumber().getValue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.dynamic.unpack;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class StringUnpack extends StringExpr {
|
||||||
|
private final DynamicExpr inner;
|
||||||
|
|
||||||
|
public StringUnpack(DynamicExpr inner) {
|
||||||
|
this.inner = inner;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return inner.get(branch, dataRoot).asString().getValue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.number.compare;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class Greater extends BoolExpr {
|
||||||
|
private final NumberExpr left;
|
||||||
|
private final NumberExpr right;
|
||||||
|
|
||||||
|
public Greater(NumberExpr left, NumberExpr right) {
|
||||||
|
this.left = left;
|
||||||
|
this.right = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return left.get(branch, dataRoot) > right.get(branch, dataRoot);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.number.compare;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class Less extends BoolExpr {
|
||||||
|
private final NumberExpr left;
|
||||||
|
private final NumberExpr right;
|
||||||
|
|
||||||
|
public Less(NumberExpr left, NumberExpr right) {
|
||||||
|
this.left = left;
|
||||||
|
this.right = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return left.get(branch, dataRoot) < right.get(branch, dataRoot);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.number.math;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class Divide extends NumberExpr {
|
||||||
|
private final NumberExpr dividend;
|
||||||
|
private final NumberExpr divisor;
|
||||||
|
|
||||||
|
public Divide(NumberExpr dividend, NumberExpr divisor) {
|
||||||
|
this.dividend = dividend;
|
||||||
|
this.divisor = divisor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Double get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return dividend.get(branch, dataRoot) / divisor.get(branch, dataRoot);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.number.math;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class Invert extends NumberExpr {
|
||||||
|
private final NumberExpr inner;
|
||||||
|
|
||||||
|
public Invert(NumberExpr inner) {
|
||||||
|
this.inner = inner;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Double get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return -inner.get(branch, dataRoot);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.number.math;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class Minus extends NumberExpr {
|
||||||
|
private final NumberExpr minuend;
|
||||||
|
private final NumberExpr subtrahend;
|
||||||
|
|
||||||
|
public Minus(NumberExpr minuend, NumberExpr subtrahend) {
|
||||||
|
this.minuend = minuend;
|
||||||
|
this.subtrahend = subtrahend;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Double get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return minuend.get(branch, dataRoot) - subtrahend.get(branch, dataRoot);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.number.math;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class Modulo extends NumberExpr {
|
||||||
|
private final NumberExpr dividend;
|
||||||
|
private final NumberExpr divisor;
|
||||||
|
|
||||||
|
public Modulo(NumberExpr dividend, NumberExpr divisor) {
|
||||||
|
this.dividend = dividend;
|
||||||
|
this.divisor = divisor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Double get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return dividend.get(branch, dataRoot) % divisor.get(branch, dataRoot);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.number.math;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class Multiply extends NumberExpr {
|
||||||
|
private final NumberExpr multiplier;
|
||||||
|
private final NumberExpr multiplicand;
|
||||||
|
|
||||||
|
public Multiply(NumberExpr multiplier, NumberExpr multiplicand) {
|
||||||
|
this.multiplier = multiplier;
|
||||||
|
this.multiplicand = multiplicand;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Double get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return multiplier.get(branch, dataRoot) * multiplicand.get(branch, dataRoot);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.number.math;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class Plus extends NumberExpr {
|
||||||
|
private final NumberExpr augend;
|
||||||
|
private final NumberExpr addend;
|
||||||
|
|
||||||
|
public Plus(NumberExpr augend, NumberExpr addend) {
|
||||||
|
this.augend = augend;
|
||||||
|
this.addend = addend;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Double get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return augend.get(branch, dataRoot) + addend.get(branch, dataRoot);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.number.math;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class Power extends NumberExpr {
|
||||||
|
private final NumberExpr base;
|
||||||
|
private final NumberExpr exponent;
|
||||||
|
|
||||||
|
public Power(NumberExpr base, NumberExpr exponent) {
|
||||||
|
this.base = base;
|
||||||
|
this.exponent = exponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Double get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return Math.pow(base.get(branch, dataRoot), exponent.get(branch, dataRoot));
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
package io.gitlab.jfronny.muscript.compiler.expr;
|
package io.gitlab.jfronny.muscript.compiler.expr.string;
|
||||||
|
|
||||||
import io.gitlab.jfronny.muscript.compiler.*;
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
public class Concatenate extends Expr.StringExpr {
|
public class Concatenate extends StringExpr {
|
||||||
private final StringExpr left;
|
private final StringExpr left;
|
||||||
private final StringExpr right;
|
private final StringExpr right;
|
||||||
|
|
@ -0,0 +1,18 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.string;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.commons.*;
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class StringCoerce extends StringExpr {
|
||||||
|
private final Expr<?> inner;
|
||||||
|
|
||||||
|
public StringCoerce(Expr<?> inner) {
|
||||||
|
this.inner = inner;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String get(Dynamic<?> branch, Dynamic<?> dataRoot) {
|
||||||
|
return StringFormatter.toString(inner.get(branch, dataRoot));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package io.gitlab.jfronny.muscript.compiler.expr.unresolved;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.*;
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.common.conditional.*;
|
||||||
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
public class UnresolvedConditional extends DynamicExpr {
|
||||||
|
private final BoolExpr condition;
|
||||||
|
private final Expr<?> trueExpr;
|
||||||
|
private final Expr<?> falseExpr;
|
||||||
|
|
||||||
|
public UnresolvedConditional(BoolExpr condition, Expr<?> trueExpr, Expr<?> falseExpr) {
|
||||||
|
this.condition = condition;
|
||||||
|
this.trueExpr = trueExpr;
|
||||||
|
this.falseExpr = falseExpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getResultType() {
|
||||||
|
return trueExpr.getResultType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dynamic get(Dynamic branch, Dynamic dataRoot) {
|
||||||
|
throw new UnsupportedOperationException("Conditional was kept unresolved. This is not supported!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DynamicExpr asDynamicExpr() {
|
||||||
|
return new DynamicConditional(condition, trueExpr.asDynamicExpr(), falseExpr.asDynamicExpr());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BoolExpr asBoolExpr() {
|
||||||
|
return new BoolConditional(condition, trueExpr.asBoolExpr(), falseExpr.asBoolExpr());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringExpr asStringExpr() {
|
||||||
|
return new StringConditional(condition, trueExpr.asStringExpr(), falseExpr.asStringExpr());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NumberExpr asNumberExpr() {
|
||||||
|
return new NumberConditional(condition, trueExpr.asNumberExpr(), falseExpr.asNumberExpr());
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package io.gitlab.jfronny.muscript.test;
|
package io.gitlab.jfronny.muscript.test;
|
||||||
|
|
||||||
import io.gitlab.jfronny.muscript.compiler.*;
|
import io.gitlab.jfronny.muscript.compiler.*;
|
||||||
|
import io.gitlab.jfronny.muscript.compiler.expr.*;
|
||||||
import io.gitlab.jfronny.muscript.debug.*;
|
import io.gitlab.jfronny.muscript.debug.*;
|
||||||
import io.gitlab.jfronny.muscript.dynamic.*;
|
import io.gitlab.jfronny.muscript.dynamic.*;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user