package me.august.lumen.compile.parser.ast.expr;
import me.august.lumen.compile.codegen.Branch;
import me.august.lumen.compile.codegen.BuildContext;
import me.august.lumen.compile.codegen.Conditional;
import me.august.lumen.compile.codegen.MethodCodeGen;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
public class TernaryExpr implements Expression, Conditional {
private Expression condition;
private Expression trueExpr;
private Expression falseExpr;
public TernaryExpr(Expression condition, Expression trueExpr, Expression falseExpr) {
this.condition = condition;
this.trueExpr = trueExpr;
this.falseExpr = falseExpr;
}
public Expression getCondition() {
return condition;
}
public Expression getTrueExpr() {
return trueExpr;
}
public Expression getFalseExpr() {
return falseExpr;
}
@Override
public Type expressionType() {
return trueExpr.expressionType();
}
@Override
public Branch branch(MethodCodeGen ifBranch, MethodCodeGen elseBranch) {
if (condition instanceof Conditional) {
return ((Conditional) condition).branch(ifBranch, elseBranch);
} else if (condition.expressionType().getSort() == Type.BOOLEAN) {
return Branch.branchBoolean(condition, ifBranch, elseBranch);
} else {
throw new IllegalArgumentException("Incompatible types.");
}
}
@Override
public void generate(MethodVisitor visitor, BuildContext context) {
branch(trueExpr, falseExpr).generate(visitor, context);
}
@Override
public Expression[] getChildren() {
return new Expression[]{condition, trueExpr, falseExpr};
}
@Override
public boolean isConstant() {
return condition.isConstant() && trueExpr.isConstant() && falseExpr.isConstant();
}
@Override
public String toString() {
return "TernaryExpr{" +
"condition=" + condition +
", trueExpr=" + trueExpr +
", falseExpr=" + falseExpr +
'}';
}
}