summary refs log tree commit diff stats
path: root/lib/pure
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pure')
-rw-r--r--lib/pure/future.nim57
-rw-r--r--lib/pure/math.nim1
2 files changed, 57 insertions, 1 deletions
diff --git a/lib/pure/future.nim b/lib/pure/future.nim
index 7d791e16c..34b76e41d 100644
--- a/lib/pure/future.nim
+++ b/lib/pure/future.nim
@@ -115,3 +115,60 @@ macro `->`*(p, b: expr): expr {.immediate.} =
   ##     f(2, 2)
 
   result = createProcType(p, b)
+
+type ListComprehension = object
+var lc*: ListComprehension
+
+macro `[]`*(lc: ListComprehension, comp, typ: expr): expr =
+  ## List comprehension, returns a sequence. `comp` is the actual list
+  ## comprehension, for example ``x | (x <- 1..10, x mod 2 == 0)``. `typ` is
+  ## the type that will be stored inside the result seq.
+  ##
+  ## .. code-block:: nimrod
+  ##
+  ##   echo lc[x | (x <- 1..10, x mod 2 == 0), int]
+  ##
+  ##   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(comp, 3)
+  expectKind(comp, nnkInfix)
+  expectKind(comp[0], nnkIdent)
+  assert($comp[0].ident == "|")
+
+  result = newCall(
+    newDotExpr(
+      newIdentNode("result"),
+      newIdentNode("add")),
+    comp[1])
+
+  for i in countdown(comp[2].len-1, 0):
+    let x = comp[2][i]
+    expectKind(x, nnkInfix)
+    expectMinLen(x, 1)
+    if x[0].kind == nnkIdent and $x[0].ident == "<-":
+      expectLen(x, 3)
+      result = newNimNode(nnkForStmt).add(x[1], x[2], result)
+    else:
+      result = newIfStmt((x, result))
+
+  result = newNimNode(nnkCall).add(
+    newNimNode(nnkPar).add(
+      newNimNode(nnkLambda).add(
+        newEmptyNode(),
+        newEmptyNode(),
+        newEmptyNode(),
+        newNimNode(nnkFormalParams).add(
+          newNimNode(nnkBracketExpr).add(
+            newIdentNode("seq"),
+            typ)),
+        newEmptyNode(),
+        newEmptyNode(),
+        newStmtList(
+          newAssignment(
+            newIdentNode("result"),
+            newNimNode(nnkPrefix).add(
+              newIdentNode("@"),
+              newNimNode(nnkBracket))),
+          result))))
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index 32bae18c2..1b6572d53 100644
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -14,7 +14,6 @@
 ## <backends.html#the-javascript-target>`_.
 
 include "system/inclrtl"
-
 {.push debugger:off .} # the user does not want to trace a part
                        # of the standard library!