import macros
type
Ta = seq[tuple[c:int, d:int]]
Tb = tuple[e:seq[int], f:seq[int]]
const
a : Ta = @[(11, 22), (33, 44)]
b : Tb = (@[55,66], @[77, 88])
macro mA(data: Ta): stmt =
echo "AST a \n", treeRepr(data)
macro mB(data: Tb): stmt =
echo "AST b \n", treeRepr(data)
mA(a)
mB(b)
With Nimrod 0.9.2, output is
AST a Sym "a" AST b Par ExprColonExpr Sym "e" Bracket IntLit 55 IntLit 66 ExprColonExpr Sym "f" Bracket IntLit 77 IntLit 88
With HEAD Nimrod ("0.9.3 (2014-03-08)"), output is
AST a Ident !"a" AST b Ident !"b"
The later seems more coherent. Is that the correct behavior ?
What is the best way do something similar to gradha's example on StackOverflow with v0.9.3 for Ta and Tb ?
I'm sorry if this is be obvious or documented but I haven't found it.
Whether a constant is expanded or not when passed to a macro is currently an implementation detail. IMO it should not be expanded and instead you can get the definition via the planned getImpl builtin, but this is rather hard to implement/ensure, so maybe we will always pass the constant's "body" instead.
That Ident !"a" is now passed to the macro is a serious bug, it has to be a symbol.
import macros
type
Ta = seq[tuple[c:int, d:int]]
Tb = tuple[e:seq[int], f:seq[int]]
const
a : Ta = @[(11, 22), (33, 44)]
b : Tb = (@[55,66], @[77, 88])
macro mA(data: static[Ta]): stmt =
echo "AST a \n", repr(data)
macro mB(data: static[Tb]): stmt =
echo "AST b \n", repr(data)
The output is:
AST a
[(11, 22), (33, 44)]
AST b
(e: [55, 66], f: [77, 88])
The code above works with the latest compiler in the devel branch. Please note that inside the macro, the input parameter is no longer typed as PNimrodNode, but rather as the actual data type (Ta and Tb respectively).
Thank you for your answers.
Please, note that inside the macro the input parameter is no longer typed as PNimrodNode, but rather as the actual data type (Ta and Tb respectively).
Does this mean the following code should work ?
macro mB(data: static[Tb]): stmt =
echo "AST b \n", repr(data)
echo data.e[0]
It gives me "test.nim(16, 13) Error: undeclared identifier: 'e' "
Just tested. It works. Thanks for the quick fix!
EDIT: It works well for a seq[int] with on value but not for a plain integer (prints a very big value). Are they handled differently ?
Ah, I missed your edit.
No problem, here is the example
import macros
type
Ta = seq[tuple[c:int, d:int]]
Tb = tuple[e:seq[int], f:seq[int]]
Tg = int
Th = seq[int]
const
a : Ta = @[(11, 22), (33, 44)]
b : Tb = (@[55,66], @[77, 88])
g : Tg = 9
h : Th = @[99]
macro mA(data: static[Ta]): stmt =
echo "AST a \n", repr(data)
echo data[0].d
macro mB(data: static[Tb]): stmt =
echo "AST b \n", repr(data)
echo data.e[0]
echo (data.e[0]+1)
macro mG(data: static[Tg]): stmt =
echo "g = ",data
echo "g+1 = ",(data+1)
macro mH(data: static[Th]): stmt =
echo "h[0] = ", data[0]
echo "h[0] +1 = ",(data[0]+1)
mA(a)
mB(b)
mG(g)
mH(h)
It outputs (with very last version of the compiler):
AST a [(11, 22), (33, 44)] 22 AST b (e: [55, 66], f: [77, 88]) 55 56 g = 140507184624984 g+1 = 140507184624985 h[0] = 99 h[0] +1 = 100 The seq[int] works logically (as a special case of Ta) but not the scalar int (Tg).