nim-stew/stew/staticfor.nim

44 lines
1.3 KiB
Nim

# stew
# Copyright (c) 2024 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
# http://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
# http://opensource.org/licenses/MIT)
# at your option. This file may not be copied, modified, or distributed except
# according to those terms.
import std/macros
proc replaceNodes(ast: NimNode, what: NimNode, by: NimNode): NimNode =
# Replace "what" ident node by "by"
proc inspect(node: NimNode): NimNode =
case node.kind:
of {nnkIdent, nnkSym}:
if node.eqIdent(what):
by
else:
node
of nnkEmpty, nnkLiterals:
node
else:
let rTree = newNimNode(node.kind, lineInfoFrom = node)
for child in node:
rTree.add inspect(child)
rTree
inspect(ast)
macro staticFor*(idx: untyped{nkIdent}, slice: static Slice[int], body: untyped): untyped =
## Unrolled `for` loop over the given range:
##
## ```nim
## staticFor(i, 0..<2):
## echo default(array[i, byte])
## ```
result = newNimNode(nnkStmtList, lineInfoFrom = body)
for i in slice:
result.add nnkBlockStmt.newTree(
ident(":staticFor" & $idx & $i),
body.replaceNodes(idx, newLit i)
)