/* * 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.emitter; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import polyglot.visit.Translator; import x10.visit.X10PrettyPrinterVisitor; /** * Expand a given template in a loop with the given set of arguments. * For the loop body, pass in an array of Lists of identical length * (each list representing all instances of a given argument), * which will be translated into array-length repetitions of the * loop body template. * If the template has only one argument, a single list can be used. */ public class Loop extends Expander { private final String id; private final String regex; private final List<?>[] lists; private final int N; public Loop(Emitter er, String id, String regex, List<?> arg) { this(er, id, regex, new List[] { arg }); } public Loop(Emitter er, String id, String regex, List<?> arg1, List<?> arg2) { this(er, id, regex, new List[] { arg1, arg2 }); } public Loop(Emitter er, String id, String regex, List<?> arg1, List<?> arg2, List<?> arg3) { this(er, id, regex, new List[] { arg1, arg2, arg3 }); } public Loop(Emitter er, String id, String regex, List<?> arg1, List<?> arg2, List<?> arg3, List<?> arg4) { this(er, id, regex, new List[] { arg1, arg2, arg3, arg4 }); } public Loop(Emitter er, String id, String regex, List<?>[] components) { super(er); this.id = id; this.regex = regex; assert(regex != null); this.lists = components; // Make sure we have at least one parameter assert(lists.length > 0); int n = -1; int i = 0; for (; i < lists.length && n == -1; i++) n = lists[i].size(); // Make sure the lists are all of the same size or circular for (; i < lists.length; i++) assert(lists[i].size() == n || lists[i].size() == -1); this.N = n; } @Override public void expand(Translator tr) { er.w.write("/* Loop: { */"); // Object[] args = new Object[lists.length]; Map<String,Object> components = new HashMap<String,Object>(); Iterator<?>[] iters = new Iterator[lists.length]; // Parallel iterators over all argument lists for (int j = 0; j < lists.length; j++) iters[j] = lists[j].iterator(); for (int i = 0; i < N; i++) { components.clear(); for (int j = 0; j < lists.length; j++) { Object component = iters[j].next(); // args[j] = component; components.put(String.valueOf(j), component); } // er.dumpRegex(id, args, tr, regex); er.dumpRegex(id, components, tr, regex); } er.w.write("/* } */"); } @Override public String toString() { StringBuffer sb = new StringBuffer("Loop "); for (int i=0; i < lists.length; ++i) { sb.append(er.convertToString(lists[i])); if (i+1 < lists.length) sb.append(" "); } return sb.toString(); } }