/* * This file is part of the X10 project (http://x10-lang.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.opensource.org/licenses/eclipse-1.0.php * * This file was originally derived from the Polyglot extensible compiler framework. * * (C) Copyright 2000-2007 Polyglot project group, Cornell University * (C) Copyright IBM Corporation 2007-2012. */ package polyglot.ast; import java.util.List; import polyglot.types.*; import polyglot.util.CodeWriter; import polyglot.util.Position; import polyglot.visit.*; import x10.types.constants.BooleanValue; import x10.types.constants.ConstantValue; /** * A <code>Conditional</code> is a representation of a Java ternary * expression. That is, <code>(cond ? consequent : alternative)</code>. */ public abstract class Conditional_c extends Expr_c implements Conditional { protected Expr cond; protected Expr consequent; protected Expr alternative; public Conditional_c(Position pos, Expr cond, Expr consequent, Expr alternative) { super(pos); assert(cond != null && consequent != null && alternative != null); this.cond = cond; this.consequent = consequent; this.alternative = alternative; } /** Get the precedence of the expression. */ public Precedence precedence() { return Precedence.CONDITIONAL; } /** Get the conditional of the expression. */ public Expr cond() { return this.cond; } /** Set the conditional of the expression. */ public Conditional cond(Expr cond) { Conditional_c n = (Conditional_c) copy(); n.cond = cond; return n; } /** Get the consequent of the expression. */ public Expr consequent() { return this.consequent; } /** Set the consequent of the expression. */ public Conditional consequent(Expr consequent) { Conditional_c n = (Conditional_c) copy(); n.consequent = consequent; return n; } /** Get the alternative of the expression. */ public Expr alternative() { return this.alternative; } /** Set the alternative of the expression. */ public Conditional alternative(Expr alternative) { Conditional_c n = (Conditional_c) copy(); n.alternative = alternative; return n; } /** Reconstruct the expression. */ protected Conditional_c reconstruct(Expr cond, Expr consequent, Expr alternative) { if (cond != this.cond || consequent != this.consequent || alternative != this.alternative) { Conditional_c n = (Conditional_c) copy(); n.cond = cond; n.consequent = consequent; n.alternative = alternative; return n; } return this; } /** Visit the children of the expression. */ public Node visitChildren(NodeVisitor v) { Expr cond = (Expr) visitChild(this.cond, v); Expr consequent = (Expr) visitChild(this.consequent, v); Expr alternative = (Expr) visitChild(this.alternative, v); return reconstruct(cond, consequent, alternative); } /** Type check the expression. */ public abstract Node typeCheck(ContextVisitor tc); public String toString() { return cond + " ? " + consequent + " : " + alternative; } /** Write the expression to an output file. */ public void prettyPrint(CodeWriter w, PrettyPrinter tr) { printSubExpr(cond, false, w, tr); w.unifiedBreak(2); w.write("? "); printSubExpr(consequent, false, w, tr); w.unifiedBreak(2); w.write(": "); printSubExpr(alternative, false, w, tr); } public Term firstChild() { return cond; } public <S> List<S> acceptCFG(CFGBuilder v, List<S> succs) { v.visitCFG(cond, FlowGraph.EDGE_KEY_TRUE, consequent, ENTRY, FlowGraph.EDGE_KEY_FALSE, alternative, ENTRY); v.visitCFG(consequent, this, EXIT); v.visitCFG(alternative, this, EXIT); return succs; } public boolean isConstant() { return cond.isConstant() && consequent.isConstant() && alternative.isConstant(); } public ConstantValue constantValue() { ConstantValue cond_ = cond.constantValue(); ConstantValue then_ = consequent.constantValue(); ConstantValue else_ = alternative.constantValue(); if (cond_ instanceof BooleanValue && then_ != null && else_ != null) { boolean c = ((BooleanValue)cond_).value(); if (c) { return then_; } else { return else_; } } return null; } }