Open
Description
Description
import std/macros
macro evalOnceAs*(exp, alias: untyped): untyped =
expectKind(alias, nnkIdent)
let
body = nnkStmtList.newTree()
val =
if exp.kind == nnkSym:
# The symbol can be used directly
# TODO dot expressions? etc..
exp
else:
let val = genSym(ident = "evalOnce_" & $alias)
body.add newLetStmt(val, exp)
val
body.add(
newProc(
name = genSym(nskTemplate, $alias),
params = [getType(untyped)],
body = val,
procType = nnkTemplateDef,
)
)
body
type ArrayBuf = object
buf: array[32, byte]
n: int
template data*(bParam: ArrayBuf): openArray =
bParam.evalOnceAs(b)
b.buf.toOpenArray(0, b.n - 1)
proc f() =
var b: int
var a: ArrayBuf
echo a.data()
echo b
var b: int
proc f2() =
var a: ArrayBuf
echo a.data()
echo b
the name b is local to the template and not dirty - it should neither conflict with the other b nor leak out of the template
A variation, when b
is in a different scope:
var b: int
proc f() =
var a: ArrayBuf
echo a.data()
echo b
f()
Here, (buf: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], n: 0)
gets printed.
Nim Version
2.0.8
Current Output
testit.nim(26, 20) Error: redefinition of 'b'; previous declaration here: /home/arnetheduck/status/nimbus-eth1/_exper/testit.nim(45, 7)
Expected Output
No response
Known Workarounds
No response
Additional Information
No response