diff --git a/muscript/build.gradle.kts b/muscript/build.gradle.kts deleted file mode 100644 index d8fadf2..0000000 --- a/muscript/build.gradle.kts +++ /dev/null @@ -1,27 +0,0 @@ -import io.gitlab.jfronny.scripts.* - -plugins { - commons.library -} - -dependencies { - implementation(projects.commons) - - testImplementation(libs.junit.jupiter.api) - testRuntimeOnly(libs.junit.jupiter.engine) -} - -publishing { - publications { - create("maven") { - groupId = "io.gitlab.jfronny" - artifactId = "muscript" - - from(components["java"]) - } - } -} - -tasks.javadoc { - linksOffline("https://maven.frohnmeyer-wds.de/javadoc/artifacts/io/gitlab/jfronny/commons/$version/raw", projects.commons) -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/StarScriptIngester.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/StarScriptIngester.java deleted file mode 100644 index a137bee..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/StarScriptIngester.java +++ /dev/null @@ -1,82 +0,0 @@ -package io.gitlab.jfronny.muscript; - -import io.gitlab.jfronny.muscript.compiler.Decompilable; - -public class StarScriptIngester { - private static final System.Logger LOGGER = System.getLogger("MuScript"); - - /** - * Naive conversion of starscript syntax to muscript - */ - public static String starScriptToMu(String source) { - StringBuilder result = new StringBuilder(); - StringBuilder currbuf = new StringBuilder(); - State state = State.Surrounding; - for (char c : source.toCharArray()) { - switch (state) { - case Surrounding -> { - if (c == '{') { - if (!currbuf.isEmpty()) { - if (!result.isEmpty()) result.append(" || "); - result.append(Decompilable.enquote(currbuf.toString())); - } - currbuf = new StringBuilder(); - state = State.UnquotedInner; - } else currbuf.append(c); - } - case UnquotedInner -> { - switch (c) { - case '}' -> { - if (!currbuf.isEmpty()) { - if (!result.isEmpty()) result.append(" || "); - result.append("(").append(currbuf).append(")"); - } - currbuf = new StringBuilder(); - state = State.Surrounding; - } - case '\'' -> { - currbuf.append(c); - state = State.SingleQuoteInner; - } - case '"' -> { - currbuf.append(c); - state = State.DoubleQuoteInner; - } - default -> currbuf.append(c); - } - } - case SingleQuoteInner -> { - currbuf.append(c); - if (c == '\'') state = State.UnquotedInner; - } - case DoubleQuoteInner -> { - currbuf.append(c); - if (c == '"') state = State.UnquotedInner; - } - } - } - if (!currbuf.isEmpty() && !result.isEmpty()) result.append(" || "); - switch (state) { - case Surrounding -> { - if (!currbuf.isEmpty()) result.append(Decompilable.enquote(currbuf.toString())); - } - case UnquotedInner -> { - LOGGER.log(System.Logger.Level.WARNING, "Starscript code segment improperly closed, closing automatically"); - if (!currbuf.isEmpty()) result.append("(").append(currbuf).append(")"); - } - case SingleQuoteInner -> { - LOGGER.log(System.Logger.Level.WARNING, "Quote in starscript swallows ending, completing with closing quote"); - if (!currbuf.isEmpty()) result.append("(").append(currbuf).append("')"); - } - case DoubleQuoteInner -> { - LOGGER.log(System.Logger.Level.WARNING, "Quote in starscript swallows ending, completing with closing quote"); - if (!currbuf.isEmpty()) result.append("(").append(currbuf).append("\")"); - } - } - return result.toString(); - } - - enum State { - Surrounding, UnquotedInner, SingleQuoteInner, DoubleQuoteInner - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/annotations/CanThrow.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/annotations/CanThrow.java deleted file mode 100644 index 8f11304..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/annotations/CanThrow.java +++ /dev/null @@ -1,12 +0,0 @@ -package io.gitlab.jfronny.muscript.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; - -/** - * Annotation for expressions that may throw exceptions - * Any expression that doesn't have this annotation will only throw if an expression referenced from it throws - */ -@Target(ElementType.TYPE) -public @interface CanThrow { -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/annotations/UncheckedDynamic.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/annotations/UncheckedDynamic.java deleted file mode 100644 index caa8593..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/annotations/UncheckedDynamic.java +++ /dev/null @@ -1,12 +0,0 @@ -package io.gitlab.jfronny.muscript.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; - -/** - * Annotation for expressions that utilize Dynamic.as* - * These expressions must also be annotated with @CanThrow - */ -@Target(ElementType.TYPE) -public @interface UncheckedDynamic { -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/BoolExpr.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/BoolExpr.java deleted file mode 100644 index 94df0ef..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/BoolExpr.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.gitlab.jfronny.muscript.ast; - -import io.gitlab.jfronny.muscript.ast.dynamic.DynamicCoerce; -import io.gitlab.jfronny.muscript.compiler.*; - -public abstract non-sealed class BoolExpr extends Expr { - protected BoolExpr(Order order, CodeLocation location) { - super(order, location); - } - - @Override - public Type getResultType() { - return Type.Boolean; - } - - @Override - public abstract BoolExpr optimize(); - - @Override - public DynamicExpr asDynamicExpr() { - return new DynamicCoerce(location, this); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/DynamicExpr.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/DynamicExpr.java deleted file mode 100644 index f8185fd..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/DynamicExpr.java +++ /dev/null @@ -1,39 +0,0 @@ -package io.gitlab.jfronny.muscript.ast; - -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.dynamic.Dynamic; -import io.gitlab.jfronny.muscript.ast.dynamic.unpack.*; - -public abstract non-sealed class DynamicExpr extends Expr { - protected DynamicExpr(Order order, CodeLocation location) { - super(order, location); - } - - @Override - public Type getResultType() { - return Type.Dynamic; - } - - @Override - public abstract DynamicExpr optimize(); - - @Override - public BoolExpr asBoolExpr() { - return new BoolUnpack(location, this); - } - - @Override - public StringExpr asStringExpr() { - return new StringUnpack(location, this); - } - - @Override - public NumberExpr asNumberExpr() { - return new NumberUnpack(location, this); - } - - @Override - public DynamicExpr asDynamicExpr() { - return this; - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/Expr.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/Expr.java deleted file mode 100644 index 2ff7de5..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/Expr.java +++ /dev/null @@ -1,84 +0,0 @@ -package io.gitlab.jfronny.muscript.ast; - -import io.gitlab.jfronny.muscript.annotations.CanThrow; -import io.gitlab.jfronny.muscript.ast.literal.*; -import io.gitlab.jfronny.muscript.ast.string.StringCoerce; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.DObject; -import io.gitlab.jfronny.muscript.data.dynamic.Dynamic; -import io.gitlab.jfronny.muscript.error.TypeMismatchException; - -import java.util.stream.Stream; - -@CanThrow -public abstract sealed class Expr extends Decompilable - permits BoolExpr, DynamicExpr, NullLiteral, NumberExpr, StringExpr { - public final CodeLocation location; - protected Expr(Order order, CodeLocation location) { - super(order); - this.location = location; - } - - public abstract Type getResultType(); - public abstract T get(Scope dataRoot); - public T get(DObject dataRoot) { - return get(dataRoot instanceof Scope scope ? scope : new Scope(dataRoot)); - } - public abstract Expr optimize(); - - public BoolExpr asBoolExpr() { - if (this instanceof BoolExpr e) return e; - throw new TypeMismatchException(location, Type.Boolean, getResultType()); - } - - public StringExpr asStringExpr() { - if (this instanceof StringExpr e) return e; - return new StringCoerce(location, this); - } - - public NumberExpr asNumberExpr() { - if (this instanceof NumberExpr e) return e; - throw new TypeMismatchException(location, Type.Number, getResultType()); - } - - public abstract DynamicExpr asDynamicExpr(); - - public abstract Stream> extractSideEffects(); - - public boolean isNull() { - return this instanceof NullLiteral; - } - - public static BoolExpr literal(boolean bool) { - return literal(CodeLocation.NONE, bool); - } - - public static StringExpr literal(String string) { - return literal(CodeLocation.NONE, string); - } - - public static NumberExpr literal(double number) { - return literal(CodeLocation.NONE, number); - } - - public static NullLiteral literalNull() { - return literalNull(CodeLocation.NONE); - } - - public static BoolExpr literal(CodeLocation location, boolean bool) { - return new BoolLiteral(location, bool); - } - - public static StringExpr literal(CodeLocation location, String string) { - return new StringLiteral(location, string); - } - - public static NumberExpr literal(CodeLocation location, double number) { - return new NumberLiteral(location, number); - } - - public static NullLiteral literalNull(CodeLocation location) { - return new NullLiteral(location); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/NullLiteral.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/NullLiteral.java deleted file mode 100644 index febecf6..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/NullLiteral.java +++ /dev/null @@ -1,68 +0,0 @@ -package io.gitlab.jfronny.muscript.ast; - -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.DNull; -import io.gitlab.jfronny.muscript.annotations.CanThrow; -import io.gitlab.jfronny.muscript.ast.literal.DynamicLiteral; -import io.gitlab.jfronny.muscript.error.LocationalException; - -import java.io.IOException; -import java.util.stream.Stream; - -@CanThrow -public final class NullLiteral extends Expr { - public NullLiteral(CodeLocation location) { - super(Order.Primary, location); - } - - @Override - public Type getResultType() { - return Type.Dynamic; - } - - @Override - public Object get(Scope dataRoot) { - return null; - } - - @Override - public NullLiteral optimize() { - return this; - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - writer.append("null"); - } - - @Override - public DynamicExpr asDynamicExpr() { - return new DynamicLiteral<>(location, new DNull()); - } - - @Override - public Stream> extractSideEffects() { - return Stream.empty(); - } - - @Override - public NumberExpr asNumberExpr() { - throw new LocationalException(location, "Attempted to convert null to a number"); - } - - @Override - public StringExpr asStringExpr() { - return literal(location, "null"); - } - - @Override - public BoolExpr asBoolExpr() { - throw new LocationalException(location, "Attempted to convert null to a boolean"); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof NullLiteral; - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/NumberExpr.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/NumberExpr.java deleted file mode 100644 index edcb0ae..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/NumberExpr.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.gitlab.jfronny.muscript.ast; - -import io.gitlab.jfronny.muscript.ast.dynamic.DynamicCoerce; -import io.gitlab.jfronny.muscript.compiler.*; - -public abstract non-sealed class NumberExpr extends Expr { - protected NumberExpr(Order order, CodeLocation location) { - super(order, location); - } - - @Override - public Type getResultType() { - return Type.Number; - } - - @Override - public abstract NumberExpr optimize(); - - @Override - public DynamicExpr asDynamicExpr() { - return new DynamicCoerce(location, this); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/StringExpr.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/StringExpr.java deleted file mode 100644 index 0e98721..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/StringExpr.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.gitlab.jfronny.muscript.ast; - -import io.gitlab.jfronny.muscript.ast.dynamic.DynamicCoerce; -import io.gitlab.jfronny.muscript.compiler.*; - -public abstract non-sealed class StringExpr extends Expr { - protected StringExpr(Order order, CodeLocation location) { - super(order, location); - } - - @Override - public Type getResultType() { - return Type.String; - } - - @Override - public abstract StringExpr optimize(); - - @Override - public DynamicExpr asDynamicExpr() { - return new DynamicCoerce(location, this); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/bool/And.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/bool/And.java deleted file mode 100644 index 409e1ec..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/bool/And.java +++ /dev/null @@ -1,52 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.bool; - -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.ast.BoolExpr; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.literal.BoolLiteral; - -import java.io.IOException; -import java.util.stream.Stream; - -public class And extends BoolExpr { - private final BoolExpr left; - private final BoolExpr right; - - public And(CodeLocation location, BoolExpr left, BoolExpr right) { - super(Order.And, location); - this.left = left; - this.right = right; - } - - @Override - public Boolean get(Scope 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 : literal(location, false); - if (right instanceof BoolLiteral literal) return literal.value ? left : literal(location, false); - return new And(location, left, right); - } - - @Override - public Stream> extractSideEffects() { - return Stream.concat(left.extractSideEffects(), right.extractSideEffects()); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - parenthesize(left, writer, false); - writer.append(" & "); - parenthesize(right, writer, true); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof And and && left.equals(and.left) && right.equals(and.right); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/bool/Not.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/bool/Not.java deleted file mode 100644 index 67a5b15..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/bool/Not.java +++ /dev/null @@ -1,67 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.bool; - -import io.gitlab.jfronny.muscript.ast.compare.Equal; -import io.gitlab.jfronny.muscript.ast.compare.Greater; -import io.gitlab.jfronny.muscript.ast.literal.NumberLiteral; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.ast.BoolExpr; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.literal.BoolLiteral; - -import java.io.IOException; -import java.util.stream.Stream; - -public class Not extends BoolExpr { - public final BoolExpr inner; - - public Not(CodeLocation location, BoolExpr inner) { - super(Order.Unary, location); - this.inner = inner; - } - - @Override - public Boolean get(Scope 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 literal(location, !literal.value); - return new Not(location, inner); - } - - @Override - public Stream> extractSideEffects() { - return inner.extractSideEffects(); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - if (inner instanceof Equal eq) { - parenthesize(eq.left, writer, false); - writer.append(" != "); - parenthesize(eq.right, writer, true); - } else if (inner instanceof Greater gt) { - if (gt.left instanceof NumberLiteral && !(gt.right instanceof NumberLiteral)) { - parenthesize(gt.right, writer, false); - writer.append(" >= "); - parenthesize(gt.left, writer, true); - } else { - parenthesize(gt.left, writer, false); - writer.append(" <= "); - parenthesize(gt.right, writer, true); - } - } else { - writer.append("!"); - parenthesize(inner, writer, false); - } - } - - @Override - public boolean equals(Object obj) { - return obj instanceof Not not && inner.equals(not.inner); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/bool/Or.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/bool/Or.java deleted file mode 100644 index 5af04b0..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/bool/Or.java +++ /dev/null @@ -1,52 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.bool; - -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.ast.BoolExpr; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.literal.BoolLiteral; - -import java.io.IOException; -import java.util.stream.Stream; - -public class Or extends BoolExpr { - private final BoolExpr left; - private final BoolExpr right; - - public Or(CodeLocation location, BoolExpr left, BoolExpr right) { - super(Order.Or, location); - this.left = left; - this.right = right; - } - - @Override - public Boolean get(Scope 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 ? literal(location, true) : right; - if (right instanceof BoolLiteral literal) return literal.value ? literal(location, true) : left; - return new Or(location, left, right); - } - - @Override - public Stream> extractSideEffects() { - return Stream.concat(left.extractSideEffects(), right.extractSideEffects()); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - parenthesize(left, writer, false); - writer.append(" | "); - parenthesize(right, writer, true); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof Or or && left.equals(or.left) && right.equals(or.right); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/compare/Equal.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/compare/Equal.java deleted file mode 100644 index ae5125a..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/compare/Equal.java +++ /dev/null @@ -1,57 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.compare; - -import io.gitlab.jfronny.muscript.ast.BoolExpr; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.Dynamic; - -import java.io.IOException; -import java.util.Objects; -import java.util.stream.Stream; - -public class Equal extends BoolExpr { - public final Expr left; - public final Expr right; - - public Equal(CodeLocation location, Expr left, Expr right) { - super(Order.Equality, location); - this.left = left; - this.right = right; - } - - @Override - public Boolean get(Scope dataRoot) { - return Objects.equals(unwrap(left.get(dataRoot)), unwrap(right.get(dataRoot))); - } - - private Object unwrap(Object o) { - 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 literal(location, true); - return new Equal(location, left, right); - } - - @Override - public Stream> extractSideEffects() { - return Stream.concat(left.extractSideEffects(), right.extractSideEffects()); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - parenthesize(left, writer, false); - writer.append(" == "); - parenthesize(right, writer, true); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof Equal equal && left.equals(equal.left) && right.equals(equal.right); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/compare/Greater.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/compare/Greater.java deleted file mode 100644 index a8b983e..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/compare/Greater.java +++ /dev/null @@ -1,69 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.compare; - -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.ast.*; -import io.gitlab.jfronny.muscript.ast.literal.NumberLiteral; -import io.gitlab.jfronny.muscript.ast.math.*; - -import java.io.IOException; -import java.util.stream.Stream; - -public class Greater extends BoolExpr { - public final NumberExpr left; - public final NumberExpr right; - - public Greater(CodeLocation location, NumberExpr left, NumberExpr right) { - super(Order.Comparison, location); - this.left = left; - this.right = right; - } - - @Override - public Boolean get(Scope 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 literal(location, litL.value > litR.value); - if (left instanceof Divide divide) - return new Greater(location, divide.dividend, new Multiply(divide.location, right, divide.divisor)).optimize(); - if (left instanceof Invert invert) - return new Greater(location, new Invert(right.location, right), invert.inner).optimize(); - if (left instanceof Minus minus) - return new Greater(location, minus.minuend, new Plus(minus.location, 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(location, plus.augend, new Minus(plus.location, plus.addend, right)).optimize(); - // Power is left out because it can't be transformed cleanly either - return new Greater(location, left, right); - } - - @Override - public Stream> extractSideEffects() { - return Stream.concat(left.extractSideEffects(), right.extractSideEffects()); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - if (left instanceof NumberLiteral && !(right instanceof NumberLiteral)) { - parenthesize(right, writer, false); - writer.append(" < "); - parenthesize(left, writer, true); - } else { - parenthesize(left, writer, false); - writer.append(" > "); - parenthesize(right, writer, true); - } - } - - @Override - public boolean equals(Object obj) { - return obj instanceof Greater greater && left.equals(greater.left) && right.equals(greater.right); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/conditional/BoolConditional.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/conditional/BoolConditional.java deleted file mode 100644 index b5032f5..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/conditional/BoolConditional.java +++ /dev/null @@ -1,64 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.conditional; - -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.bool.Not; -import io.gitlab.jfronny.muscript.ast.dynamic.ExprGroup; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.ast.BoolExpr; -import io.gitlab.jfronny.muscript.ast.literal.BoolLiteral; - -import java.io.IOException; -import java.util.List; -import java.util.stream.Stream; - -public class BoolConditional extends BoolExpr { - public final BoolExpr condition; - public final BoolExpr trueExpr; - public final BoolExpr falseExpr; - - public BoolConditional(CodeLocation location, BoolExpr condition, BoolExpr trueExpr, BoolExpr falseExpr) { - super(Order.Conditional, location); - this.condition = condition; - this.trueExpr = trueExpr; - this.falseExpr = falseExpr; - } - - @Override - public Boolean get(Scope 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; - if (condition instanceof Not not) return new BoolConditional(location, not.inner, falseExpr, trueExpr); - return new BoolConditional(location, condition, trueExpr, falseExpr); - } - - @Override - public Stream> extractSideEffects() { - return UnresolvedConditional.extractSideEffects(location, condition, trueExpr, falseExpr); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - parenthesize(condition, writer, true); - writer.append(" ? "); - trueExpr.decompile(writer); - writer.append(" : "); - falseExpr.decompile(writer); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof BoolConditional conditional - && condition.equals(conditional.condition) - && trueExpr.equals(conditional.trueExpr) - && falseExpr.equals(conditional.falseExpr); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/conditional/DynamicConditional.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/conditional/DynamicConditional.java deleted file mode 100644 index 342a14b..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/conditional/DynamicConditional.java +++ /dev/null @@ -1,66 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.conditional; - -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.bool.Not; -import io.gitlab.jfronny.muscript.ast.dynamic.ExprGroup; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.Dynamic; -import io.gitlab.jfronny.muscript.ast.BoolExpr; -import io.gitlab.jfronny.muscript.ast.DynamicExpr; -import io.gitlab.jfronny.muscript.ast.literal.BoolLiteral; - -import java.io.IOException; -import java.util.List; -import java.util.stream.Stream; - -public class DynamicConditional extends DynamicExpr { - public final BoolExpr condition; - public final DynamicExpr trueExpr; - public final DynamicExpr falseExpr; - - public DynamicConditional(CodeLocation location, BoolExpr condition, DynamicExpr trueExpr, DynamicExpr falseExpr) { - super(Order.Conditional, location); - this.condition = condition; - this.trueExpr = trueExpr; - this.falseExpr = falseExpr; - } - - @Override - public Dynamic get(Scope 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; - if (condition instanceof Not not) return new DynamicConditional(location, not.inner, falseExpr, trueExpr); - return new DynamicConditional(location, condition, trueExpr, falseExpr); - } - - @Override - public Stream> extractSideEffects() { - return UnresolvedConditional.extractSideEffects(location, condition, trueExpr, falseExpr); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - parenthesize(condition, writer, true); - writer.append(" ? "); - trueExpr.decompile(writer); - writer.append(" : "); - falseExpr.decompile(writer); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof DynamicConditional conditional - && condition.equals(conditional.condition) - && trueExpr.equals(conditional.trueExpr) - && falseExpr.equals(conditional.falseExpr); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/conditional/NumberConditional.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/conditional/NumberConditional.java deleted file mode 100644 index 40b6dac..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/conditional/NumberConditional.java +++ /dev/null @@ -1,63 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.conditional; - -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.bool.Not; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.ast.BoolExpr; -import io.gitlab.jfronny.muscript.ast.NumberExpr; -import io.gitlab.jfronny.muscript.ast.literal.BoolLiteral; - -import java.io.IOException; -import java.util.stream.Stream; - -public class NumberConditional extends NumberExpr { - public final BoolExpr condition; - public final NumberExpr trueExpr; - public final NumberExpr falseExpr; - - public NumberConditional(CodeLocation location, BoolExpr condition, NumberExpr trueExpr, NumberExpr falseExpr) { - super(Order.Conditional, location); - this.condition = condition; - this.trueExpr = trueExpr; - this.falseExpr = falseExpr; - } - - @Override - public Double get(Scope 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; - if (condition instanceof Not not) return new NumberConditional(location, not.inner, falseExpr, trueExpr); - return new NumberConditional(location, condition, trueExpr, falseExpr); - } - - @Override - public Stream> extractSideEffects() { - return UnresolvedConditional.extractSideEffects(location, condition, trueExpr, falseExpr); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - parenthesize(condition, writer, true); - writer.append(" ? "); - trueExpr.decompile(writer); - writer.append(" : "); - falseExpr.decompile(writer); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof NumberConditional conditional - && condition.equals(conditional.condition) - && trueExpr.equals(conditional.trueExpr) - && falseExpr.equals(conditional.falseExpr); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/conditional/StringConditional.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/conditional/StringConditional.java deleted file mode 100644 index 5f80d22..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/conditional/StringConditional.java +++ /dev/null @@ -1,63 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.conditional; - -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.bool.Not; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.ast.BoolExpr; -import io.gitlab.jfronny.muscript.ast.StringExpr; -import io.gitlab.jfronny.muscript.ast.literal.BoolLiteral; - -import java.io.IOException; -import java.util.stream.Stream; - -public class StringConditional extends StringExpr { - public final BoolExpr condition; - public final StringExpr trueExpr; - public final StringExpr falseExpr; - - public StringConditional(CodeLocation location, BoolExpr condition, StringExpr trueExpr, StringExpr falseExpr) { - super(Order.Conditional, location); - this.condition = condition; - this.trueExpr = trueExpr; - this.falseExpr = falseExpr; - } - - @Override - public String get(Scope 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; - if (condition instanceof Not not) return new StringConditional(location, not.inner, falseExpr, trueExpr); - return new StringConditional(location, condition, trueExpr, falseExpr); - } - - @Override - public Stream> extractSideEffects() { - return UnresolvedConditional.extractSideEffects(location, condition, trueExpr, falseExpr); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - parenthesize(condition, writer, true); - writer.append(" ? "); - trueExpr.decompile(writer); - writer.append(" : "); - falseExpr.decompile(writer); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof StringConditional conditional - && condition.equals(conditional.condition) - && trueExpr.equals(conditional.trueExpr) - && falseExpr.equals(conditional.falseExpr); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/conditional/UnresolvedConditional.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/conditional/UnresolvedConditional.java deleted file mode 100644 index b092bab..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/conditional/UnresolvedConditional.java +++ /dev/null @@ -1,106 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.conditional; - -import io.gitlab.jfronny.muscript.ast.bool.Not; -import io.gitlab.jfronny.muscript.ast.dynamic.ExprGroup; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.DNull; -import io.gitlab.jfronny.muscript.data.dynamic.Dynamic; -import io.gitlab.jfronny.muscript.ast.*; -import io.gitlab.jfronny.muscript.ast.literal.BoolLiteral; - -import java.io.IOException; -import java.util.List; -import java.util.stream.Stream; - -public class UnresolvedConditional extends DynamicExpr { - private final BoolExpr condition; - private final Expr trueExpr; - private final Expr falseExpr; - - public UnresolvedConditional(CodeLocation location, BoolExpr condition, Expr trueExpr, Expr falseExpr) { - super(Order.Conditional, location); - this.condition = condition; - this.trueExpr = trueExpr; - this.falseExpr = falseExpr; - } - - @Override - public Type getResultType() { - return trueExpr.getResultType(); - } - - @Override - 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(); - if (condition instanceof Not not) return new UnresolvedConditional(location, not.inner, falseExpr, trueExpr); - return new UnresolvedConditional(location, condition, trueExpr, falseExpr); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - parenthesize(condition, writer, true); - writer.append(" ? "); - trueExpr.decompile(writer); - writer.append(" : "); - falseExpr.decompile(writer); - } - - @Override - public Dynamic get(Scope dataRoot) { - // unresolved conditionals may exist as root elements in scripts/closures - // thus, this needs to be handled, but the result will always be null - if (condition.get(dataRoot)) trueExpr.get(dataRoot); - else falseExpr.get(dataRoot); - return new DNull(); - } - - @Override - public DynamicExpr asDynamicExpr() { - return new DynamicConditional(location, condition, trueExpr.asDynamicExpr(), falseExpr.asDynamicExpr()); - } - - @Override - public Stream> extractSideEffects() { - return extractSideEffects(location, condition, trueExpr, falseExpr); - } - - public static Stream> extractSideEffects(CodeLocation location, BoolExpr condition, Expr trueExpr, Expr falseExpr) { - List> trueSE = trueExpr.extractSideEffects().toList(); - List> falseSE = falseExpr.extractSideEffects().toList(); - if (trueSE.isEmpty() && falseSE.isEmpty()) return condition.extractSideEffects(); - return Stream.of(new UnresolvedConditional( - location, - condition, - ExprGroup.of(trueExpr.location, trueSE, false), - ExprGroup.of(falseExpr.location, falseSE, false) - )); - } - - @Override - public BoolExpr asBoolExpr() { - return new BoolConditional(location, condition, trueExpr.asBoolExpr(), falseExpr.asBoolExpr()); - } - - @Override - public StringExpr asStringExpr() { - return new StringConditional(location, condition, trueExpr.asStringExpr(), falseExpr.asStringExpr()); - } - - @Override - public NumberExpr asNumberExpr() { - return new NumberConditional(location, 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); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Bind.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Bind.java deleted file mode 100644 index bf74d76..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Bind.java +++ /dev/null @@ -1,59 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.dynamic; - -import io.gitlab.jfronny.muscript.ast.DynamicExpr; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.DCallable; -import io.gitlab.jfronny.muscript.data.dynamic.additional.DFinal; -import io.gitlab.jfronny.muscript.data.dynamic.Dynamic; - -import java.io.IOException; -import java.util.LinkedList; -import java.util.List; -import java.util.stream.Stream; - -public class Bind extends DynamicExpr { - public final DynamicExpr callable; - public final DynamicExpr parameter; - - public Bind(CodeLocation location, DynamicExpr callable, DynamicExpr parameter) { - super(Order.Call, location); - this.callable = callable; - this.parameter = parameter; - } - - @Override - public Dynamic get(Scope dataRoot) { - Dynamic param = parameter.get(dataRoot); - DCallable clb = callable.get(dataRoot).asCallable(); - return DFinal.of("", args -> { - List argsWithParameter = new LinkedList<>(args.getValue()); - argsWithParameter.addFirst(param); - return clb.call(DFinal.of(argsWithParameter)); - }, () -> this); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - parenthesize(parameter, writer, false); - writer.append("::"); - if (callable instanceof Variable) { - callable.decompile(writer); - } else { - writer.append('('); - callable.decompile(writer); - writer.append(')'); - } - } - - @Override - public DynamicExpr optimize() { - return new Bind(location, callable.optimize(), parameter.optimize()); - } - - @Override - public Stream> extractSideEffects() { - return Stream.concat(callable.extractSideEffects(), parameter.extractSideEffects()); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Call.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Call.java deleted file mode 100644 index 1a82938..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Call.java +++ /dev/null @@ -1,125 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.dynamic; - -import io.gitlab.jfronny.muscript.ast.DynamicExpr; -import io.gitlab.jfronny.muscript.annotations.CanThrow; -import io.gitlab.jfronny.muscript.annotations.UncheckedDynamic; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.*; -import io.gitlab.jfronny.muscript.data.dynamic.additional.DFinal; -import io.gitlab.jfronny.muscript.error.LocationalException; -import io.gitlab.jfronny.muscript.error.StackFrame; - -import java.io.IOException; -import java.util.*; -import java.util.stream.Stream; - -@CanThrow -@UncheckedDynamic -public class Call extends DynamicExpr { - public final DynamicExpr left; - public final List args; - - public Call(CodeLocation location, DynamicExpr left, List args) { - super(Order.Call, location); - this.left = left; - this.args = args; - } - - @Override - public Dynamic get(Scope dataRoot) { - DCallable dc; - DList arg; - try { - Dynamic lv = left.get(dataRoot); - if (Dynamic.isNull(lv)) throw new LocationalException(location, "Cannot invoke null"); - dc = lv.asCallable(); - arg = DFinal.of(args.stream().flatMap(e -> e.get(dataRoot)).toArray(Dynamic[]::new)); - } catch (DynamicTypeConversionException e) { - throw e.locational(location); - } catch (RuntimeException e) { - throw new LocationalException(location, "Could not perform call successfully", e); - } - try { - return dc.call(arg); - } catch (LocationalException le) { - throw le.appendStack(new StackFrame.Raw(location.file(), dc.getName(), left.location.chStart())); - } catch (DynamicTypeConversionException e) { - throw e.locational(location); - } catch (RuntimeException e) { - throw new LocationalException(location, e.getMessage(), e); - } - } - - @Override - public DynamicExpr optimize() { - List args = new ArrayList<>(); - DynamicExpr left = this.left.optimize(); - if (left instanceof Bind bind) { - left = bind.callable; - args.add(new Arg(bind.parameter, false)); - } - for (Arg arg : this.args) args.add(arg.optimize()); - if (left instanceof Closure closure) { - return new ExprGroup( - closure.location, - closure.stream().toList(), - new ExprGroup.PackedArgs( - args, - closure.boundArgs, - closure.variadic - ) - ); - } - return new Call(location, left, args); - } - - @Override - public Stream> extractSideEffects() { - return Stream.of(this); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - parenthesize(left, writer, false); - if (args.size() > 3) { - writer.increaseIndent(); - writer.append("(\n"); - boolean first = true; - for (Arg arg : args) { - if (!first) writer.append(",\n"); - first = false; - arg.expr.decompile(writer); - if (arg.variadic) writer.append("..."); - } - writer.decreaseIndent(); - writer.append("\n)"); - } else { - writer.append('('); - boolean first = true; - for (Arg arg : args) { - if (!first) writer.append(", "); - first = false; - arg.expr.decompile(writer); - if (arg.variadic) writer.append("..."); - } - writer.append(')'); - } - } - - @Override - public boolean equals(Object obj) { - return obj instanceof Call call && left.equals(call.left) && args.equals(call.args); - } - - public record Arg(DynamicExpr expr, boolean variadic) { - public Stream get(Scope dataRoot) { - return variadic ? expr.get(dataRoot).asList().getValue().stream() : Stream.of(expr.get(dataRoot)); - } - - public Arg optimize() { - return new Arg(expr.optimize(), variadic); - } - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Closure.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Closure.java deleted file mode 100644 index f6f7009..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Closure.java +++ /dev/null @@ -1,118 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.dynamic; - -import io.gitlab.jfronny.muscript.ast.DynamicExpr; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.*; -import io.gitlab.jfronny.muscript.data.dynamic.additional.DFinal; -import io.gitlab.jfronny.muscript.data.dynamic.type.DTypeCallable; -import io.gitlab.jfronny.muscript.error.LocationalException; - -import java.io.IOException; -import java.util.LinkedList; -import java.util.List; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -public class Closure extends DynamicExpr { - public final List boundArgs; - private final List> steps; - private final DynamicExpr fin; - public final boolean variadic; - - public Closure(CodeLocation location, List boundArgs, List> expressions, boolean variadic) { - this(location, boundArgs, expressions.subList(0, expressions.size() - 1), expressions.getLast().asDynamicExpr(), variadic); - } - - private Closure(CodeLocation location, List boundArgs, List> steps, DynamicExpr fin, boolean variadic) { - super(Order.Primary, location); - this.boundArgs = List.copyOf(boundArgs); - this.steps = List.copyOf(steps); - this.fin = fin; - this.variadic = variadic; - } - - private DTypeCallable getSignature() { - //TODO take into account inner instructions to properly determine type - List args = new LinkedList<>(); - for (int i = 0; i < boundArgs.size(); i++) { - args.add(new DTypeCallable.Arg(boundArgs.get(i), null, variadic && (i == boundArgs.size() - 1))); - } - return new DTypeCallable(args, null); - } - - @Override - public DCallable get(Scope dataRoot) { - return DFinal.of(getSignature(), null, args -> { - // Compare with ExprGroup.get() - int ac = args.size(); - int ae = boundArgs.size(); - if (variadic) ae--; - if (ac < ae) throw new LocationalException(location, "Invoked with too few arguments (expected " + ae + " but got " + ac + ")"); - if (!variadic && ac > ae) throw new LocationalException(location, "Invoked with too many arguments (expected " + ae + " but got " + ac + ")"); - Scope fork = dataRoot.fork(); - for (int i = 0; i < ae; i++) fork.set(boundArgs.get(i), args.get(i)); - if (variadic) { - fork.set(boundArgs.getLast(), IntStream.range(ae, ac) - .mapToObj(args::get) - .toList()); - } - for (Expr step : steps) { - step.get(fork); - } - return fin.get(fork); - }, () -> this); - } - - @Override - public DynamicExpr optimize() { - return new Closure( - location, - boundArgs, - steps.stream() - .map(Expr::optimize) - .flatMap(Expr::extractSideEffects) - .>map(Expr::optimize) - .toList(), - fin.optimize(), - variadic - ); - } - - @Override - public Stream> extractSideEffects() { - return Stream.empty(); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - writer.append("{"); - boolean first = true; - for (int i = 0; i < boundArgs.size(); i++) { - if (!first) writer.append(","); - first = false; - writer.append(' ').appendLiteral(boundArgs.get(i)); - if (i == boundArgs.size() - 1 && variadic) writer.append("..."); - } - writer.append(" ->").increaseIndent(); - for (Expr expr : stream().toList()) { - writer.append("\n"); - expr.decompile(writer); - writer.append(";"); - } - writer.decreaseIndent().append("\n}"); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof Closure closure - && boundArgs.equals(closure.boundArgs) - && steps.equals(closure.steps) - && fin.equals(closure.fin); - } - - public Stream> stream() { - return Stream.concat(steps.stream(), Stream.of(fin)); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/DynamicCoerce.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/DynamicCoerce.java deleted file mode 100644 index 8c123da..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/DynamicCoerce.java +++ /dev/null @@ -1,62 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.dynamic; - -import io.gitlab.jfronny.muscript.ast.*; -import io.gitlab.jfronny.muscript.ast.dynamic.unpack.*; -import io.gitlab.jfronny.muscript.compiler.CodeLocation; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.*; -import io.gitlab.jfronny.muscript.data.dynamic.additional.DFinal; - -import java.io.IOException; -import java.util.stream.Stream; - -public class DynamicCoerce extends DynamicExpr { - public final Expr inner; - - public DynamicCoerce(CodeLocation location, Expr inner) { - super(inner.order, location); - this.inner = inner; - if (!(inner instanceof DynamicExpr) - && !(inner instanceof BoolExpr) - && !(inner instanceof StringExpr) - && !(inner instanceof NumberExpr) - && !(inner instanceof NullLiteral)) { - throw new IllegalArgumentException("A DynamicCoerce can only be created with a well-defined expression type"); - } - } - - @Override - public Dynamic get(Scope dataRoot) { - if (inner instanceof DynamicExpr e) return e.get(dataRoot); - if (inner instanceof BoolExpr e) return DFinal.of(e.get(dataRoot)); - if (inner instanceof StringExpr e) return DFinal.of(e.get(dataRoot)); - if (inner instanceof NumberExpr e) return DFinal.of(e.get(dataRoot)); - 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(location, inner); - } - - @Override - public Stream> extractSideEffects() { - return inner.extractSideEffects(); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - inner.decompile(writer); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof DynamicCoerce coerce && inner.equals(coerce.inner); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/ExprGroup.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/ExprGroup.java deleted file mode 100644 index 79ea0bd..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/ExprGroup.java +++ /dev/null @@ -1,133 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.dynamic; - -import io.gitlab.jfronny.muscript.ast.DynamicExpr; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.NullLiteral; -import io.gitlab.jfronny.muscript.ast.string.Concatenate; -import io.gitlab.jfronny.muscript.compiler.CodeLocation; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.Dynamic; -import io.gitlab.jfronny.muscript.error.LocationalException; -import org.jetbrains.annotations.Nullable; - -import java.io.IOException; -import java.util.LinkedList; -import java.util.List; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -public class ExprGroup extends DynamicExpr { - private final List> steps; - private final DynamicExpr fin; - private final @Nullable PackedArgs packedArgs; - private final boolean fork; - - public ExprGroup(CodeLocation location, List> expressions) { - this(location, expressions, null); - } - - public ExprGroup(CodeLocation location, List> expressions, @Nullable PackedArgs packedArgs) { - this(location, expressions, packedArgs, true); - } - - public ExprGroup(CodeLocation location, List> expressions, @Nullable PackedArgs packedArgs, boolean fork) { - super(Order.Primary, location); - this.steps = expressions.subList(0, expressions.size() - 1); - this.fin = expressions.getLast().asDynamicExpr(); - this.packedArgs = packedArgs; - this.fork = fork; - if (!fork && packedArgs != null) throw new UnsupportedOperationException("packedArgs may only be used for forking ExprGroups"); - } - - public static Expr of(CodeLocation location, List> expressions) { - return of(location, expressions, true); - } - - public static Expr of(CodeLocation location, List> expressions, boolean fork) { - if (expressions.isEmpty()) return new NullLiteral(location); - if (!fork && expressions.size() == 1) return expressions.getFirst(); - return new ExprGroup(location, expressions, null, fork); - } - - @Override - public Dynamic get(Scope dataRoot) { - Scope fork = this.fork ? dataRoot.fork() : dataRoot; - if (this.fork && packedArgs != null) { - List from = new LinkedList<>(); - for (Call.Arg arg : packedArgs.from) { - Dynamic data = arg.expr().get(dataRoot); - if (arg.variadic()) from.addAll(data.asList().getValue()); - else from.add(data); - } - List to = packedArgs.to; - // Compare with Closure.get() - int ac = from.size(); - int ae = to.size(); - if (packedArgs.variadic) ae--; - if (ac < ae) throw new LocationalException(location, "Invoked with too few arguments (expected " + ae + " but got " + ac + ")"); - if (!packedArgs.variadic && ac > ae) throw new LocationalException(location, "Invoked with too many arguments (expected " + ae + " but got " + ac + ")"); - for (int i = 0; i < ae; i++) fork.set(to.get(i), from.get(i)); - if (packedArgs.variadic) { - fork.set(to.get(to.size() - 1), IntStream.range(ae, ac) - .mapToObj(from::get) - .toList()); - } - } - for (Expr step : steps) { - step.get(fork); - } - return fin.get(fork); - } - - @Override - public DynamicExpr optimize() { - List> exprs = Stream.concat( - steps.stream() - .map(Expr::optimize) - .flatMap(Expr::extractSideEffects) - .map(Expr::optimize), - Stream.of(fin.optimize()) - ).toList(); - return packedArgs == null - ? of(location, exprs, fork).asDynamicExpr() - : new ExprGroup(location, exprs, packedArgs, fork); - } - - @Override - public Stream> extractSideEffects() { - return fork ? Stream.of(this) : Stream.of(of(location, stream().flatMap(Expr::extractSideEffects).toList())); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - if (!fork) { - // Use string concatenation since the result is ignored either way - stream() - .reduce((left, right) -> new Concatenate(location, left.asStringExpr(), right.asStringExpr())) - .orElseGet(() -> new NullLiteral(location)) - .optimize() - .decompile(writer); - } else { - new Call( - location, - new Closure( - location, - packedArgs == null - ? List.of() - : packedArgs.to, - stream().toList(), - false - ), - packedArgs == null ? List.of() : packedArgs.from - ).decompile(writer); - } - } - - public Stream> stream() { - return Stream.concat(steps.stream(), Stream.of(fin)); - } - - public record PackedArgs(List from, List to, boolean variadic) {} -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Get.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Get.java deleted file mode 100644 index aad3821..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Get.java +++ /dev/null @@ -1,78 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.dynamic; - -import io.gitlab.jfronny.muscript.ast.DynamicExpr; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.annotations.CanThrow; -import io.gitlab.jfronny.muscript.annotations.UncheckedDynamic; -import io.gitlab.jfronny.muscript.ast.literal.StringLiteral; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.*; -import io.gitlab.jfronny.muscript.error.LocationalException; -import io.gitlab.jfronny.muscript.error.TypeMismatchException; - -import java.io.IOException; -import java.util.stream.Stream; - -@CanThrow -@UncheckedDynamic -public class Get extends DynamicExpr { - private final DynamicExpr left; - private final Expr name; - - public Get(CodeLocation location, DynamicExpr left, Expr name) { - super(Order.Call, location); - this.left = left; - this.name = name; - if (name.getResultType() != Type.String && name.getResultType() != Type.Number && name.getResultType() != Type.Dynamic) { - throw new TypeMismatchException(location, Type.String, name.getResultType(), "Name must be either a string or a number"); - } - } - - @Override - public Dynamic get(Scope dataRoot) { - Dynamic left = this.left.get(dataRoot); - if (Dynamic.isNull(left)) throw new LocationalException(location, "Could not get \"" + name.asStringExpr().get(dataRoot) + "\" because left is null"); - if (left.isObject()) { - DObject o = left.asObject(); - var n = name.asStringExpr().get(dataRoot); - if (!o.has(n)) throw new LocationalException(location, "Object does not contain \"" + n + "\""); - return o.get(n); - } else if (left.isList()) { - DList l = left.asList(); - int idx = name.asNumberExpr().get(dataRoot).intValue(); - if (idx < 0 || idx >= l.size()) throw new LocationalException(location, "Index " + idx + " is out of range for list with size " + l.size()); - return l.get(idx); - } - throw new DynamicTypeConversionException("object or list", left).locational(location); - } - - @Override - public DynamicExpr optimize() { - DynamicExpr left = this.left.optimize(); - Expr name = this.name.optimize(); - return new Get(location, left, name); - } - - @Override - public Stream> extractSideEffects() { - return Stream.concat(left.extractSideEffects(), name.extractSideEffects()); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - parenthesize(left, writer, false); - if (name instanceof StringLiteral lit && Lexer.isValidId(lit.value)) { - writer.append('.').append(lit.value); - } else { - writer.append('['); - name.decompile(writer); - writer.append(']'); - } - } - - @Override - public boolean equals(Object obj) { - return obj instanceof Get get && left.equals(get.left) && name.equals(get.name); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/ListOf.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/ListOf.java deleted file mode 100644 index 61afd75..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/ListOf.java +++ /dev/null @@ -1,47 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.dynamic; - -import io.gitlab.jfronny.muscript.ast.DynamicExpr; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.compiler.CodeLocation; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.Dynamic; -import io.gitlab.jfronny.muscript.data.dynamic.additional.DFinal; - -import java.io.IOException; -import java.util.List; -import java.util.stream.Stream; - -public class ListOf extends DynamicExpr { - private final List elements; - - protected ListOf(CodeLocation location, List elements) { - super(Order.Primary, location); - this.elements = elements; - } - - @Override - public Dynamic get(Scope dataRoot) { - return DFinal.of(elements.stream().map(s -> s.get(dataRoot)).toList()); - } - - @Override - public DynamicExpr optimize() { - return new ListOf(location, elements.stream().map(DynamicExpr::optimize).toList()); - } - - @Override - public Stream> extractSideEffects() { - return elements.stream().flatMap(Expr::extractSideEffects); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - new Call( - location, - new Variable(location, "listOf"), - elements.stream().map(s -> new Call.Arg(s, false)).toList() - ).decompile(writer); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/ObjectLiteral.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/ObjectLiteral.java deleted file mode 100644 index 0836de1..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/ObjectLiteral.java +++ /dev/null @@ -1,63 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.dynamic; - -import io.gitlab.jfronny.muscript.ast.DynamicExpr; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.literal.DynamicLiteral; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.Dynamic; -import io.gitlab.jfronny.muscript.data.dynamic.additional.DFinal; - -import java.io.IOException; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.stream.Stream; - -public class ObjectLiteral extends DynamicExpr { - public final Map content; - - public ObjectLiteral(CodeLocation location, Map content) { - super(Order.Primary, location); - this.content = content; - } - - @Override - public Dynamic get(Scope dataRoot) { - Map result = new LinkedHashMap<>(); - this.content.forEach((k, v) -> result.put(k, v.get(dataRoot))); - return DFinal.of(result); - } - - @Override - public DynamicExpr optimize() { - Map content = new LinkedHashMap<>(); - Map literalContent = new LinkedHashMap<>(); - boolean literal = true; - for (Map.Entry entry : this.content.entrySet()) { - DynamicExpr de = entry.getValue().optimize(); - if (de instanceof DynamicLiteral dl && literal) literalContent.put(entry.getKey(), dl.value); - else literal = false; - content.put(entry.getKey(), de); - } - if (literal) return new DynamicLiteral<>(location, DFinal.of(literalContent)); - return new ObjectLiteral(location, content); - } - - @Override - public Stream> extractSideEffects() { - return content.values().stream().flatMap(Expr::extractSideEffects); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - writer.increaseIndent().append("{\n"); - boolean first = true; - for (Map.Entry entry : content.entrySet()) { - if (!first) writer.append(",\n"); - first = false; - writer.appendLiteral(entry.getKey()).append(" = "); - entry.getValue().decompile(writer); - } - writer.decreaseIndent().append("\n}"); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Variable.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Variable.java deleted file mode 100644 index 0807541..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Variable.java +++ /dev/null @@ -1,51 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.dynamic; - -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.Dynamic; -import io.gitlab.jfronny.muscript.ast.DynamicExpr; -import io.gitlab.jfronny.muscript.annotations.CanThrow; -import io.gitlab.jfronny.muscript.annotations.UncheckedDynamic; -import io.gitlab.jfronny.muscript.error.LocationalException; - -import java.io.IOException; -import java.util.stream.Stream; - -@CanThrow -@UncheckedDynamic -public class Variable extends DynamicExpr { - public final String name; - - public Variable(CodeLocation location, String name) { - super(Order.Primary, location); - this.name = name; - } - - @Override - public Dynamic get(Scope dataRoot) { - if (name.equals("this")) return dataRoot; - if (dataRoot.has(name)) return dataRoot.get(name); - else throw new LocationalException(location, "This object doesn't contain '" + name + "'"); - } - - @Override - public DynamicExpr optimize() { - return this; - } - - @Override - public Stream> extractSideEffects() { - return Stream.empty(); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - writer.appendLiteral(name); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof Variable variable && name.equals(variable.name); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/assign/BoolAssign.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/assign/BoolAssign.java deleted file mode 100644 index bb3a575..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/assign/BoolAssign.java +++ /dev/null @@ -1,52 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.dynamic.assign; - -import io.gitlab.jfronny.muscript.ast.BoolExpr; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.error.LocationalException; - -import java.io.IOException; -import java.util.stream.Stream; - -public class BoolAssign extends BoolExpr { - private final String name; - private final BoolExpr value; - - protected BoolAssign(CodeLocation location, String name, BoolExpr value) { - super(Order.Primary, location); - if (name.equals("this")) throw new LocationalException(location, "Cannot reassign 'this'"); - this.name = name; - this.value = value; - } - - @Override - public Boolean get(Scope dataRoot) { - boolean data = value.get(dataRoot); - dataRoot.set(name, data); - return data; - } - - @Override - public BoolExpr optimize() { - return new BoolAssign(location, name, value.optimize()); - } - - @Override - public Stream> extractSideEffects() { - return Stream.of(this); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - writer.appendLiteral(name).append(" = "); - value.decompile(writer); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof BoolAssign assign - && name.equals(assign.name) - && value.equals(assign.value); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/assign/DynamicAssign.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/assign/DynamicAssign.java deleted file mode 100644 index b39ec37..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/assign/DynamicAssign.java +++ /dev/null @@ -1,63 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.dynamic.assign; - -import io.gitlab.jfronny.muscript.ast.*; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.DCallable; -import io.gitlab.jfronny.muscript.data.dynamic.Dynamic; -import io.gitlab.jfronny.muscript.error.LocationalException; - -import java.io.IOException; -import java.util.stream.Stream; - -public class DynamicAssign extends DynamicExpr { - private final String name; - private final DynamicExpr value; - - public DynamicAssign(CodeLocation location, String name, DynamicExpr value) { - super(Order.Primary, location); - if (name.equals("this")) throw new LocationalException(location, "Cannot reassign 'this'"); - this.name = name; - this.value = value; - } - - @Override - public Dynamic get(Scope dataRoot) { - Dynamic data = value.get(dataRoot); - dataRoot.set(name, data.isCallable() ? data.asCallable().named(name) : data); - return data; - } - - @Override - public DynamicExpr optimize() { - return new DynamicAssign(location, name, value.optimize()); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - writer.appendLiteral(name).append(" = "); - value.decompile(writer); - } - - @Override - public BoolExpr asBoolExpr() { - return new BoolAssign(location, name, value.asBoolExpr()); - } - - @Override - public NumberExpr asNumberExpr() { - return new NumberAssign(location, name, value.asNumberExpr()); - } - - @Override - public Stream> extractSideEffects() { - return Stream.of(this); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof DynamicAssign assign - && name.equals(assign.name) - && value.equals(assign.value); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/assign/NumberAssign.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/assign/NumberAssign.java deleted file mode 100644 index 4a2ee5b..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/assign/NumberAssign.java +++ /dev/null @@ -1,52 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.dynamic.assign; - -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.NumberExpr; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.error.LocationalException; - -import java.io.IOException; -import java.util.stream.Stream; - -public class NumberAssign extends NumberExpr { - private final String name; - private final NumberExpr value; - - protected NumberAssign(CodeLocation location, String name, NumberExpr value) { - super(Order.Primary, location); - if (name.equals("this")) throw new LocationalException(location, "Cannot reassign 'this'"); - this.name = name; - this.value = value; - } - - @Override - public Double get(Scope dataRoot) { - double data = value.get(dataRoot); - dataRoot.set(name, data); - return data; - } - - @Override - public NumberExpr optimize() { - return new NumberAssign(location, name, value.optimize()); - } - - @Override - public Stream> extractSideEffects() { - return Stream.of(this); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - writer.appendLiteral(name).append(" = "); - value.decompile(writer); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof NumberAssign assign - && name.equals(assign.name) - && value.equals(assign.value); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/assign/StringAssign.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/assign/StringAssign.java deleted file mode 100644 index 535f189..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/assign/StringAssign.java +++ /dev/null @@ -1,52 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.dynamic.assign; - -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.StringExpr; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.error.LocationalException; - -import java.io.IOException; -import java.util.stream.Stream; - -public class StringAssign extends StringExpr { - private final String name; - private final StringExpr value; - - protected StringAssign(CodeLocation location, String name, StringExpr value) { - super(Order.Primary, location); - if (name.equals("this")) throw new LocationalException(location, "Cannot reassign 'this'"); - this.name = name; - this.value = value; - } - - @Override - public String get(Scope dataRoot) { - String data = value.get(dataRoot); - dataRoot.set(name, data); - return data; - } - - @Override - public StringExpr optimize() { - return new StringAssign(location, name, value.optimize()); - } - - @Override - public Stream> extractSideEffects() { - return Stream.of(this); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - writer.appendLiteral(name).append(" = "); - value.decompile(writer); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof StringAssign assign - && name.equals(assign.name) - && value.equals(assign.value); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/unpack/BoolUnpack.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/unpack/BoolUnpack.java deleted file mode 100644 index 89c8ce9..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/unpack/BoolUnpack.java +++ /dev/null @@ -1,61 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.dynamic.unpack; - -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.compiler.CodeLocation; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.Dynamic; -import io.gitlab.jfronny.muscript.data.dynamic.DynamicTypeConversionException; -import io.gitlab.jfronny.muscript.ast.BoolExpr; -import io.gitlab.jfronny.muscript.ast.DynamicExpr; -import io.gitlab.jfronny.muscript.annotations.CanThrow; -import io.gitlab.jfronny.muscript.annotations.UncheckedDynamic; -import io.gitlab.jfronny.muscript.ast.dynamic.DynamicCoerce; -import io.gitlab.jfronny.muscript.error.LocationalException; - -import java.io.IOException; -import java.util.stream.Stream; - -@CanThrow -@UncheckedDynamic -public class BoolUnpack extends BoolExpr { - public final DynamicExpr inner; - - public BoolUnpack(CodeLocation location, DynamicExpr inner) { - super(inner.order, location); - this.inner = inner; - } - - @Override - public Boolean get(Scope dataRoot) { - try { - Dynamic iv = inner.get(dataRoot); - if (Dynamic.isNull(iv)) throw new LocationalException(location, "Cannot unpack null"); - return iv.asBool().getValue(); - } catch (DynamicTypeConversionException e) { - throw e.locational(location); - } - } - - @Override - public BoolExpr optimize() { - DynamicExpr inner = this.inner.optimize(); - if (inner instanceof DynamicCoerce coerce) return coerce.inner.asBoolExpr(); - return new BoolUnpack(location, inner); - } - - @Override - public Stream> extractSideEffects() { - return inner.extractSideEffects(); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - inner.decompile(writer); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof BoolUnpack unpack && inner.equals(unpack.inner); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/unpack/NumberUnpack.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/unpack/NumberUnpack.java deleted file mode 100644 index 59e04a4..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/unpack/NumberUnpack.java +++ /dev/null @@ -1,61 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.dynamic.unpack; - -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.compiler.CodeLocation; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.Dynamic; -import io.gitlab.jfronny.muscript.data.dynamic.DynamicTypeConversionException; -import io.gitlab.jfronny.muscript.ast.DynamicExpr; -import io.gitlab.jfronny.muscript.ast.NumberExpr; -import io.gitlab.jfronny.muscript.annotations.CanThrow; -import io.gitlab.jfronny.muscript.annotations.UncheckedDynamic; -import io.gitlab.jfronny.muscript.ast.dynamic.DynamicCoerce; -import io.gitlab.jfronny.muscript.error.LocationalException; - -import java.io.IOException; -import java.util.stream.Stream; - -@CanThrow -@UncheckedDynamic -public class NumberUnpack extends NumberExpr { - public final DynamicExpr inner; - - public NumberUnpack(CodeLocation location, DynamicExpr inner) { - super(inner.order, location); - this.inner = inner; - } - - @Override - public Double get(Scope dataRoot) { - try { - Dynamic iv = inner.get(dataRoot); - if (Dynamic.isNull(iv)) throw new LocationalException(location, "Cannot unpack null"); - return iv.asNumber().getValue(); - } catch (DynamicTypeConversionException e) { - throw e.locational(location); - } - } - - @Override - public NumberExpr optimize() { - DynamicExpr inner = this.inner.optimize(); - if (inner instanceof DynamicCoerce coerce) return coerce.inner.asNumberExpr(); - return new NumberUnpack(location, inner.optimize()); - } - - @Override - public Stream> extractSideEffects() { - return inner.extractSideEffects(); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - inner.decompile(writer); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof NumberUnpack unpack && inner.equals(unpack.inner); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/unpack/StringUnpack.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/unpack/StringUnpack.java deleted file mode 100644 index f34b292..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/unpack/StringUnpack.java +++ /dev/null @@ -1,61 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.dynamic.unpack; - -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.compiler.CodeLocation; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.Dynamic; -import io.gitlab.jfronny.muscript.data.dynamic.DynamicTypeConversionException; -import io.gitlab.jfronny.muscript.ast.DynamicExpr; -import io.gitlab.jfronny.muscript.ast.StringExpr; -import io.gitlab.jfronny.muscript.annotations.CanThrow; -import io.gitlab.jfronny.muscript.annotations.UncheckedDynamic; -import io.gitlab.jfronny.muscript.ast.dynamic.DynamicCoerce; -import io.gitlab.jfronny.muscript.error.LocationalException; - -import java.io.IOException; -import java.util.stream.Stream; - -@CanThrow -@UncheckedDynamic -public class StringUnpack extends StringExpr { - public final DynamicExpr inner; - - public StringUnpack(CodeLocation location, DynamicExpr inner) { - super(inner.order, location); - this.inner = inner; - } - - @Override - public String get(Scope dataRoot) { - try { - Dynamic iv = inner.get(dataRoot); - if (Dynamic.isNull(iv)) throw new LocationalException(location, "Cannot unpack null"); - return iv.asString().getValue(); - } catch (DynamicTypeConversionException e) { - throw e.locational(location); - } - } - - @Override - public StringExpr optimize() { - DynamicExpr inner = this.inner.optimize(); - if (inner instanceof DynamicCoerce coerce) return coerce.inner.asStringExpr(); - return new StringUnpack(location, inner); - } - - @Override - public Stream> extractSideEffects() { - return inner.extractSideEffects(); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - inner.decompile(writer); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof StringUnpack unpack && inner.equals(unpack.inner); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/literal/BoolLiteral.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/literal/BoolLiteral.java deleted file mode 100644 index cc6aca0..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/literal/BoolLiteral.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.literal; - -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.ast.BoolExpr; - -import java.io.IOException; -import java.util.stream.Stream; - -public final class BoolLiteral extends BoolExpr { - public final boolean value; - - public BoolLiteral(CodeLocation location, boolean value) { - super(Order.Primary, location); - this.value = value; - } - - @Override - public Boolean get(Scope dataRoot) { - return value; - } - - @Override - public BoolExpr optimize() { - return this; - } - - @Override - public Stream> extractSideEffects() { - return Stream.empty(); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - writer.append(value ? "true" : "false"); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof BoolLiteral literal && value == literal.value; - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/literal/DynamicLiteral.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/literal/DynamicLiteral.java deleted file mode 100644 index 66e355f..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/literal/DynamicLiteral.java +++ /dev/null @@ -1,44 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.literal; - -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.data.dynamic.Dynamic; -import io.gitlab.jfronny.muscript.ast.DynamicExpr; - -import java.io.IOException; -import java.util.stream.Stream; - -public final class DynamicLiteral extends DynamicExpr { - public final Dynamic value; - - public DynamicLiteral(CodeLocation location, Dynamic value) { - super(Order.Primary, location); - this.value = value; - } - - @Override - public Dynamic get(Scope dataRoot) { - return value; - } - - @Override - public DynamicExpr optimize() { - return this; - } - - @Override - public Stream> extractSideEffects() { - return Stream.empty(); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - value.serialize(writer); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof DynamicLiteral literal && value.equals(literal.value); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/literal/NumberLiteral.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/literal/NumberLiteral.java deleted file mode 100644 index bb32a36..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/literal/NumberLiteral.java +++ /dev/null @@ -1,44 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.literal; - -import io.gitlab.jfronny.commons.StringFormatter; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.ast.NumberExpr; - -import java.io.IOException; -import java.util.stream.Stream; - -public final class NumberLiteral extends NumberExpr { - public final double value; - - public NumberLiteral(CodeLocation location, double value) { - super(Order.Primary, location); - this.value = value; - } - - @Override - public Double get(Scope dataRoot) { - return value; - } - - @Override - public NumberExpr optimize() { - return this; - } - - @Override - public Stream> extractSideEffects() { - return Stream.empty(); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - writer.append(StringFormatter.toString(value)); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof NumberLiteral literal && value == literal.value; - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/literal/StringLiteral.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/literal/StringLiteral.java deleted file mode 100644 index 5bc518b..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/literal/StringLiteral.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.literal; - -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.StringExpr; -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; - -import java.io.IOException; -import java.util.stream.Stream; - -public final class StringLiteral extends StringExpr { - public final String value; - - public StringLiteral(CodeLocation location, String value) { - super(Order.Primary, location); - this.value = value; - } - - @Override - public String get(Scope dataRoot) { - return value; - } - - @Override - public StringExpr optimize() { - return this; - } - - @Override - public Stream> extractSideEffects() { - return Stream.empty(); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - writer.append(enquote(value)); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof StringLiteral literal && value.equals(literal.value); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Divide.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Divide.java deleted file mode 100644 index e6765a4..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Divide.java +++ /dev/null @@ -1,54 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.math; - -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.NumberExpr; -import io.gitlab.jfronny.muscript.ast.literal.NumberLiteral; - -import java.io.IOException; -import java.util.stream.Stream; - -public class Divide extends NumberExpr { - public final NumberExpr dividend; - public final NumberExpr divisor; - - public Divide(CodeLocation location, NumberExpr dividend, NumberExpr divisor) { - super(Order.Factor, location); - this.dividend = dividend; - this.divisor = divisor; - } - - @Override - public Double get(Scope 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 literal(location, litL.value / litR.value); - if (dividend instanceof Divide divide && divide.dividend instanceof NumberLiteral literal) - return new Divide(location, divide.dividend, new Multiply(divide.location, divisor, literal)).optimize(); - return new Divide(location, dividend, divisor); - } - - @Override - public Stream> extractSideEffects() { - return Stream.concat(dividend.extractSideEffects(), divisor.extractSideEffects()); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - parenthesize(dividend, writer, false); - writer.append(" / "); - parenthesize(divisor, writer, true); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof Divide divide && dividend.equals(divide.dividend) && divisor.equals(divide.divisor); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Invert.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Invert.java deleted file mode 100644 index 4c14714..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Invert.java +++ /dev/null @@ -1,49 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.math; - -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.NumberExpr; -import io.gitlab.jfronny.muscript.ast.literal.NumberLiteral; - -import java.io.IOException; -import java.util.stream.Stream; - -public class Invert extends NumberExpr { - public final NumberExpr inner; - - public Invert(CodeLocation location, NumberExpr inner) { - super(Order.Unary, location); - this.inner = inner; - } - - @Override - public Double get(Scope 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(location, -literal.value); - if (inner instanceof Minus minus) return new Minus(location, minus.subtrahend, minus.minuend).optimize(); - return new Invert(location, inner); - } - - @Override - public Stream> extractSideEffects() { - return inner.extractSideEffects(); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - writer.append('-'); - parenthesize(inner, writer, false); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof Invert invert && inner.equals(invert.inner); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Minus.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Minus.java deleted file mode 100644 index 964a9e0..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Minus.java +++ /dev/null @@ -1,60 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.math; - -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.NumberExpr; -import io.gitlab.jfronny.muscript.ast.literal.NumberLiteral; - -import java.io.IOException; -import java.util.stream.Stream; - -public class Minus extends NumberExpr { - public final NumberExpr minuend; - public final NumberExpr subtrahend; - - public Minus(CodeLocation location, NumberExpr minuend, NumberExpr subtrahend) { - super(Order.Term, location); - this.minuend = minuend; - this.subtrahend = subtrahend; - } - - @Override - public Double get(Scope 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 literal(location, litM.value - litS.value); - if (minuend instanceof Minus minus) - return new Minus(location, minus.minuend, new Plus(minus.location, minus.subtrahend, subtrahend)).optimize(); - if (minuend instanceof Invert invM && subtrahend instanceof Invert invS) - return new Minus(location, invS.inner, invM.inner); - if (minuend instanceof Invert inv) - return new Invert(location, new Plus(location, inv.inner, subtrahend)).optimize(); - if (subtrahend instanceof Invert inv) - return new Plus(location, minuend, inv.inner).optimize(); - return new Minus(location, minuend, subtrahend); - } - - @Override - public Stream> extractSideEffects() { - return Stream.concat(minuend.extractSideEffects(), subtrahend.extractSideEffects()); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - parenthesize(minuend, writer, false); - writer.append(" - "); - parenthesize(subtrahend, writer, true); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof Minus minus && minuend.equals(minus.minuend) && subtrahend.equals(minus.subtrahend); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Modulo.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Modulo.java deleted file mode 100644 index b786d7f..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Modulo.java +++ /dev/null @@ -1,52 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.math; - -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.NumberExpr; -import io.gitlab.jfronny.muscript.ast.literal.NumberLiteral; - -import java.io.IOException; -import java.util.stream.Stream; - -public class Modulo extends NumberExpr { - private final NumberExpr dividend; - private final NumberExpr divisor; - - public Modulo(CodeLocation location, NumberExpr dividend, NumberExpr divisor) { - super(Order.Factor, location); - this.dividend = dividend; - this.divisor = divisor; - } - - @Override - public Double get(Scope 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(location, litD.value % litS.value); - return new Modulo(location, dividend, divisor); - } - - @Override - public Stream> extractSideEffects() { - return Stream.concat(dividend.extractSideEffects(), divisor.extractSideEffects()); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - parenthesize(dividend, writer, false); - writer.append(" % "); - parenthesize(divisor, writer, true); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof Modulo modulo && dividend.equals(modulo.dividend) && divisor.equals(modulo.divisor); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Multiply.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Multiply.java deleted file mode 100644 index 0fc1874..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Multiply.java +++ /dev/null @@ -1,52 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.math; - -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.NumberExpr; -import io.gitlab.jfronny.muscript.ast.literal.NumberLiteral; - -import java.io.IOException; -import java.util.stream.Stream; - -public class Multiply extends NumberExpr { - public final NumberExpr multiplier; - public final NumberExpr multiplicand; - - public Multiply(CodeLocation location, NumberExpr multiplier, NumberExpr multiplicand) { - super(Order.Factor, location); - this.multiplier = multiplier; - this.multiplicand = multiplicand; - } - - @Override - public Double get(Scope 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 literal(location, litEr.value * litAnd.value); - return new Multiply(location, multiplier, multiplicand); - } - - @Override - public Stream> extractSideEffects() { - return Stream.concat(multiplier.extractSideEffects(), multiplicand.extractSideEffects()); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - parenthesize(multiplier, writer, false); - writer.append(" * "); - parenthesize(multiplicand, writer, true); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof Multiply multiply && multiplier.equals(multiply.multiplier) && multiplicand.equals(multiply.multiplicand); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Plus.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Plus.java deleted file mode 100644 index 10f99e2..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Plus.java +++ /dev/null @@ -1,56 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.math; - -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.NumberExpr; -import io.gitlab.jfronny.muscript.ast.literal.NumberLiteral; - -import java.io.IOException; -import java.util.stream.Stream; - -public class Plus extends NumberExpr { - public final NumberExpr augend; - public final NumberExpr addend; - - public Plus(CodeLocation location, NumberExpr augend, NumberExpr addend) { - super(Order.Term, location); - this.augend = augend; - this.addend = addend; - } - - @Override - public Double get(Scope 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 literal(location, litU.value + litD.value); - if (augend instanceof Invert invU && addend instanceof Invert invD) - return new Invert(location, new Plus(location, invU.inner, invD.inner)).optimize(); - if (augend instanceof Invert inv) return new Minus(location, addend, inv.inner).optimize(); - if (addend instanceof Invert inv) return new Minus(location, augend, inv.inner).optimize(); - return new Plus(location, augend, addend); - } - - @Override - public Stream> extractSideEffects() { - return Stream.concat(augend.extractSideEffects(), addend.extractSideEffects()); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - parenthesize(augend, writer, false); - writer.append(" + "); - parenthesize(addend, writer, true); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof Plus plus && augend.equals(plus.augend) && addend.equals(plus.addend); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Power.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Power.java deleted file mode 100644 index b2e539a..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/math/Power.java +++ /dev/null @@ -1,62 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.math; - -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.NumberExpr; -import io.gitlab.jfronny.muscript.ast.literal.NumberLiteral; - -import java.io.IOException; -import java.util.stream.Stream; - -public class Power extends NumberExpr { - private final NumberExpr base; - private final NumberExpr exponent; - - public Power(CodeLocation location, NumberExpr base, NumberExpr exponent) { - super(Order.Exp, location); - this.base = base; - this.exponent = exponent; - } - - @Override - public Double get(Scope 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 literal(location, 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.location, - literal(location, Math.pow(literal.value, exp.value)), - new Power(location, multiply.multiplicand, exp)); - if (multiply.multiplicand instanceof NumberLiteral literal) - return new Multiply(multiply.location, - literal(location, Math.pow(literal.value, exp.value)), - new Power(location, multiply.multiplier, exp)); - } - return new Power(location, base, exponent); - } - - @Override - public Stream> extractSideEffects() { - return Stream.concat(base.extractSideEffects(), exponent.extractSideEffects()); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - parenthesize(base, writer, false); - writer.append(" ^ "); - parenthesize(exponent, writer, true); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof Power power && base.equals(power.base) && exponent.equals(power.exponent); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/string/Concatenate.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/string/Concatenate.java deleted file mode 100644 index c929193..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/string/Concatenate.java +++ /dev/null @@ -1,58 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.string; - -import io.gitlab.jfronny.muscript.compiler.*; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.ast.Expr; -import io.gitlab.jfronny.muscript.ast.StringExpr; -import io.gitlab.jfronny.muscript.ast.literal.StringLiteral; - -import java.io.IOException; -import java.util.stream.Stream; - -public class Concatenate extends StringExpr { - public final StringExpr left; - public final StringExpr right; - - public Concatenate(CodeLocation location, StringExpr left, StringExpr right) { - super(Order.Concat, location); - this.left = left; - this.right = right; - } - - @Override - public String get(Scope 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 literal(location, litL.value + litR.value); - if (right instanceof StringLiteral litR && left instanceof Concatenate concatenate && concatenate.right instanceof StringLiteral litL) { - return new Concatenate(location, concatenate.left, literal(concatenate.location, litL.value + litR.value)); - } - if (left instanceof StringLiteral litL && right instanceof Concatenate concatenate && concatenate.left instanceof StringLiteral litR) { - return new Concatenate(location, literal(concatenate.location, litL.value + litR.value), concatenate.right); - } - return new Concatenate(location, left, right); - } - - @Override - public Stream> extractSideEffects() { - return Stream.concat(left.extractSideEffects(), right.extractSideEffects()); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - parenthesize(left, writer, false); - writer.append(" || "); - parenthesize(right, writer, true); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof Concatenate concatenate && left.equals(concatenate.left) && right.equals(concatenate.right); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/string/StringCoerce.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/string/StringCoerce.java deleted file mode 100644 index 7c896af..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/string/StringCoerce.java +++ /dev/null @@ -1,51 +0,0 @@ -package io.gitlab.jfronny.muscript.ast.string; - -import io.gitlab.jfronny.commons.StringFormatter; -import io.gitlab.jfronny.muscript.compiler.CodeLocation; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.data.Scope; -import io.gitlab.jfronny.muscript.ast.*; -import io.gitlab.jfronny.muscript.ast.literal.*; - -import java.io.IOException; -import java.util.stream.Stream; - -public class StringCoerce extends StringExpr { - private final Expr inner; - - public StringCoerce(CodeLocation location, Expr inner) { - super(inner.order, location); - this.inner = inner; - } - - @Override - public String get(Scope dataRoot) { - return StringFormatter.toString(inner.get(dataRoot)); - } - - @Override - public StringExpr optimize() { - Expr inner = this.inner.optimize(); - if (inner instanceof NullLiteral) return literal(location, "null"); - if (inner instanceof BoolLiteral expr) return literal(location, StringFormatter.toString(expr.value)); - if (inner instanceof DynamicLiteral expr) return literal(location, StringFormatter.toString(expr.value)); - if (inner instanceof NumberLiteral expr) return literal(location, StringFormatter.toStringPrecise(expr.value)); - if (inner instanceof StringExpr expr) return expr; - return new StringCoerce(location, inner); - } - - @Override - public Stream> extractSideEffects() { - return inner.extractSideEffects(); - } - - @Override - public void decompile(ExprWriter writer) throws IOException { - inner.decompile(writer); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof StringCoerce coerce && inner.equals(coerce.inner); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/CodeLocation.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/CodeLocation.java deleted file mode 100644 index 8b11507..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/CodeLocation.java +++ /dev/null @@ -1,25 +0,0 @@ -package io.gitlab.jfronny.muscript.compiler; - -import org.jetbrains.annotations.Nullable; - -import java.util.Arrays; - -public record CodeLocation(int chStart, int chEnd, @Nullable String source, @Nullable String file) { - public static final CodeLocation NONE = new CodeLocation(-1, -1); - - public CodeLocation(int chStart, int chEnd) { - this(chStart, chEnd, null, null); - } - - public CodeLocation(int ch) { - this(ch, ch); - } - - public CodeLocation withSource(String source) { - return new CodeLocation(chStart, chEnd, source, file); - } - - public CodeLocation withFile(String file) { - return new CodeLocation(chStart, chEnd, source, file); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Decompilable.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Decompilable.java deleted file mode 100644 index 7d48fcb..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Decompilable.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.gitlab.jfronny.muscript.compiler; - -import java.io.IOException; -import java.util.Arrays; -import java.util.stream.Collectors; - -public abstract class Decompilable { - public final Order order; - - protected Decompilable(Order order) { - this.order = order; - } - - public abstract void decompile(ExprWriter writer) throws IOException; - - protected void parenthesize(Decompilable val, ExprWriter writer, boolean parenEqualOrder) throws IOException { - boolean wrap = !parenEqualOrder ? val.order.ordinal() < this.order.ordinal() : val.order.ordinal() <= this.order.ordinal(); - if (wrap) writer.append('('); - val.decompile(writer); - if (wrap) writer.append(')'); - } - - /** - * Creates quotes around a string, supports strings containing quotes - */ - public static String enquote(String literalText) { - if (!literalText.contains("'")) return "'" + literalText + "'"; - if (!literalText.contains("\"")) return "\"" + literalText + "\""; - return Arrays.stream(literalText.split("'")).map(s -> "'" + s + "'") - .collect(Collectors.joining(" || \"'\" || ")); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - try (ExprWriter ew = new ExprWriter(sb, false)) { - decompile(ew); - } catch (IOException e) { - throw new RuntimeException("Could not decompile", e); - } - return sb.toString(); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/ExprWriter.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/ExprWriter.java deleted file mode 100644 index e85c6ee..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/ExprWriter.java +++ /dev/null @@ -1,66 +0,0 @@ -package io.gitlab.jfronny.muscript.compiler; - -import java.io.Closeable; -import java.io.IOException; - -public class ExprWriter implements Appendable, Closeable { - private final Appendable target; - private final boolean compact; - private int indent = 0; - - public ExprWriter(Appendable target, boolean compact) { - this.target = target; - this.compact = compact; - } - - @Override - public ExprWriter append(CharSequence csq) throws IOException { - target.append(csq.toString().replace("\r", "").replace("\n", compact ? " " : "\n" + indent())); - return this; - } - - @Override - public ExprWriter append(CharSequence csq, int start, int end) throws IOException { - return append(csq.subSequence(start, end)); - } - - @Override - public ExprWriter append(char c) throws IOException { - switch (c) { - case '\r' -> {} - case '\n' -> { - if (compact) target.append(" "); - else target.append("\n").append(indent()); - } - default -> target.append(c); - } - return this; - } - - public ExprWriter appendLiteral(String s) throws IOException { - if (!Lexer.isValidId(s)) { - if (s.contains("`")) throw new IllegalArgumentException("Not a valid literal: " + s); - else return append('`').append(s).append('`'); - } else return append(s); - } - - private String indent() { - return " ".repeat(indent); - } - - public ExprWriter increaseIndent() { - indent += 2; - return this; - } - - public ExprWriter decreaseIndent() { - if (indent <= 1) throw new IllegalStateException("Attempted to decrease indent lower than 0"); - indent -= 2; - return this; - } - - @Override - public void close() { - if (indent != 0) throw new IllegalStateException("Attempted to close ExprWriter before end"); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Lexer.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Lexer.java deleted file mode 100644 index 3ee7a50..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Lexer.java +++ /dev/null @@ -1,273 +0,0 @@ -package io.gitlab.jfronny.muscript.compiler; - -import java.util.Objects; -import java.util.Set; -import java.util.regex.Pattern; - -/** - * The lexer for muScript, heavily inspired by starscript - * @deprecated To be moved into the lexer module and refactored - */ -@Deprecated(forRemoval = true) -public class Lexer extends VersionedComponent { - public final String file; - - /** - * The type of the token - */ - public Token token; - /** - * The string representation of the token - */ - public String lexeme; - - public char ch; - - public final String source; - public int start, current; - - public boolean passedNewline = false; - - public Lexer(MuScriptVersion version, String source) { - this(version, source, null); - } - - public Lexer(MuScriptVersion version, String source, String file) { - super(version); - this.source = Objects.requireNonNull(source); - this.file = file; - } - - public CodeLocation location() { - return new CodeLocation(start, current - 1, source, file); - } - - /** - * Scans for the next token storing it in {@link Lexer#token} and {@link Lexer#lexeme}. Produces {@link Token#EOF} if the end of source code has been reached and {@link Token#Error} if there has been an error - */ - public void next() { - start = current; - passedNewline = false; - - if (isAtEnd()) { - createToken(Token.EOF); - return; - } - - // Scan expression - skipWhitespaceAndComments(); - if (isAtEnd()) { - createToken(Token.EOF); - return; - } - - char c = advance(); - - if (isDigit(c)) number(); - else if (isIdentifier(c)) identifier(false); - else { - switch (c) { - case '\'', '"' -> string(c); - - case '`' -> identifier(true); - - case '=' -> { - if (match('=')) createToken(Token.EqualEqual); - else createToken(Token.Assign); - } - case '!' -> createToken(match('=') ? Token.BangEqual : Token.Bang); - - case '+' -> createToken(Token.Plus); - case '-' -> { - if (match('>')) createToken(Token.Arrow); - else createToken(Token.Minus); - } - case '*' -> createToken(Token.Star); - case '/' -> createToken(Token.Slash); - case '%' -> createToken(Token.Percentage); - case '>' -> createToken(match('=') ? Token.GreaterEqual : Token.Greater); - case '<' -> createToken(match('=') ? Token.LessEqual : Token.Less); - - case '&' -> createToken(Token.And); - case '|' -> createToken(match('|') ? Token.Concat : Token.Or); - case '^' -> createToken(Token.UpArrow); - - case '.' -> { - if (match('.')) { - if (match('.')) createToken(Token.Ellipsis); - else createToken(Token.Error, "Unexpected '..', did you mean '...'?"); - } else createToken(Token.Dot); - } - case ',' -> createToken(Token.Comma); - case '?' -> createToken(Token.QuestionMark); - case ':' -> createToken(match(':') ? Token.DoubleColon : Token.Colon); - case '(' -> createToken(Token.LeftParen); - case ')' -> createToken(Token.RightParen); - case '[' -> createToken(Token.LeftBracket); - case ']' -> createToken(Token.RightBracket); - case '{' -> createToken(Token.LeftBrace); - case '}' -> createToken(Token.RightBrace); - - case ';' -> { - createToken(Token.Semicolon); - passedNewline = true; - } - - default -> unexpected(); - } - } - } - - private void string(char stringChar) { - while (!isAtEnd() && peek() != stringChar) { - advance(); - } - - if (isAtEnd()) { - createToken(Token.Error, "Unterminated expression"); - } else { - advance(); - createToken(Token.String, source.substring(start + 1, current - 1)); - } - } - - private void number() { - while (isDigit(peek())) advance(); - - if (peek() == '.' && isDigit(peekNext())) { - advance(); - - while (isDigit(peek())) advance(); - } - - createToken(Token.Number); - } - - private void identifier(boolean explicit) { - if (explicit) { - while (!isAtEnd() && peek() != '`') { - advance(); - } - if (isAtEnd()) { - createToken(Token.Error, "Unterminated expression"); - } else { - advance(); - createToken(Token.Identifier, source.substring(start + 1, current - 1)); - } - } else { - while (!isAtEnd()) { - char c = peek(); - if (isIdentifier(c) || isDigit(c)) { - advance(); - } else break; - } - - createToken(Token.Identifier); - - switch (lexeme) { - case "null" -> token = Token.Null; - case "true" -> token = Token.True; - case "false" -> token = Token.False; - } - } - } - - private void skipWhitespaceAndComments() { - while (true) { - if (isAtEnd()) return; - - switch (peek()) { - case ' ', '\t' -> advance(); - case '\r', '\n' -> { - advance(); - passedNewline = true; - } - case '/' -> { - switch (peekNext()) { - case '/' -> { - while (!isAtEnd() && peek() != '\r' && peek() != '\n') advance(); - } - case '*' -> { - advance(); - advance(); - while (!isAtEnd() && (peek() != '*' || peekNext() != '/')) advance(); - if (!isAtEnd()) { - advance(); - advance(); - } - } - default -> { - start = current; - return; - } - } - } - default -> { - start = current; - return; - } - } - } - } - - // Helpers - - private void unexpected() { - createToken(Token.Error, "Unexpected character"); - } - - private void createToken(Token token, String lexeme) { - this.token = token; - this.lexeme = lexeme; - } - - private void createToken(Token token) { - createToken(token, source.substring(start, current)); - } - - private boolean match(char expected) { - if (isAtEnd()) return false; - if (source.charAt(current) != expected) return false; - - advance(); - return true; - } - - private char advance() { - return ch = source.charAt(current++); - } - - private char peek() { - if (isAtEnd()) return '\0'; - return source.charAt(current); - } - - private char peekNext() { - if (current + 1 >= source.length()) return '\0'; - return source.charAt(current + 1); - } - - private boolean isAtEnd() { - return current >= source.length(); - } - - private boolean isDigit(char c) { - return c >= '0' && c <= '9'; - } - - private boolean isIdentifier(char c) { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == '$'; - } - - public static boolean isValidId(String id) { - return IDENTIFIER.matcher(id).matches() && !RESERVED_IDS.contains(id); - } - public static final Set RESERVED_IDS = Set.of("null", "true", "false"); - public static final Pattern IDENTIFIER = Pattern.compile("[a-zA-Z_$][a-zA-Z_$0-9]*"); - - // Visualization - @Override - public String toString() { - return source.substring(0, start) + '[' + source.substring(start, current) + ']' + source.substring(current); - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/MuScriptVersion.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/MuScriptVersion.java deleted file mode 100644 index 8c54bce..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/MuScriptVersion.java +++ /dev/null @@ -1,11 +0,0 @@ -package io.gitlab.jfronny.muscript.compiler; - -public enum MuScriptVersion { - V1, V2, V3; - - public static final MuScriptVersion DEFAULT = V3; - - public boolean contains(MuScriptVersion version) { - return compareTo(version) >= 0; - } -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Order.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Order.java deleted file mode 100644 index 0f49c25..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Order.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.gitlab.jfronny.muscript.compiler; - -public enum Order { - Script, - Conditional, - And, - Or, - Equality, - Concat, - Comparison, - Term, - Factor, - Exp, - Unary, - Call, - Primary; -} diff --git a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Parser.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Parser.java deleted file mode 100644 index bd6400b..0000000 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Parser.java +++ /dev/null @@ -1,508 +0,0 @@ -package io.gitlab.jfronny.muscript.compiler; - -import io.gitlab.jfronny.muscript.ast.*; -import io.gitlab.jfronny.muscript.ast.bool.*; -import io.gitlab.jfronny.muscript.ast.compare.Equal; -import io.gitlab.jfronny.muscript.ast.compare.Greater; -import io.gitlab.jfronny.muscript.ast.conditional.UnresolvedConditional; -import io.gitlab.jfronny.muscript.ast.dynamic.*; -import io.gitlab.jfronny.muscript.ast.dynamic.assign.DynamicAssign; -import io.gitlab.jfronny.muscript.ast.literal.DynamicLiteral; -import io.gitlab.jfronny.muscript.ast.math.*; -import io.gitlab.jfronny.muscript.ast.string.Concatenate; -import io.gitlab.jfronny.muscript.compiler.lexer.LegacyLexer; -import io.gitlab.jfronny.muscript.compiler.lexer.Lexer; -import io.gitlab.jfronny.muscript.data.Script; -import io.gitlab.jfronny.muscript.data.dynamic.additional.DFinal; -import io.gitlab.jfronny.muscript.error.*; -import org.jetbrains.annotations.Nullable; - -import java.util.*; - -public class Parser extends VersionedComponent { - private final Lexer lexer; - - private Lexer.Token previous = null; - - public static Expr parse(MuScriptVersion version, String source) { - return parse(version, source, null); - } - - public static Expr parse(MuScriptVersion version, String source, String file) { - return new Parser(new LegacyLexer(version, source, file)).parse().optimize(); - } - - public static Script parseScript(MuScriptVersion version, String source) { - return parseScript(version, source, null); - } - - public static Script parseScript(MuScriptVersion version, String source, String file) { - return new Parser(new LegacyLexer(version, source, file)).parseScript().optimize(); - } - - public static Script parseMultiScript(MuScriptVersion version, String startFile, SourceFS filesystem) { - return new Script(parseMultiScript(version, startFile, filesystem, new HashSet<>()).stream().flatMap(Script::stream).toList()); - } - - private static List