/* * 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 * * (C) Copyright IBM Corporation 2006-2010. */ package x10.ast; import java.util.Collections; import java.util.List; import polyglot.ast.Expr; import polyglot.ast.Formal; import polyglot.ast.Loop; import polyglot.ast.Node; import polyglot.ast.Stmt; import polyglot.types.Name; import polyglot.types.SemanticException; import polyglot.types.ContainerType; import polyglot.types.Type; import polyglot.util.CodeWriter; import polyglot.util.Position; import polyglot.visit.CFGBuilder; import polyglot.visit.ContextVisitor; import polyglot.visit.FlowGraph; import polyglot.visit.PrettyPrinter; import polyglot.visit.TypeChecker; import x10.ast.X10Loop.LoopKind; import x10.errors.Errors; import polyglot.types.Context; import x10.types.MethodInstance; import polyglot.types.TypeSystem; import x10.types.checker.Checker; import x10.types.checker.PlaceChecker; /** * An immutable representation of an X10 for loop: for (i : D) S * * @author vj Dec 9, 2004 */ public class ForLoop_c extends X10Loop_c implements ForLoop { /** * @param pos */ public ForLoop_c(Position pos) { super(pos); loopKind=LoopKind.FOR; } /** * @param pos * @param formal * @param domain * @param body */ public ForLoop_c(Position pos, Formal formal, Expr domain, Stmt body) { super(pos, formal, domain, body); loopKind=LoopKind.FOR; } /* (non-Javadoc) * @see polyglot.ast.Term#acceptCFG(polyglot.visit.CFGBuilder, java.util.List) */ public <S> List<S> acceptCFG(CFGBuilder v, List<S> succs) { v.visitCFG(formal, domain, ENTRY); v.visitCFG(domain, FlowGraph.EDGE_KEY_TRUE, body, ENTRY, FlowGraph.EDGE_KEY_FALSE, this, EXIT); v.push(this).visitCFG(body, continueTarget(), ENTRY); return succs; } private static final Name ITERATOR = Name.make("iterator"); public Node typeCheck(ContextVisitor tc) { X10Loop result = (X10Loop) super.typeCheck(tc); TypeSystem xts = (TypeSystem) tc.typeSystem(); // TODO: generate a cast if STATIC_CHECKS is off MethodInstance mi = null; Expr domain = result.domain(); mi = Checker.findAppropriateMethod(tc, domain.type(), ITERATOR, Collections.<Type>emptyList(), Collections.<Type>emptyList()); assert (mi != null); domain = (Expr) PlaceChecker.makeReceiverLocalIfNecessary(tc, domain, mi.flags()); if (domain != null) { if (domain != result.domain()) result = result.domain(domain); } else if (!xts.isUnknown(result.domain().type())) { Errors.issue(tc.job(), new Errors.DomainIteratedForLoopMustBeLocal(result.domain().position())); } return result; } public boolean condIsConstant() { return false; } public boolean condIsConstantTrue() { return false; } public String toString() { return "for (" + formal + " in " + domain + ")" + body; } public void prettyPrint(CodeWriter w, PrettyPrinter tr) { w.write("for("); printBlock(formal, w, tr); if (formal instanceof X10Formal) { X10Formal f = (X10Formal) formal; w.write("["); for (int i=0 ; i<f.vars().size() ; ++i) { if (i>0) w.write(","); printBlock(f.vars().get(i), w, tr); } w.write("]"); } w.write(" in "); printBlock(domain, w, tr); w.write(") "); printSubStmt(body, w, tr); } }