/* * 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.Collections; import java.util.List; import polyglot.frontend.Globals; import polyglot.types.*; import polyglot.util.*; import polyglot.visit.*; import x10.errors.Errors; /** * An <code>Assign</code> represents a Java assignment expression. */ public abstract class Assign_c extends Expr_c implements Assign, Ambiguous { protected Operator op; protected Expr right; protected NodeFactory nf; public Assign_c(NodeFactory nf, Position pos, Operator op, Expr right) { super(pos); assert(op != null && right != null); this.op = op; this.right = right; this.nf = nf; } /** Get the precedence of the expression. */ public Precedence precedence() { return Precedence.ASSIGN; } /** Get the left operand of the expression. */ public abstract Expr left(); /** Get the operator of the expression. */ public Operator operator() { return this.op; } /** Set the operator of the expression. */ public Assign operator(Operator op) { Assign_c n = (Assign_c) copy(); n.op = op; return n; } /** Get the right operand of the expression. */ public Expr right() { return this.right; } /** Set the right operand of the expression. */ public Assign right(Expr right) { if (right == this.right) return this; Assign_c n = (Assign_c) copy(); n.right = right; return n; } public abstract Assign visitLeft(NodeVisitor v); /** Visit the children of the expression. */ public Node visitChildren(NodeVisitor v) { Assign a = visitLeft(v); Expr right = (Expr) visitChild(a.right(), v); return a.right(right); } public abstract Type leftType(); public abstract Assign typeCheckLeft(ContextVisitor tc); /** Type check the expression. */ public abstract Node typeCheck(ContextVisitor tc); /** Get the throwsArithmeticException of the expression. */ public boolean throwsArithmeticException() { // conservatively assume that any division or mod may throw // ArithmeticException this is NOT true-- floats and doubles don't // throw any exceptions ever... return op == DIV_ASSIGN || op == MOD_ASSIGN; } //public String toString() { // return leftString() + " " + op + " " + right; // } /** Write the expression to an output file. */ public void prettyPrint(CodeWriter w, PrettyPrinter tr) { printSubExpr(left(), true, w, tr); w.write(" "); w.write(op.toString()); w.allowBreak(2, 2, " ", 1); // miser mode w.begin(0); printSubExpr(right, false, w, tr); w.end(); } /** Dumps the AST. */ public void dump(CodeWriter w) { super.dump(w); w.allowBreak(4, " "); w.begin(0); w.write("(operator " + op + ")"); w.end(); } abstract public Term firstChild(); public <S> List<S> acceptCFG(CFGBuilder v, List<S> succs) { if (operator() == ASSIGN) { acceptCFGAssign(v); } else { acceptCFGOpAssign(v); } return succs; } /** * ###@@@DOCO TODO */ protected abstract void acceptCFGAssign(CFGBuilder v); /** * ###@@@DOCO TODO */ protected abstract void acceptCFGOpAssign(CFGBuilder v); public List<Type> throwTypes(TypeSystem ts) { if (throwsArithmeticException()) { return Collections.<Type>singletonList(ts.ArithmeticException()); } return Collections.<Type>emptyList(); } }