package io.gitlab.jfronny.muscript.ast.context; import io.gitlab.jfronny.commons.StringFormatter; import io.gitlab.jfronny.muscript.ast.*; import io.gitlab.jfronny.muscript.ast.bool.BoolAssign; import io.gitlab.jfronny.muscript.ast.bool.BoolConditional; import io.gitlab.jfronny.muscript.ast.bool.BoolLiteral; import io.gitlab.jfronny.muscript.ast.bool.BoolUnpack; import io.gitlab.jfronny.muscript.ast.dynamic.DynamicAssign; import io.gitlab.jfronny.muscript.ast.dynamic.DynamicCoerce; import io.gitlab.jfronny.muscript.ast.dynamic.DynamicConditional; import io.gitlab.jfronny.muscript.ast.number.NumberAssign; import io.gitlab.jfronny.muscript.ast.number.NumberConditional; import io.gitlab.jfronny.muscript.ast.number.NumberLiteral; import io.gitlab.jfronny.muscript.ast.number.NumberUnpack; import io.gitlab.jfronny.muscript.ast.string.*; public class ExprUtils { public static DynamicExpr asDynamic(Expr expression) { expression = unpack(expression); return expression instanceof DynamicExpr dynamic ? dynamic : new DynamicCoerce(expression); } public static BoolExpr asBool(Expr expression) { return switch (unpack(expression)) { case BoolExpr bool -> bool; case DynamicConditional(var location, var condition, var ifTrue, var ifFalse) -> new BoolConditional(location, condition, asBool(ifTrue), asBool(ifFalse)); case DynamicAssign(var location, var left, var right) -> new BoolAssign(location, left, asBool(right)); case DynamicExpr dynamic -> new BoolUnpack(dynamic); case NullLiteral nl -> throw new TypeMismatchException("Expected boolean expression but got null"); case StringExpr string -> throw new TypeMismatchException("Expected boolean expression but got string"); case NumberExpr number -> throw new TypeMismatchException("Expected boolean expression but got number"); }; } public static NumberExpr asNumber(Expr expression) { return switch (unpack(expression)) { case NumberExpr number -> number; case DynamicConditional(var location, var condition, var ifTrue, var ifFalse) -> new NumberConditional(location, condition, asNumber(ifTrue), asNumber(ifFalse)); case DynamicAssign(var location, var left, var right) -> new NumberAssign(location, left, asNumber(right)); case DynamicExpr dynamic -> new NumberUnpack(dynamic); case NullLiteral nl -> throw new TypeMismatchException("Expected number expression but got null"); case StringExpr string -> throw new TypeMismatchException("Expected number expression but got string"); case BoolExpr bool -> throw new TypeMismatchException("Expected number expression but got boolean"); }; } public static StringExpr asString(Expr expression) { return switch (unpack(expression)) { case StringExpr string -> string; case NumberLiteral number -> new StringLiteral(expression.location(), StringFormatter.toString(number.value())); case BoolLiteral bool -> new StringLiteral(expression.location(), bool.value() ? "true" : "false"); case NullLiteral nl -> new StringLiteral(expression.location(), "null"); case DynamicConditional(var location, var condition, var ifTrue, var ifFalse) -> new StringConditional(location, condition, asString(ifTrue), asString(ifFalse)); case BoolConditional(var location, var condition, var ifTrue, var ifFalse) -> new StringConditional(location, condition, asString(ifTrue), asString(ifFalse)); case NumberConditional(var location, var condition, var ifTrue, var ifFalse) -> new StringConditional(location, condition, asString(ifTrue), asString(ifFalse)); case DynamicAssign(var location, var left, var right) -> new StringAssign(location, left, asString(right)); case DynamicExpr dynamic -> new StringUnpack(dynamic); default -> new StringCoerce(expression); }; } public static Expr unpack(Expr expression) { return switch (expression) { case BoolUnpack(var inner) -> inner; case NumberUnpack(var inner) -> inner; case StringUnpack(var inner) -> inner; case DynamicCoerce(var inner) -> inner; case StringCoerce(var inner) -> inner; default -> expression; }; } }