summary refs log tree commit diff stats
path: root/lib/pure
diff options
context:
space:
mode:
authordef <dennis@felsin9.de>2014-08-03 14:11:57 +0200
committerdef <dennis@felsin9.de>2014-08-03 14:11:57 +0200
commit9f99dd0196edda1e5bb6440abb9e7003d26ecfca (patch)
tree37f0788b55b0fff474db430b0418bda33fe1bd8b /lib/pure
parent915d3291ab57d59e41877c98dba97d6388c56a35 (diff)
downloadNim-9f99dd0196edda1e5bb6440abb9e7003d26ecfca.tar.gz
Add list comprehensions to future module
Diffstat (limited to 'lib/pure')
-rw-r--r--lib/pure/future.nim53
1 files changed, 53 insertions, 0 deletions
diff --git a/lib/pure/future.nim b/lib/pure/future.nim
index b7df05207..121877ad1 100644
--- a/lib/pure/future.nim
+++ b/lib/pure/future.nim
@@ -115,3 +115,56 @@ macro `->`*(p, b: expr): expr {.immediate.} =
   ##     f(2, 2)
 
   result = createProcType(p, b)
+
+type ListComprehension = object
+var lc*: ListComprehension
+
+macro `[]`*(lc: ListComprehension, x, t): expr =
+  ## List comprehensions.
+  ##
+  ## .. code-block:: nimrod
+  ##
+  ##   const n = 20
+  ##   echo lc[(x,y,z) | (x <- 1..n, y <- x..n, z <- y..n, x*x + y*y == z*z),
+  ##           tuple[a,b,c: int]]
+
+  expectLen(x, 3)
+  expectKind(x, nnkInfix)
+  expectKind(x[0], nnkIdent)
+  assert($x[0].ident == "|")
+
+  result = newCall(
+    newDotExpr(
+      newIdentNode("result"),
+      newIdentNode("add")),
+    x[1])
+
+  for i in countdown(x[2].len-1, 0):
+    let y = x[2][i]
+    expectKind(y, nnkInfix)
+    expectMinLen(y, 1)
+    if y[0].kind == nnkIdent and $y[0].ident == "<-":
+      expectLen(y, 3)
+      result = newNimNode(nnkForStmt).add(y[1], y[2], result)
+    else:
+      result = newIfStmt((y, result))
+
+  result = newNimNode(nnkCall).add(
+    newNimNode(nnkPar).add(
+      newNimNode(nnkLambda).add(
+        newEmptyNode(),
+        newEmptyNode(),
+        newEmptyNode(),
+        newNimNode(nnkFormalParams).add(
+          newNimNode(nnkBracketExpr).add(
+            newIdentNode("seq"),
+            t)),
+        newEmptyNode(),
+        newEmptyNode(),
+        newStmtList(
+          newAssignment(
+            newIdentNode("result"),
+            newNimNode(nnkPrefix).add(
+              newIdentNode("@"),
+              newNimNode(nnkBracket))),
+          result))))