summary refs log tree commit diff stats
path: root/doc/manual.rst
diff options
context:
space:
mode:
authorMiran <narimiran@disroot.org>2020-09-08 14:25:25 +0200
committerGitHub <noreply@github.com>2020-09-08 14:25:25 +0200
commitc49b88163c12d18506ef43e4d26abd5d76f68359 (patch)
tree522590ff24ad68767fb00f69f51a7a062d4cb973 /doc/manual.rst
parenta81610230ddacf33f11e8cc57a379f12a985f8b6 (diff)
downloadNim-c49b88163c12d18506ef43e4d26abd5d76f68359.tar.gz
"for-loop macros" are no longer an experimental feature (#15288)
Diffstat (limited to 'doc/manual.rst')
-rw-r--r--doc/manual.rst42
1 files changed, 42 insertions, 0 deletions
diff --git a/doc/manual.rst b/doc/manual.rst
index b78e11b32..fc4c11f50 100644
--- a/doc/manual.rst
+++ b/doc/manual.rst
@@ -5469,6 +5469,48 @@ powerful programming construct that still suffices. So the "check list" is:
 (4) Else: Use a macro.
 
 
+For loop macros
+---------------
+
+A macro that takes as its only input parameter an expression of the special
+type ``system.ForLoopStmt`` can rewrite the entirety of a ``for`` loop:
+
+.. code-block:: nim
+    :test: "nim c $1"
+
+  import macros
+
+  macro enumerate(x: ForLoopStmt): untyped =
+    expectKind x, nnkForStmt
+    # we strip off the first for loop variable and use
+    # it as an integer counter:
+    result = newStmtList()
+    result.add newVarStmt(x[0], newLit(0))
+    var body = x[^1]
+    if body.kind != nnkStmtList:
+      body = newTree(nnkStmtList, body)
+    body.add newCall(bindSym"inc", x[0])
+    var newFor = newTree(nnkForStmt)
+    for i in 1..x.len-3:
+      newFor.add x[i]
+    # transform enumerate(X) to 'X'
+    newFor.add x[^2][1]
+    newFor.add body
+    result.add newFor
+    # now wrap the whole macro in a block to create a new scope
+    result = quote do:
+      block: `result`
+
+  for a, b in enumerate(items([1, 2, 3])):
+    echo a, " ", b
+
+  # without wrapping the macro in a block, we'd need to choose different
+  # names for `a` and `b` here to avoid redefinition errors
+  for a, b in enumerate([1, 2, 3, 5]):
+    echo a, " ", b
+
+
+
 Special Types
 =============