From c60ec8cfa7cb3a6e1d6f668c843ecf2909e92a31 Mon Sep 17 00:00:00 2001 From: Googler Date: Mon, 23 Mar 2015 14:20:18 +0000 Subject: [PATCH] Skylark: zip function is implemented. -- MOS_MIGRATED_REVID=89296560 --- .../build/lib/packages/MethodLibrary.java | 42 +++++++++++++++++++ .../build/lib/syntax/SkylarkList.java | 2 +- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/google/devtools/build/lib/packages/MethodLibrary.java b/src/main/java/com/google/devtools/build/lib/packages/MethodLibrary.java index 5dd163d266bf39..8dd77e16d84150 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/MethodLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/packages/MethodLibrary.java @@ -47,8 +47,10 @@ import com.google.devtools.build.lib.syntax.SkylarkType; import com.google.devtools.build.lib.syntax.SkylarkType.SkylarkFunctionType; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -950,6 +952,45 @@ public String apply(Object input) { } }; + @SkylarkBuiltin(name = "zip", + doc = "Returns a list of tuples, where the i-th tuple contains " + + "the i-th element from each of the argument sequences or iterables. The list has the " + + "size of the shortest input. With a single iterable argument, it returns a list of " + + "1-tuples. With no arguments, it returns an empty list. Examples:" + + "
"
+          + "zip()  # == []\n"
+          + "zip([1, 2])  # == [(1,), (2,)]\n"
+          + "zip([1, 2], [3, 4])  # == [(1, 3), (2, 4)]\n"
+          + "zip([1, 2], [3, 4, 5])  # == [(1, 3), (2, 4)]
", + returnType = SkylarkList.class) + private static final Function zip = new AbstractFunction("zip") { + @Override + public Object call(List args, Map kwargs, FuncallExpression ast, + Environment env) throws EvalException, InterruptedException { + Iterator[] iterators = new Iterator[args.size()]; + for (int i = 0; i < args.size(); i++) { + iterators[i] = EvalUtils.toIterable(args.get(i), ast.getLocation()).iterator(); + } + List result = new ArrayList(); + boolean allHasNext; + do { + allHasNext = !args.isEmpty(); + List elem = Lists.newArrayListWithExpectedSize(args.size()); + for (Iterator iterator : iterators) { + if (iterator.hasNext()) { + elem.add(iterator.next()); + } else { + allHasNext = false; + } + } + if (allHasNext) { + result.add(SkylarkList.tuple(elem)); + } + } while (allHasNext); + return SkylarkList.list(result, ast.getLocation()); + } + }; + /** * Skylark String module. */ @@ -1052,6 +1093,7 @@ public static final class DictModule {} .put(type, SkylarkType.of(String.class)) .put(fail, SkylarkType.NONE) .put(print, SkylarkType.NONE) + .put(zip, SkylarkType.LIST) .build(); /** diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java index 983ebb484f4de3..5562fbf851ecc2 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java @@ -129,7 +129,7 @@ public List toList() { @Override public String toString() { - return "[]"; + return isTuple() ? "()" : "[]"; } }