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; @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) { super(order); this.chStart = chStart; this.chEnd = chEnd; } 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)); } @Deprecated public T get(Dynamic dataRoot) { return get(dataRoot.asObject()); } public abstract Expr optimize(); public BoolExpr asBoolExpr() { if (this instanceof BoolExpr e) return e; throw new TypeMismatchException(chStart, chEnd, Type.Boolean, getResultType()); } public StringExpr asStringExpr() { if (this instanceof StringExpr e) return e; return new StringCoerce(chStart, chEnd, this); } public NumberExpr asNumberExpr() { if (this instanceof NumberExpr e) return e; throw new TypeMismatchException(chStart, chEnd, Type.Number, getResultType()); } public abstract DynamicExpr asDynamicExpr(); public boolean isNull() { return this instanceof NullLiteral; } public static BoolExpr literal(boolean bool) { return literal(-1, bool); } public static StringExpr literal(String string) { return literal(-1, string); } public static NumberExpr literal(double number) { return literal(-1, number); } public static NullLiteral literalNull() { return literalNull(-1); } @Deprecated public static BoolExpr literal(int character, boolean bool) { return literal(character, character, bool); } @Deprecated public static StringExpr literal(int character, String string) { return literal(character, character, string); } @Deprecated public static NumberExpr literal(int character, double number) { return literal(character, character, number); } @Deprecated public static NullLiteral literalNull(int character) { return literalNull(character, character); } public static BoolExpr literal(int chStart, int chEnd, boolean bool) { return new BoolLiteral(chStart, chEnd, bool); } public static StringExpr literal(int chStart, int chEnd, String string) { return new StringLiteral(chStart, chEnd, string); } public static NumberExpr literal(int chStart, int chEnd, double number) { return new NumberLiteral(chStart, chEnd, number); } public static NullLiteral literalNull(int chStart, int chEnd) { return new NullLiteral(chStart, chEnd); } }