"for-loop macros" are no longer an experimental feature (#15288)
This commit is contained in:
parent
a81610230d
commit
c49b88163c
6 changed files with 50 additions and 51 deletions
|
|
@ -1030,52 +1030,6 @@ but only the statement's selector expression is used to determine which
|
|||
macro to call.
|
||||
|
||||
|
||||
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
|
||||
{.experimental: "forLoopMacros".}
|
||||
|
||||
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
|
||||
|
||||
|
||||
Currently for loop macros must be enabled explicitly
|
||||
via ``{.experimental: "forLoopMacros".}``.
|
||||
|
||||
|
||||
Term rewriting macros
|
||||
=====================
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue