I noticed a difference of behavior for this example code. Could someone explain it to me, please ?
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.

2014-03-08 18:14:59

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.

2014-03-08 20:12:56
To get the desired behavior here, you should use static params:
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).

2014-03-09 07:47:35

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' "

2014-03-09 09:59:20
Yes, the code is correct. I pushed a couple of fixes to devel and it should work now. 2014-03-09 15:08:32

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 ?

2014-03-09 15:23:28
Ah, I missed your edit. Can you post an example with the problem? 2014-03-11 18:42:39

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).
2014-03-11 19:25:26