From e652bfe6ba8283af21eb39a02d2aec77a015d0c4 Mon Sep 17 00:00:00 2001 From: JFronny Date: Tue, 18 Apr 2023 13:40:34 +0200 Subject: [PATCH] track code location --- .../gitlab/jfronny/muscript/ast/BoolExpr.java | 9 +- .../jfronny/muscript/ast/DynamicExpr.java | 13 +- .../io/gitlab/jfronny/muscript/ast/Expr.java | 58 +++--- .../jfronny/muscript/ast/NullLiteral.java | 12 +- .../jfronny/muscript/ast/NumberExpr.java | 9 +- .../jfronny/muscript/ast/StringExpr.java | 9 +- .../gitlab/jfronny/muscript/ast/bool/And.java | 13 +- .../gitlab/jfronny/muscript/ast/bool/Not.java | 11 +- .../gitlab/jfronny/muscript/ast/bool/Or.java | 13 +- .../jfronny/muscript/ast/compare/Equal.java | 11 +- .../jfronny/muscript/ast/compare/Greater.java | 19 +- .../ast/conditional/BoolConditional.java | 11 +- .../ast/conditional/DynamicConditional.java | 11 +- .../ast/conditional/NumberConditional.java | 11 +- .../ast/conditional/StringConditional.java | 11 +- .../conditional/UnresolvedConditional.java | 16 +- .../jfronny/muscript/ast/dynamic/Bind.java | 6 +- .../jfronny/muscript/ast/dynamic/Call.java | 19 +- .../jfronny/muscript/ast/dynamic/Closure.java | 14 +- .../muscript/ast/dynamic/DynamicCoerce.java | 7 +- .../jfronny/muscript/ast/dynamic/Get.java | 10 +- .../muscript/ast/dynamic/ObjectLiteral.java | 8 +- .../muscript/ast/dynamic/Variable.java | 6 +- .../ast/dynamic/assign/BoolAssign.java | 11 +- .../ast/dynamic/assign/DynamicAssign.java | 14 +- .../ast/dynamic/assign/NumberAssign.java | 11 +- .../ast/dynamic/assign/StringAssign.java | 11 +- .../ast/dynamic/unpack/BoolUnpack.java | 9 +- .../ast/dynamic/unpack/NumberUnpack.java | 9 +- .../ast/dynamic/unpack/StringUnpack.java | 9 +- .../muscript/ast/literal/BoolLiteral.java | 7 +- .../muscript/ast/literal/DynamicLiteral.java | 7 +- .../muscript/ast/literal/NumberLiteral.java | 7 +- .../muscript/ast/literal/StringLiteral.java | 7 +- .../jfronny/muscript/ast/math/Divide.java | 13 +- .../jfronny/muscript/ast/math/Invert.java | 13 +- .../jfronny/muscript/ast/math/Minus.java | 18 +- .../jfronny/muscript/ast/math/Modulo.java | 11 +- .../jfronny/muscript/ast/math/Multiply.java | 11 +- .../jfronny/muscript/ast/math/Plus.java | 15 +- .../jfronny/muscript/ast/math/Power.java | 23 ++- .../muscript/ast/string/Concatenate.java | 15 +- .../muscript/ast/string/StringCoerce.java | 15 +- .../muscript/compiler/CodeLocation.java | 23 +++ .../jfronny/muscript/compiler/Lexer.java | 10 +- .../jfronny/muscript/compiler/Parser.java | 168 +++++++++++------- .../jfronny/muscript/compiler/SourceFS.java | 5 + .../gitlab/jfronny/muscript/data/Script.java | 15 +- .../DynamicTypeConversionException.java | 5 +- .../muscript/error/LocationalError.java | 26 ++- .../muscript/error/LocationalException.java | 30 ++-- .../jfronny/muscript/error/StackFrame.java | 10 +- .../muscript/error/TypeMismatchException.java | 9 +- .../jfronny/muscript/test/AssignTest.java | 3 +- .../jfronny/muscript/test/StackTraceTest.java | 33 ++-- .../muscript/test/ValidExampleTest.java | 2 +- 56 files changed, 500 insertions(+), 382 deletions(-) create mode 100644 muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/CodeLocation.java create mode 100644 muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/SourceFS.java 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 index 7ca12ef..94df0ef 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/BoolExpr.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/BoolExpr.java @@ -1,12 +1,11 @@ package io.gitlab.jfronny.muscript.ast; import io.gitlab.jfronny.muscript.ast.dynamic.DynamicCoerce; -import io.gitlab.jfronny.muscript.compiler.Order; -import io.gitlab.jfronny.muscript.compiler.Type; +import io.gitlab.jfronny.muscript.compiler.*; public abstract non-sealed class BoolExpr extends Expr { - protected BoolExpr(Order order, int chStart, int chEnd) { - super(order, chStart, chEnd); + protected BoolExpr(Order order, CodeLocation location) { + super(order, location); } @Override @@ -19,6 +18,6 @@ public abstract non-sealed class BoolExpr extends Expr { @Override public DynamicExpr asDynamicExpr() { - return new DynamicCoerce(chStart, chEnd, this); + 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 index b5be9c8..afc8e8f 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/DynamicExpr.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/DynamicExpr.java @@ -1,13 +1,12 @@ package io.gitlab.jfronny.muscript.ast; -import io.gitlab.jfronny.muscript.compiler.Order; +import io.gitlab.jfronny.muscript.compiler.*; import io.gitlab.jfronny.muscript.data.dynamic.Dynamic; import io.gitlab.jfronny.muscript.ast.dynamic.unpack.*; -import io.gitlab.jfronny.muscript.compiler.Type; public abstract non-sealed class DynamicExpr extends Expr> { - protected DynamicExpr(Order order, int chStart, int chEnd) { - super(order, chStart, chEnd); + protected DynamicExpr(Order order, CodeLocation location) { + super(order, location); } @Override @@ -20,17 +19,17 @@ public abstract non-sealed class DynamicExpr extends Expr> { @Override public BoolExpr asBoolExpr() { - return new BoolUnpack(chStart, chEnd, this); + return new BoolUnpack(location, this); } @Override public StringExpr asStringExpr() { - return new StringUnpack(chStart, chEnd, this); + return new StringUnpack(location, this); } @Override public NumberExpr asNumberExpr() { - return new NumberUnpack(chStart, chEnd, this); + return new NumberUnpack(location, this); } @Override 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 index 5606ed7..1b7239a 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/Expr.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/Expr.java @@ -12,12 +12,10 @@ import io.gitlab.jfronny.muscript.error.TypeMismatchException; @CanThrow public abstract sealed class Expr extends Decompilable permits BoolExpr, DynamicExpr, NullLiteral, NumberExpr, StringExpr { - public final int chStart; - public final int chEnd; - protected Expr(Order order, int chStart, int chEnd) { + public final CodeLocation location; + protected Expr(Order order, CodeLocation location) { super(order); - this.chStart = chStart; - this.chEnd = chEnd; + this.location = location; } public abstract Type getResultType(); @@ -33,17 +31,17 @@ public abstract sealed class Expr extends Decompilable public BoolExpr asBoolExpr() { if (this instanceof BoolExpr e) return e; - throw new TypeMismatchException(chStart, chEnd, Type.Boolean, getResultType()); + throw new TypeMismatchException(location, Type.Boolean, getResultType()); } public StringExpr asStringExpr() { if (this instanceof StringExpr e) return e; - return new StringCoerce(chStart, chEnd, this); + return new StringCoerce(location, this); } public NumberExpr asNumberExpr() { if (this instanceof NumberExpr e) return e; - throw new TypeMismatchException(chStart, chEnd, Type.Number, getResultType()); + throw new TypeMismatchException(location, Type.Number, getResultType()); } public abstract DynamicExpr asDynamicExpr(); @@ -53,54 +51,74 @@ public abstract sealed class Expr extends Decompilable } public static BoolExpr literal(boolean bool) { - return literal(-1, bool); + return literal(CodeLocation.NONE, bool); } public static StringExpr literal(String string) { - return literal(-1, string); + return literal(CodeLocation.NONE, string); } public static NumberExpr literal(double number) { - return literal(-1, number); + return literal(CodeLocation.NONE, number); } public static NullLiteral literalNull() { - return literalNull(-1); + return literalNull(CodeLocation.NONE); } @Deprecated public static BoolExpr literal(int character, boolean bool) { - return literal(character, character, bool); + return literal(new CodeLocation(character), bool); } @Deprecated public static StringExpr literal(int character, String string) { - return literal(character, character, string); + return literal(new CodeLocation(character), string); } @Deprecated public static NumberExpr literal(int character, double number) { - return literal(character, character, number); + return literal(new CodeLocation(character), number); } @Deprecated public static NullLiteral literalNull(int character) { - return literalNull(character, character); + return literalNull(new CodeLocation(character)); } + @Deprecated public static BoolExpr literal(int chStart, int chEnd, boolean bool) { - return new BoolLiteral(chStart, chEnd, bool); + return literal(new CodeLocation(chStart, chEnd), bool); } + @Deprecated public static StringExpr literal(int chStart, int chEnd, String string) { - return new StringLiteral(chStart, chEnd, string); + return literal(new CodeLocation(chStart, chEnd), string); } + @Deprecated public static NumberExpr literal(int chStart, int chEnd, double number) { - return new NumberLiteral(chStart, chEnd, number); + return literal(new CodeLocation(chStart, chEnd), number); } + @Deprecated public static NullLiteral literalNull(int chStart, int chEnd) { - return new NullLiteral(chStart, chEnd); + return literalNull(new CodeLocation(chStart, chEnd)); + } + + 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 index dd33ae5..08541d7 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/NullLiteral.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/NullLiteral.java @@ -11,8 +11,8 @@ import java.io.IOException; @CanThrow public final class NullLiteral extends Expr { - public NullLiteral(int chStart, int chEnd) { - super(Order.Primary, chStart, chEnd); + public NullLiteral(CodeLocation location) { + super(Order.Primary, location); } @Override @@ -37,22 +37,22 @@ public final class NullLiteral extends Expr { @Override public DynamicExpr asDynamicExpr() { - return new DynamicLiteral<>(chStart, chEnd, new DNull()); + return new DynamicLiteral<>(location, new DNull()); } @Override public NumberExpr asNumberExpr() { - throw new LocationalException(chStart, chEnd, "Attempted to convert null to a number"); + throw new LocationalException(location, "Attempted to convert null to a number"); } @Override public StringExpr asStringExpr() { - return literal(chStart, chEnd, "null"); + return literal(location, "null"); } @Override public BoolExpr asBoolExpr() { - throw new LocationalException(chStart, chEnd, "Attempted to convert null to a boolean"); + throw new LocationalException(location, "Attempted to convert null to a boolean"); } @Override 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 index f142de1..edcb0ae 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/NumberExpr.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/NumberExpr.java @@ -1,12 +1,11 @@ package io.gitlab.jfronny.muscript.ast; import io.gitlab.jfronny.muscript.ast.dynamic.DynamicCoerce; -import io.gitlab.jfronny.muscript.compiler.Order; -import io.gitlab.jfronny.muscript.compiler.Type; +import io.gitlab.jfronny.muscript.compiler.*; public abstract non-sealed class NumberExpr extends Expr { - protected NumberExpr(Order order, int chStart, int chEnd) { - super(order, chStart, chEnd); + protected NumberExpr(Order order, CodeLocation location) { + super(order, location); } @Override @@ -19,6 +18,6 @@ public abstract non-sealed class NumberExpr extends Expr { @Override public DynamicExpr asDynamicExpr() { - return new DynamicCoerce(chStart, chEnd, this); + 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 index d1a2a4f..0e98721 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/StringExpr.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/StringExpr.java @@ -1,12 +1,11 @@ package io.gitlab.jfronny.muscript.ast; import io.gitlab.jfronny.muscript.ast.dynamic.DynamicCoerce; -import io.gitlab.jfronny.muscript.compiler.Order; -import io.gitlab.jfronny.muscript.compiler.Type; +import io.gitlab.jfronny.muscript.compiler.*; public abstract non-sealed class StringExpr extends Expr { - protected StringExpr(Order order, int chStart, int chEnd) { - super(order, chStart, chEnd); + protected StringExpr(Order order, CodeLocation location) { + super(order, location); } @Override @@ -19,6 +18,6 @@ public abstract non-sealed class StringExpr extends Expr { @Override public DynamicExpr asDynamicExpr() { - return new DynamicCoerce(chStart, chEnd, this); + 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 index b62692f..28850ae 100644 --- 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 @@ -1,7 +1,6 @@ package io.gitlab.jfronny.muscript.ast.bool; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +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; @@ -13,8 +12,8 @@ public class And extends BoolExpr { private final BoolExpr left; private final BoolExpr right; - public And(int chStart, int chEnd, BoolExpr left, BoolExpr right) { - super(Order.And, chStart, chEnd); + public And(CodeLocation location, BoolExpr left, BoolExpr right) { + super(Order.And, location); this.left = left; this.right = right; } @@ -28,9 +27,9 @@ public class And extends BoolExpr { public BoolExpr optimize() { BoolExpr left = this.left.optimize(); BoolExpr right = this.right.optimize(); - if (left instanceof BoolLiteral literal) return literal.value ? right : Expr.literal(chStart, chEnd, false); - if (right instanceof BoolLiteral literal) return literal.value ? left : Expr.literal(chStart, chEnd, false); - return new And(chStart, chEnd, left, right); + 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 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 index fcfa63b..d6c5c20 100644 --- 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 @@ -3,8 +3,7 @@ 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.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +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; @@ -15,8 +14,8 @@ import java.io.IOException; public class Not extends BoolExpr { public final BoolExpr inner; - public Not(int chStart, int chEnd, BoolExpr inner) { - super(Order.Unary, chStart, chEnd); + public Not(CodeLocation location, BoolExpr inner) { + super(Order.Unary, location); this.inner = inner; } @@ -29,8 +28,8 @@ public class Not extends BoolExpr { public BoolExpr optimize() { BoolExpr inner = this.inner.optimize(); if (inner instanceof Not not) return not.inner; - if (inner instanceof BoolLiteral literal) return Expr.literal(chStart, chEnd, !literal.value); - return new Not(chStart, chEnd, inner); + if (inner instanceof BoolLiteral literal) return literal(location, !literal.value); + return new Not(location, inner); } @Override 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 index 7332ef2..74e88e7 100644 --- 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 @@ -1,7 +1,6 @@ package io.gitlab.jfronny.muscript.ast.bool; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +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; @@ -13,8 +12,8 @@ public class Or extends BoolExpr { private final BoolExpr left; private final BoolExpr right; - public Or(int chStart, int chEnd, BoolExpr left, BoolExpr right) { - super(Order.Or, chStart, chEnd); + public Or(CodeLocation location, BoolExpr left, BoolExpr right) { + super(Order.Or, location); this.left = left; this.right = right; } @@ -28,9 +27,9 @@ public class Or extends BoolExpr { public BoolExpr optimize() { BoolExpr left = this.left.optimize(); BoolExpr right = this.right.optimize(); - if (left instanceof BoolLiteral literal) return literal.value ? Expr.literal(chStart, chEnd, true) : right; - if (right instanceof BoolLiteral literal) return literal.value ? Expr.literal(chStart, chEnd, true) : left; - return new Or(chStart, chEnd, left, right); + 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 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 index 9263b16..e58cc7a 100644 --- 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 @@ -2,8 +2,7 @@ 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.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +import io.gitlab.jfronny.muscript.compiler.*; import io.gitlab.jfronny.muscript.data.Scope; import io.gitlab.jfronny.muscript.data.dynamic.Dynamic; @@ -14,8 +13,8 @@ public class Equal extends BoolExpr { public final Expr left; public final Expr right; - public Equal(int chStart, int chEnd, Expr left, Expr right) { - super(Order.Equality, chStart, chEnd); + public Equal(CodeLocation location, Expr left, Expr right) { + super(Order.Equality, location); this.left = left; this.right = right; } @@ -34,8 +33,8 @@ public class Equal extends BoolExpr { public BoolExpr optimize() { Expr left = this.left.optimize(); Expr right = this.right.optimize(); - if (left.equals(right)) return Expr.literal(chStart, chEnd, true); - return new Equal(chStart, chEnd, left, right); + if (left.equals(right)) return literal(location, true); + return new Equal(location, left, right); } @Override 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 index 4083fec..ed8efc1 100644 --- 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 @@ -1,7 +1,6 @@ package io.gitlab.jfronny.muscript.ast.compare; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +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; @@ -13,8 +12,8 @@ public class Greater extends BoolExpr { public final NumberExpr left; public final NumberExpr right; - public Greater(int chStart, int chEnd, NumberExpr left, NumberExpr right) { - super(Order.Comparison, chStart, chEnd); + public Greater(CodeLocation location, NumberExpr left, NumberExpr right) { + super(Order.Comparison, location); this.left = left; this.right = right; } @@ -29,19 +28,19 @@ public class Greater extends BoolExpr { NumberExpr left = this.left.optimize(); NumberExpr right = this.right.optimize(); if (left instanceof NumberLiteral litL && right instanceof NumberLiteral litR) - return Expr.literal(chStart, chEnd, litL.value > litR.value); + return literal(location, litL.value > litR.value); if (left instanceof Divide divide) - return new Greater(chStart, chEnd, divide.dividend, new Multiply(divide.chStart, divide.chEnd, right, divide.divisor)).optimize(); + return new Greater(location, divide.dividend, new Multiply(divide.location, right, divide.divisor)).optimize(); if (left instanceof Invert invert) - return new Greater(chStart, chEnd, new Invert(right.chStart, right.chEnd, right), invert.inner).optimize(); + return new Greater(location, new Invert(right.location, right), invert.inner).optimize(); if (left instanceof Minus minus) - return new Greater(chStart, chEnd, minus.minuend, new Plus(minus.chStart, minus.chEnd, minus.subtrahend, right)).optimize(); + 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(chStart, chEnd, plus.augend, new Minus(plus.chStart, plus.chEnd, plus.addend, right)).optimize(); + 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(chStart, chEnd, left, right); + return new Greater(location, left, right); } @Override 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 index 2012022..d002b8f 100644 --- 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 @@ -1,8 +1,7 @@ package io.gitlab.jfronny.muscript.ast.conditional; import io.gitlab.jfronny.muscript.ast.bool.Not; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +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; @@ -14,8 +13,8 @@ public class BoolConditional extends BoolExpr { public final BoolExpr trueExpr; public final BoolExpr falseExpr; - public BoolConditional(int chStart, int chEnd, BoolExpr condition, BoolExpr trueExpr, BoolExpr falseExpr) { - super(Order.Conditional, chStart, chEnd); + public BoolConditional(CodeLocation location, BoolExpr condition, BoolExpr trueExpr, BoolExpr falseExpr) { + super(Order.Conditional, location); this.condition = condition; this.trueExpr = trueExpr; this.falseExpr = falseExpr; @@ -33,8 +32,8 @@ public class BoolConditional extends BoolExpr { 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(chStart, chEnd, not.inner, falseExpr, trueExpr); - return new BoolConditional(chStart, chEnd, condition, trueExpr, falseExpr); + if (condition instanceof Not not) return new BoolConditional(location, not.inner, falseExpr, trueExpr); + return new BoolConditional(location, condition, trueExpr, falseExpr); } @Override 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 index ae57490..12e7173 100644 --- 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 @@ -1,8 +1,7 @@ package io.gitlab.jfronny.muscript.ast.conditional; import io.gitlab.jfronny.muscript.ast.bool.Not; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +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; @@ -16,8 +15,8 @@ public class DynamicConditional extends DynamicExpr { public final DynamicExpr trueExpr; public final DynamicExpr falseExpr; - public DynamicConditional(int chStart, int chEnd, BoolExpr condition, DynamicExpr trueExpr, DynamicExpr falseExpr) { - super(Order.Conditional, chStart, chEnd); + public DynamicConditional(CodeLocation location, BoolExpr condition, DynamicExpr trueExpr, DynamicExpr falseExpr) { + super(Order.Conditional, location); this.condition = condition; this.trueExpr = trueExpr; this.falseExpr = falseExpr; @@ -35,8 +34,8 @@ public class DynamicConditional extends DynamicExpr { 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(chStart, chEnd, not.inner, falseExpr, trueExpr); - return new DynamicConditional(chStart, chEnd, condition, trueExpr, falseExpr); + if (condition instanceof Not not) return new DynamicConditional(location, not.inner, falseExpr, trueExpr); + return new DynamicConditional(location, condition, trueExpr, falseExpr); } @Override 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 index cab3636..c96fce5 100644 --- 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 @@ -1,8 +1,7 @@ package io.gitlab.jfronny.muscript.ast.conditional; import io.gitlab.jfronny.muscript.ast.bool.Not; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +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; @@ -15,8 +14,8 @@ public class NumberConditional extends NumberExpr { public final NumberExpr trueExpr; public final NumberExpr falseExpr; - public NumberConditional(int chStart, int chEnd, BoolExpr condition, NumberExpr trueExpr, NumberExpr falseExpr) { - super(Order.Conditional, chStart, chEnd); + public NumberConditional(CodeLocation location, BoolExpr condition, NumberExpr trueExpr, NumberExpr falseExpr) { + super(Order.Conditional, location); this.condition = condition; this.trueExpr = trueExpr; this.falseExpr = falseExpr; @@ -34,8 +33,8 @@ public class NumberConditional extends NumberExpr { 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(chStart, chEnd, not.inner, falseExpr, trueExpr); - return new NumberConditional(chStart, chEnd, condition, trueExpr, falseExpr); + if (condition instanceof Not not) return new NumberConditional(location, not.inner, falseExpr, trueExpr); + return new NumberConditional(location, condition, trueExpr, falseExpr); } @Override 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 index 94f057d..df4f23a 100644 --- 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 @@ -1,8 +1,7 @@ package io.gitlab.jfronny.muscript.ast.conditional; import io.gitlab.jfronny.muscript.ast.bool.Not; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +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; @@ -15,8 +14,8 @@ public class StringConditional extends StringExpr { public final StringExpr trueExpr; public final StringExpr falseExpr; - public StringConditional(int chStart, int chEnd, BoolExpr condition, StringExpr trueExpr, StringExpr falseExpr) { - super(Order.Conditional, chStart, chEnd); + public StringConditional(CodeLocation location, BoolExpr condition, StringExpr trueExpr, StringExpr falseExpr) { + super(Order.Conditional, location); this.condition = condition; this.trueExpr = trueExpr; this.falseExpr = falseExpr; @@ -34,8 +33,8 @@ public class StringConditional extends StringExpr { 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(chStart, chEnd, not.inner, falseExpr, trueExpr); - return new StringConditional(chStart, chEnd, condition, trueExpr, falseExpr); + if (condition instanceof Not not) return new StringConditional(location, not.inner, falseExpr, trueExpr); + return new StringConditional(location, condition, trueExpr, falseExpr); } @Override 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 index 295d148..177e9c2 100644 --- 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 @@ -17,8 +17,8 @@ public class UnresolvedConditional extends DynamicExpr { private final Expr trueExpr; private final Expr falseExpr; - public UnresolvedConditional(int chStart, int chEnd, BoolExpr condition, Expr trueExpr, Expr falseExpr) { - super(Order.Conditional, chStart, chEnd); + public UnresolvedConditional(CodeLocation location, BoolExpr condition, Expr trueExpr, Expr falseExpr) { + super(Order.Conditional, location); this.condition = condition; this.trueExpr = trueExpr; this.falseExpr = falseExpr; @@ -36,8 +36,8 @@ public class UnresolvedConditional extends DynamicExpr { 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(chStart, chEnd, not.inner, falseExpr, trueExpr); - return new UnresolvedConditional(chStart, chEnd, condition, trueExpr, falseExpr); + if (condition instanceof Not not) return new UnresolvedConditional(location, not.inner, falseExpr, trueExpr); + return new UnresolvedConditional(location, condition, trueExpr, falseExpr); } @Override @@ -60,22 +60,22 @@ public class UnresolvedConditional extends DynamicExpr { @Override public DynamicExpr asDynamicExpr() { - return new DynamicConditional(chStart, chEnd, condition, trueExpr.asDynamicExpr(), falseExpr.asDynamicExpr()); + return new DynamicConditional(location, condition, trueExpr.asDynamicExpr(), falseExpr.asDynamicExpr()); } @Override public BoolExpr asBoolExpr() { - return new BoolConditional(chStart, chEnd, condition, trueExpr.asBoolExpr(), falseExpr.asBoolExpr()); + return new BoolConditional(location, condition, trueExpr.asBoolExpr(), falseExpr.asBoolExpr()); } @Override public StringExpr asStringExpr() { - return new StringConditional(chStart, chEnd, condition, trueExpr.asStringExpr(), falseExpr.asStringExpr()); + return new StringConditional(location, condition, trueExpr.asStringExpr(), falseExpr.asStringExpr()); } @Override public NumberExpr asNumberExpr() { - return new NumberConditional(chStart, chEnd, condition, trueExpr.asNumberExpr(), falseExpr.asNumberExpr()); + return new NumberConditional(location, condition, trueExpr.asNumberExpr(), falseExpr.asNumberExpr()); } @Override 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 index 45d04d5..3c68050 100644 --- 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 @@ -14,8 +14,8 @@ public class Bind extends DynamicExpr { public final DynamicExpr callable; public final DynamicExpr parameter; - public Bind(int chStart, int chEnd, DynamicExpr callable, DynamicExpr parameter) { - super(Order.Call, chStart, chEnd); + public Bind(CodeLocation location, DynamicExpr callable, DynamicExpr parameter) { + super(Order.Call, location); this.callable = callable; this.parameter = parameter; } @@ -47,6 +47,6 @@ public class Bind extends DynamicExpr { @Override public DynamicExpr optimize() { - return new Bind(chStart, chEnd, callable.optimize(), parameter.optimize()); + return new Bind(location, callable.optimize(), parameter.optimize()); } } 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 index 5af53e7..0425a28 100644 --- 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 @@ -3,8 +3,7 @@ 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.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +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; @@ -21,8 +20,8 @@ public class Call extends DynamicExpr { public final DynamicExpr left; public final List args; - public Call(int chStart, int chEnd, DynamicExpr left, List args) { - super(Order.Call, chStart, chEnd); + public Call(CodeLocation location, DynamicExpr left, List args) { + super(Order.Call, location); this.left = left; this.args = args; } @@ -36,18 +35,18 @@ public class Call extends DynamicExpr { .asCallable(); arg = DFinal.of(args.stream().flatMap(e -> e.get(dataRoot)).toArray(Dynamic[]::new)); } catch (DynamicTypeConversionException e) { - throw e.locational(chStart, chEnd); + throw e.locational(location); } catch (RuntimeException e) { - throw new LocationalException(chStart, chEnd, "Could not perform call successfully", e); + throw new LocationalException(location, "Could not perform call successfully", e); } try { return dc.getValue().apply(arg); } catch (LocationalException le) { - throw le.appendStack(new StackFrame.Raw(dc.getName(), left.chStart)); + throw le.appendStack(new StackFrame.Raw(location.file(), dc.getName(), left.location.chStart())); } catch (DynamicTypeConversionException e) { - throw e.locational(chStart, chEnd); + throw e.locational(location); } catch (RuntimeException e) { - throw new LocationalException(chStart, chEnd, "Could not perform call successfully", e); + throw new LocationalException(location, "Could not perform call successfully", e); } } @@ -60,7 +59,7 @@ public class Call extends DynamicExpr { args.add(new Arg(bind.parameter, false)); } for (Arg arg : this.args) args.add(arg.optimize()); - return new Call(chStart, chEnd, left, args); + return new Call(location, left, args); } @Override 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 index 650afc3..f0572c0 100644 --- 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 @@ -19,12 +19,12 @@ public class Closure extends DynamicExpr { private final DynamicExpr fin; private final boolean variadic; - public Closure(int chStart, int chEnd, List boundArgs, List> expressions, boolean variadic) { - this(chStart, chEnd, boundArgs, expressions.subList(0, expressions.size() - 1), expressions.get(expressions.size() - 1).asDynamicExpr(), variadic); + public Closure(CodeLocation location, List boundArgs, List> expressions, boolean variadic) { + this(location, boundArgs, expressions.subList(0, expressions.size() - 1), expressions.get(expressions.size() - 1).asDynamicExpr(), variadic); } - private Closure(int chStart, int chEnd, List boundArgs, List> steps, DynamicExpr fin, boolean variadic) { - super(Order.Primary, chStart, chEnd); + 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; @@ -37,8 +37,8 @@ public class Closure extends DynamicExpr { int ac = args.size(); int ae = boundArgs.size(); if (variadic) ae--; - if (ac < ae) throw new LocationalException(chStart, chEnd, "Invoked with too few arguments (expected " + ae + " but got " + ac + ")"); - if (!variadic && ac > ae) throw new LocationalException(chStart, chEnd, "Invoked with too many arguments (expected " + ae + " but got " + ac + ")"); + 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) { @@ -56,7 +56,7 @@ public class Closure extends DynamicExpr { @Override public DynamicExpr optimize() { // Eliminating side effect free steps might be possible, but would be too much work imo - return new Closure(chStart, chEnd, boundArgs, steps.stream().>map(Expr::optimize).toList(), fin.optimize(), variadic); + return new Closure(location, boundArgs, steps.stream().>map(Expr::optimize).toList(), fin.optimize(), variadic); } @Override 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 index 9abf076..6d5d5ee 100644 --- 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 @@ -2,6 +2,7 @@ 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.*; @@ -12,8 +13,8 @@ import java.io.IOException; public class DynamicCoerce extends DynamicExpr { public final Expr inner; - public DynamicCoerce(int chStart, int chEnd, Expr inner) { - super(inner.order, chStart, chEnd); + public DynamicCoerce(CodeLocation location, Expr inner) { + super(inner.order, location); this.inner = inner; if (!(inner instanceof DynamicExpr) && !(inner instanceof BoolExpr) @@ -40,7 +41,7 @@ public class DynamicCoerce extends DynamicExpr { 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(chStart, chEnd, inner); + return new DynamicCoerce(location, inner); } @Override 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 index 743d03b..81761e5 100644 --- 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 @@ -18,12 +18,12 @@ public class Get extends DynamicExpr { private final DynamicExpr left; private final Expr name; - public Get(int chStart, int chEnd, DynamicExpr left, Expr name) { - super(Order.Call, chStart, chEnd); + 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(chStart, chEnd, Type.String, name.getResultType(), "Name must be either a string or a number"); + throw new TypeMismatchException(location, Type.String, name.getResultType(), "Name must be either a string or a number"); } } @@ -35,14 +35,14 @@ public class Get extends DynamicExpr { } else if (left instanceof DList l) { return l.get(name.asNumberExpr().get(dataRoot).intValue()); } - throw new DynamicTypeConversionException("object or list", left).locational(chStart, chEnd); + 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(chStart, chEnd, left, name); + return new Get(location, left, name); } @Override 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 index 6b82b56..0a5ba32 100644 --- 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 @@ -14,8 +14,8 @@ import java.util.Map; public class ObjectLiteral extends DynamicExpr { public final Map content; - public ObjectLiteral(int chStart, int chEnd, Map content) { - super(Order.Primary, chStart, chEnd); + public ObjectLiteral(CodeLocation location, Map content) { + super(Order.Primary, location); this.content = content; } @@ -37,8 +37,8 @@ public class ObjectLiteral extends DynamicExpr { else literal = false; content.put(entry.getKey(), de); } - if (literal) return new DynamicLiteral<>(chStart, chEnd, DFinal.of(literalContent)); - return new ObjectLiteral(chStart, chEnd, content); + if (literal) return new DynamicLiteral<>(location, DFinal.of(literalContent)); + return new ObjectLiteral(location, content); } @Override 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 index de7a73f..4dc0df1 100644 --- 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 @@ -15,8 +15,8 @@ import java.io.IOException; public class Variable extends DynamicExpr { public final String name; - public Variable(int chStart, int chEnd, String name) { - super(Order.Primary, chStart, chEnd); + public Variable(CodeLocation location, String name) { + super(Order.Primary, location); this.name = name; } @@ -24,7 +24,7 @@ public class Variable extends DynamicExpr { public Dynamic get(Scope dataRoot) { if (name.equals("this")) return dataRoot; if (dataRoot.has(name)) return dataRoot.get(name); - else throw new LocationalException(chStart, chEnd, "This object doesn't contain '" + name + "'"); + else throw new LocationalException(location, "This object doesn't contain '" + name + "'"); } @Override 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 index 1f35553..812fc85 100644 --- 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 @@ -1,8 +1,7 @@ package io.gitlab.jfronny.muscript.ast.dynamic.assign; import io.gitlab.jfronny.muscript.ast.BoolExpr; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +import io.gitlab.jfronny.muscript.compiler.*; import io.gitlab.jfronny.muscript.data.Scope; import io.gitlab.jfronny.muscript.error.LocationalException; @@ -12,9 +11,9 @@ public class BoolAssign extends BoolExpr { private final String name; private final BoolExpr value; - protected BoolAssign(int chStart, int chEnd, String name, BoolExpr value) { - super(Order.Primary, chStart, chEnd); - if (name.equals("this")) throw new LocationalException(chStart, chEnd, "Cannot reassign 'this'"); + 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; } @@ -28,7 +27,7 @@ public class BoolAssign extends BoolExpr { @Override public BoolExpr optimize() { - return new BoolAssign(chStart, chEnd, name, value.optimize()); + return new BoolAssign(location, name, value.optimize()); } @Override 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 index 3a68d9a..19d1c96 100644 --- 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 @@ -13,9 +13,9 @@ public class DynamicAssign extends DynamicExpr { private final String name; private final DynamicExpr value; - public DynamicAssign(int chStart, int chEnd, String name, DynamicExpr value) { - super(Order.Primary, chStart, chEnd); - if (name.equals("this")) throw new LocationalException(chStart, chEnd, "Cannot reassign 'this'"); + 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; } @@ -29,7 +29,7 @@ public class DynamicAssign extends DynamicExpr { @Override public DynamicExpr optimize() { - return new DynamicAssign(chStart, chEnd, name, value.optimize()); + return new DynamicAssign(location, name, value.optimize()); } @Override @@ -40,17 +40,17 @@ public class DynamicAssign extends DynamicExpr { @Override public BoolExpr asBoolExpr() { - return new BoolAssign(chStart, chEnd, name, value.asBoolExpr()); + return new BoolAssign(location, name, value.asBoolExpr()); } @Override public StringExpr asStringExpr() { - return new StringAssign(chStart, chEnd, name, value.asStringExpr()); + return new StringAssign(location, name, value.asStringExpr()); } @Override public NumberExpr asNumberExpr() { - return new NumberAssign(chStart, chEnd, name, value.asNumberExpr()); + return new NumberAssign(location, name, value.asNumberExpr()); } @Override 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 index 06aa56d..a8293ba 100644 --- 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 @@ -1,8 +1,7 @@ package io.gitlab.jfronny.muscript.ast.dynamic.assign; import io.gitlab.jfronny.muscript.ast.NumberExpr; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +import io.gitlab.jfronny.muscript.compiler.*; import io.gitlab.jfronny.muscript.data.Scope; import io.gitlab.jfronny.muscript.error.LocationalException; @@ -12,9 +11,9 @@ public class NumberAssign extends NumberExpr { private final String name; private final NumberExpr value; - protected NumberAssign(int chStart, int chEnd, String name, NumberExpr value) { - super(Order.Primary, chStart, chEnd); - if (name.equals("this")) throw new LocationalException(chStart, chEnd, "Cannot reassign 'this'"); + 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; } @@ -28,7 +27,7 @@ public class NumberAssign extends NumberExpr { @Override public NumberExpr optimize() { - return new NumberAssign(chStart, chEnd, name, value.optimize()); + return new NumberAssign(location, name, value.optimize()); } @Override 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 index b303c46..1bc2c10 100644 --- 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 @@ -1,8 +1,7 @@ package io.gitlab.jfronny.muscript.ast.dynamic.assign; import io.gitlab.jfronny.muscript.ast.StringExpr; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +import io.gitlab.jfronny.muscript.compiler.*; import io.gitlab.jfronny.muscript.data.Scope; import io.gitlab.jfronny.muscript.error.LocationalException; @@ -12,9 +11,9 @@ public class StringAssign extends StringExpr { private final String name; private final StringExpr value; - protected StringAssign(int chStart, int chEnd, String name, StringExpr value) { - super(Order.Primary, chStart, chEnd); - if (name.equals("this")) throw new LocationalException(chStart, chEnd, "Cannot reassign 'this'"); + 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; } @@ -28,7 +27,7 @@ public class StringAssign extends StringExpr { @Override public StringExpr optimize() { - return new StringAssign(chStart, chEnd, name, value.optimize()); + return new StringAssign(location, name, value.optimize()); } @Override 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 index 8476b7e..a04fd78 100644 --- 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 @@ -1,5 +1,6 @@ package 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.DynamicTypeConversionException; @@ -16,8 +17,8 @@ import java.io.IOException; public class BoolUnpack extends BoolExpr { public final DynamicExpr inner; - public BoolUnpack(int chStart, int chEnd, DynamicExpr inner) { - super(inner.order, chStart, chEnd); + public BoolUnpack(CodeLocation location, DynamicExpr inner) { + super(inner.order, location); this.inner = inner; } @@ -26,7 +27,7 @@ public class BoolUnpack extends BoolExpr { try { return inner.get(dataRoot).asBool().getValue(); } catch (DynamicTypeConversionException e) { - throw e.locational(chStart, chEnd); + throw e.locational(location); } } @@ -34,7 +35,7 @@ public class BoolUnpack extends BoolExpr { public BoolExpr optimize() { DynamicExpr inner = this.inner.optimize(); if (inner instanceof DynamicCoerce coerce) return coerce.inner.asBoolExpr(); - return new BoolUnpack(chStart, chEnd, inner); + return new BoolUnpack(location, inner); } @Override 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 index 214be3f..184bd1f 100644 --- 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 @@ -1,5 +1,6 @@ package 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.DynamicTypeConversionException; @@ -16,8 +17,8 @@ import java.io.IOException; public class NumberUnpack extends NumberExpr { public final DynamicExpr inner; - public NumberUnpack(int chStart, int chEnd, DynamicExpr inner) { - super(inner.order, chStart, chEnd); + public NumberUnpack(CodeLocation location, DynamicExpr inner) { + super(inner.order, location); this.inner = inner; } @@ -26,7 +27,7 @@ public class NumberUnpack extends NumberExpr { try { return inner.get(dataRoot).asNumber().getValue(); } catch (DynamicTypeConversionException e) { - throw e.locational(chStart, chEnd); + throw e.locational(location); } } @@ -34,7 +35,7 @@ public class NumberUnpack extends NumberExpr { public NumberExpr optimize() { DynamicExpr inner = this.inner.optimize(); if (inner instanceof DynamicCoerce coerce) return coerce.inner.asNumberExpr(); - return new NumberUnpack(chStart, chEnd, inner.optimize()); + return new NumberUnpack(location, inner.optimize()); } @Override 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 index 62664cc..e9ea461 100644 --- 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 @@ -1,5 +1,6 @@ package 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.DynamicTypeConversionException; @@ -16,8 +17,8 @@ import java.io.IOException; public class StringUnpack extends StringExpr { public final DynamicExpr inner; - public StringUnpack(int chStart, int chEnd, DynamicExpr inner) { - super(inner.order, chStart, chEnd); + public StringUnpack(CodeLocation location, DynamicExpr inner) { + super(inner.order, location); this.inner = inner; } @@ -26,7 +27,7 @@ public class StringUnpack extends StringExpr { try { return inner.get(dataRoot).asString().getValue(); } catch (DynamicTypeConversionException e) { - throw e.locational(chStart, chEnd); + throw e.locational(location); } } @@ -34,7 +35,7 @@ public class StringUnpack extends StringExpr { public StringExpr optimize() { DynamicExpr inner = this.inner.optimize(); if (inner instanceof DynamicCoerce coerce) return coerce.inner.asStringExpr(); - return new StringUnpack(chStart, chEnd, inner); + return new StringUnpack(location, inner); } @Override 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 index 56882ae..f0ef9ee 100644 --- 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 @@ -1,7 +1,6 @@ package io.gitlab.jfronny.muscript.ast.literal; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +import io.gitlab.jfronny.muscript.compiler.*; import io.gitlab.jfronny.muscript.data.Scope; import io.gitlab.jfronny.muscript.ast.BoolExpr; @@ -10,8 +9,8 @@ import java.io.IOException; public final class BoolLiteral extends BoolExpr { public final boolean value; - public BoolLiteral(int chStart, int chEnd, boolean value) { - super(Order.Primary, chStart, chEnd); + public BoolLiteral(CodeLocation location, boolean value) { + super(Order.Primary, location); this.value = 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 index 6a291d7..7270a1d 100644 --- 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 @@ -1,7 +1,6 @@ package io.gitlab.jfronny.muscript.ast.literal; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +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; @@ -11,8 +10,8 @@ import java.io.IOException; public final class DynamicLiteral extends DynamicExpr { public final Dynamic value; - public DynamicLiteral(int chStart, int chEnd, Dynamic value) { - super(Order.Primary, chStart, chEnd); + public DynamicLiteral(CodeLocation location, Dynamic value) { + super(Order.Primary, location); this.value = 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 index baa7627..ffbd80b 100644 --- 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 @@ -1,8 +1,7 @@ package io.gitlab.jfronny.muscript.ast.literal; import io.gitlab.jfronny.commons.StringFormatter; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +import io.gitlab.jfronny.muscript.compiler.*; import io.gitlab.jfronny.muscript.data.Scope; import io.gitlab.jfronny.muscript.ast.NumberExpr; @@ -11,8 +10,8 @@ import java.io.IOException; public final class NumberLiteral extends NumberExpr { public final double value; - public NumberLiteral(int chStart, int chEnd, double value) { - super(Order.Primary, chStart, chEnd); + public NumberLiteral(CodeLocation location, double value) { + super(Order.Primary, location); this.value = 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 index 43a93e3..f098876 100644 --- 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 @@ -1,8 +1,7 @@ package io.gitlab.jfronny.muscript.ast.literal; import io.gitlab.jfronny.muscript.ast.StringExpr; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +import io.gitlab.jfronny.muscript.compiler.*; import io.gitlab.jfronny.muscript.data.Scope; import java.io.IOException; @@ -10,8 +9,8 @@ import java.io.IOException; public final class StringLiteral extends StringExpr { public final String value; - public StringLiteral(int chStart, int chEnd, String value) { - super(Order.Primary, chStart, chEnd); + public StringLiteral(CodeLocation location, String value) { + super(Order.Primary, location); this.value = 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 index 2a0f8f6..403cfee 100644 --- 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 @@ -1,7 +1,6 @@ package io.gitlab.jfronny.muscript.ast.math; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +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; @@ -13,8 +12,8 @@ public class Divide extends NumberExpr { public final NumberExpr dividend; public final NumberExpr divisor; - public Divide(int chStart, int chEnd, NumberExpr dividend, NumberExpr divisor) { - super(Order.Factor, chStart, chEnd); + public Divide(CodeLocation location, NumberExpr dividend, NumberExpr divisor) { + super(Order.Factor, location); this.dividend = dividend; this.divisor = divisor; } @@ -29,10 +28,10 @@ public class Divide extends NumberExpr { NumberExpr dividend = this.dividend.optimize(); NumberExpr divisor = this.divisor.optimize(); if (dividend instanceof NumberLiteral litL && divisor instanceof NumberLiteral litR) - return Expr.literal(chStart, chEnd, litL.value / litR.value); + return literal(location, litL.value / litR.value); if (dividend instanceof Divide divide && divide.dividend instanceof NumberLiteral literal) - return new Divide(chStart, chEnd, divide.dividend, new Multiply(divide.chStart, dividend.chEnd, divisor, literal)).optimize(); - return new Divide(chStart, chEnd, dividend, divisor); + return new Divide(location, divide.dividend, new Multiply(divide.location, divisor, literal)).optimize(); + return new Divide(location, dividend, divisor); } @Override 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 index d5553b9..8821799 100644 --- 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 @@ -1,7 +1,6 @@ package io.gitlab.jfronny.muscript.ast.math; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +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; @@ -12,8 +11,8 @@ import java.io.IOException; public class Invert extends NumberExpr { public final NumberExpr inner; - public Invert(int chStart, int chEnd, NumberExpr inner) { - super(Order.Unary, chStart, chEnd); + public Invert(CodeLocation location, NumberExpr inner) { + super(Order.Unary, location); this.inner = inner; } @@ -26,9 +25,9 @@ public class Invert extends NumberExpr { public NumberExpr optimize() { NumberExpr inner = this.inner.optimize(); if (inner instanceof Invert invert) return invert.inner; - if (inner instanceof NumberLiteral literal) return Expr.literal(chStart, chEnd, -literal.value); - if (inner instanceof Minus minus) return new Minus(chStart, chEnd, minus.subtrahend, minus.minuend).optimize(); - return new Invert(chStart, chEnd, 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 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 index 99d9769..0e5c74c 100644 --- 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 @@ -1,7 +1,6 @@ package io.gitlab.jfronny.muscript.ast.math; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +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; @@ -13,8 +12,8 @@ public class Minus extends NumberExpr { public final NumberExpr minuend; public final NumberExpr subtrahend; - public Minus(int chStart, int chEnd, NumberExpr minuend, NumberExpr subtrahend) { - super(Order.Term, chStart, chEnd); + public Minus(CodeLocation location, NumberExpr minuend, NumberExpr subtrahend) { + super(Order.Term, location); this.minuend = minuend; this.subtrahend = subtrahend; } @@ -29,10 +28,15 @@ public class Minus extends NumberExpr { NumberExpr minuend = this.minuend.optimize(); NumberExpr subtrahend = this.subtrahend.optimize(); if (minuend instanceof NumberLiteral litM && subtrahend instanceof NumberLiteral litS) - return Expr.literal(chStart, chEnd, litM.value - litS.value); + return literal(location, litM.value - litS.value); if (minuend instanceof Minus minus) - return new Minus(chStart, chEnd, minus.minuend, new Plus(minus.chStart, minus.chEnd, minus.subtrahend, subtrahend)).optimize(); - return new Minus(chStart, chEnd, minuend, subtrahend); + 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 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 index eb8013a..d8110b1 100644 --- 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 @@ -1,7 +1,6 @@ package io.gitlab.jfronny.muscript.ast.math; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +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; @@ -13,8 +12,8 @@ public class Modulo extends NumberExpr { private final NumberExpr dividend; private final NumberExpr divisor; - public Modulo(int chStart, int chEnd, NumberExpr dividend, NumberExpr divisor) { - super(Order.Factor, chStart, chEnd); + public Modulo(CodeLocation location, NumberExpr dividend, NumberExpr divisor) { + super(Order.Factor, location); this.dividend = dividend; this.divisor = divisor; } @@ -29,8 +28,8 @@ public class Modulo extends NumberExpr { NumberExpr dividend = this.dividend.optimize(); NumberExpr divisor = this.divisor.optimize(); if (dividend instanceof NumberLiteral litD && divisor instanceof NumberLiteral litS) - return Expr.literal(chStart, chEnd, litD.value % litS.value); - return new Modulo(chStart, chEnd, dividend, divisor); + return Expr.literal(location, litD.value % litS.value); + return new Modulo(location, dividend, divisor); } @Override 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 index 1fb9f83..b1851c6 100644 --- 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 @@ -1,7 +1,6 @@ package io.gitlab.jfronny.muscript.ast.math; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +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; @@ -13,8 +12,8 @@ public class Multiply extends NumberExpr { public final NumberExpr multiplier; public final NumberExpr multiplicand; - public Multiply(int chStart, int chEnd, NumberExpr multiplier, NumberExpr multiplicand) { - super(Order.Factor, chStart, chEnd); + public Multiply(CodeLocation location, NumberExpr multiplier, NumberExpr multiplicand) { + super(Order.Factor, location); this.multiplier = multiplier; this.multiplicand = multiplicand; } @@ -29,8 +28,8 @@ public class Multiply extends NumberExpr { NumberExpr multiplier = this.multiplier.optimize(); NumberExpr multiplicand = this.multiplicand.optimize(); if (multiplier instanceof NumberLiteral litEr && multiplicand instanceof NumberLiteral litAnd) - return Expr.literal(chStart, chEnd, litEr.value * litAnd.value); - return new Multiply(chStart, chEnd, multiplier, multiplicand); + return literal(location, litEr.value * litAnd.value); + return new Multiply(location, multiplier, multiplicand); } @Override 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 index e84dc45..6ae5a4b 100644 --- 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 @@ -1,7 +1,6 @@ package io.gitlab.jfronny.muscript.ast.math; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +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; @@ -13,8 +12,8 @@ public class Plus extends NumberExpr { public final NumberExpr augend; public final NumberExpr addend; - public Plus(int chStart, int chEnd, NumberExpr augend, NumberExpr addend) { - super(Order.Term, chStart, chEnd); + public Plus(CodeLocation location, NumberExpr augend, NumberExpr addend) { + super(Order.Term, location); this.augend = augend; this.addend = addend; } @@ -29,8 +28,12 @@ public class Plus extends NumberExpr { NumberExpr augend = this.augend.optimize(); NumberExpr addend = this.addend.optimize(); if (augend instanceof NumberLiteral litU && addend instanceof NumberLiteral litD) - return Expr.literal(chStart, chEnd, litU.value + litD.value); - return new Plus(chStart, chEnd, augend, addend); + 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 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 index 913ca55..69687cf 100644 --- 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 @@ -1,7 +1,6 @@ package io.gitlab.jfronny.muscript.ast.math; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +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; @@ -13,8 +12,8 @@ public class Power extends NumberExpr { private final NumberExpr base; private final NumberExpr exponent; - public Power(int chStart, int chEnd, NumberExpr base, NumberExpr exponent) { - super(Order.Exp, chStart, chEnd); + public Power(CodeLocation location, NumberExpr base, NumberExpr exponent) { + super(Order.Exp, location); this.base = base; this.exponent = exponent; } @@ -29,18 +28,18 @@ public class Power extends NumberExpr { NumberExpr base = this.base.optimize(); NumberExpr exponent = this.exponent.optimize(); if (base instanceof NumberLiteral litB && exponent instanceof NumberLiteral litE) - return Expr.literal(chStart, chEnd, Math.pow(litB.value, litE.value)); + 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.chStart, multiply.chEnd, - Expr.literal(chStart, chEnd, Math.pow(literal.value, exp.value)), - new Power(chStart, chEnd, multiply.multiplicand, exp)); + 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.chStart, multiply.chEnd, - Expr.literal(chStart, chEnd, Math.pow(literal.value, exp.value)), - new Power(chStart, chEnd, multiply.multiplier, exp)); + return new Multiply(multiply.location, + literal(location, Math.pow(literal.value, exp.value)), + new Power(location, multiply.multiplier, exp)); } - return new Power(chStart, chEnd, base, exponent); + return new Power(location, base, exponent); } @Override 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 index fc64b34..a4281d2 100644 --- 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 @@ -1,7 +1,6 @@ package io.gitlab.jfronny.muscript.ast.string; -import io.gitlab.jfronny.muscript.compiler.ExprWriter; -import io.gitlab.jfronny.muscript.compiler.Order; +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; @@ -13,8 +12,8 @@ public class Concatenate extends StringExpr { public final StringExpr left; public final StringExpr right; - public Concatenate(int chStart, int chEnd, StringExpr left, StringExpr right) { - super(Order.Concat, chStart, chEnd); + public Concatenate(CodeLocation location, StringExpr left, StringExpr right) { + super(Order.Concat, location); this.left = left; this.right = right; } @@ -29,14 +28,14 @@ public class Concatenate extends StringExpr { StringExpr left = this.left.optimize(); StringExpr right = this.right.optimize(); if (left instanceof StringLiteral litL && right instanceof StringLiteral litR) - return Expr.literal(chStart, chEnd, litL.value + litR.value); + return literal(location, litL.value + litR.value); if (right instanceof StringLiteral litR && left instanceof Concatenate concatenate && concatenate.right instanceof StringLiteral litL) { - return new Concatenate(chStart, chEnd, concatenate.left, Expr.literal(concatenate.chStart, concatenate.chEnd, litL.value + litR.value)); + 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(chStart, chEnd, Expr.literal(concatenate.chStart, concatenate.chEnd, litL.value + litR.value), concatenate.right); + return new Concatenate(location, literal(concatenate.location, litL.value + litR.value), concatenate.right); } - return new Concatenate(chStart, chEnd, left, right); + return new Concatenate(location, left, right); } @Override 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 index 9573918..afd2119 100644 --- 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 @@ -1,6 +1,7 @@ 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.*; @@ -11,8 +12,8 @@ import java.io.IOException; public class StringCoerce extends StringExpr { private final Expr inner; - public StringCoerce(int chStart, int chEnd, Expr inner) { - super(inner.order, chStart, chEnd); + public StringCoerce(CodeLocation location, Expr inner) { + super(inner.order, location); this.inner = inner; } @@ -24,12 +25,12 @@ public class StringCoerce extends StringExpr { @Override public StringExpr optimize() { Expr inner = this.inner.optimize(); - if (inner instanceof NullLiteral) return Expr.literal(chStart, chEnd, "null"); - if (inner instanceof BoolLiteral expr) return Expr.literal(chStart, chEnd, StringFormatter.toString(expr.value)); - if (inner instanceof DynamicLiteral expr) return Expr.literal(chStart, chEnd, StringFormatter.toString(expr.value)); - if (inner instanceof NumberLiteral expr) return Expr.literal(chStart, chEnd, StringFormatter.toString(expr.value)); + 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.toString(expr.value)); if (inner instanceof StringExpr expr) return expr; - return new StringCoerce(chStart, chEnd, inner); + return new StringCoerce(location, inner); } @Override 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 new file mode 100644 index 0000000..387df3f --- /dev/null +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/CodeLocation.java @@ -0,0 +1,23 @@ +package io.gitlab.jfronny.muscript.compiler; + +import org.jetbrains.annotations.Nullable; + +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/Lexer.java b/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Lexer.java index 5126b49..e87bb63 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Lexer.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Lexer.java @@ -1,10 +1,13 @@ package io.gitlab.jfronny.muscript.compiler; +import java.util.Objects; import java.util.Set; import java.util.regex.Pattern; // Heavily inspired by starscript public class Lexer { + public final String file; + /** * The type of the token */ @@ -20,7 +23,12 @@ public class Lexer { public int start, current; public Lexer(String source) { - this.source = source; + this(source, null); + } + + public Lexer(String source, String file) { + this.source = Objects.requireNonNull(source); + this.file = file; } /** 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 index f6adb87..9123a24 100644 --- a/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Parser.java +++ b/muscript/src/main/java/io/gitlab/jfronny/muscript/compiler/Parser.java @@ -16,6 +16,7 @@ import io.gitlab.jfronny.muscript.error.*; import org.jetbrains.annotations.Nullable; import java.util.*; +import java.util.stream.Collectors; public class Parser { private final Lexer lexer; @@ -24,11 +25,56 @@ public class Parser { private final TokenData current = new TokenData(); public static Expr parse(String source) { - return new Parser(new Lexer(source)).parse().optimize(); + return parse(source, null); + } + + public static Expr parse(String source, String file) { + return new Parser(new Lexer(source, file)).parse().optimize(); } public static Script parseScript(String source) { - return new Parser(new Lexer(source)).parseScript().optimize(); + return parseScript(source, null); + } + + public static Script parseScript(String source, String file) { + return new Parser(new Lexer(source, file)).parseScript().optimize(); + } + + public static Script parseMultiScript(String startFile, SourceFS filesystem) { + return new Script(parseMultiScript(startFile, filesystem, new HashSet<>()).stream().flatMap(Script::stream).toList()); + } + + private static List