package io.gitlab.jfronny.muscript.ast.conditional; 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.annotations.CanThrow; import io.gitlab.jfronny.muscript.ast.literal.BoolLiteral; import java.io.IOException; @CanThrow public class UnresolvedConditional extends DynamicExpr { private final BoolExpr condition; 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); 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(); return new UnresolvedConditional(chStart, chEnd, 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(chStart, chEnd, condition, trueExpr.asDynamicExpr(), falseExpr.asDynamicExpr()); } @Override public BoolExpr asBoolExpr() { return new BoolConditional(chStart, chEnd, condition, trueExpr.asBoolExpr(), falseExpr.asBoolExpr()); } @Override public StringExpr asStringExpr() { return new StringConditional(chStart, chEnd, condition, trueExpr.asStringExpr(), falseExpr.asStringExpr()); } @Override public NumberExpr asNumberExpr() { return new NumberConditional(chStart, chEnd, 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); } }