Created
June 7, 2018 21:46
-
-
Save cipharius/79facf7c8d04219543b296edbf2a819c to your computer and use it in GitHub Desktop.
Macro for unrolling for loop with generic range iterators
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import macros | |
proc replaceIdent(node, ident: NimNode, replacement: NimNode) = | |
for i, child in node: | |
if child == ident: | |
node[i] = replacement.copy() | |
if child.len > 0: | |
child.replaceIdent(ident, replacement) | |
macro unrollLoop(statements: untyped): typed = | |
result = newNimNode(nnkStmtList) | |
let loop = statements[0] | |
loop.expectKind(nnkForStmt) | |
loop.expectLen(3) | |
let | |
loopIndex = loop[0] | |
loopRange = loop[1] | |
loopBody = loop.body | |
loopRange.expectKind(nnkInfix) | |
let | |
a = int(loopRange[1].intVal) | |
b = int(loopRange[2].intVal) | |
echo loopRange[0].kind | |
var unrollRange: Slice[int] | |
if loopRange[0].eqIdent("..<"): | |
unrollRange = a..<b | |
elif loopRange[0].eqIdent(".."): | |
unrollRange = a..b | |
else: | |
error("Unsupported iterator") | |
for i in unrollRange: | |
var newStmt = loopBody.copy() | |
newStmt.replaceIdent(loopIndex, i.newLit()) | |
result.add(newStmt) | |
var someSequence = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] | |
var accumulate = 0 | |
unrollLoop: | |
for i in 0..<10: | |
echo someSequence[i] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment