mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-01 10:52:14 +00:00
Merge pull request #1443 from def-/future-listcomprehensions
Add list comprehensions to future module
This commit is contained in:
@@ -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))))
|
||||
|
||||
Reference in New Issue
Block a user