Trying macro with a typed argument: 
    
    
    import macros
    macro m(n:typed):stmt =
      echo n.treerepr
      proc p(n:NimNode) =
        for i in 0..<n.len: n[i].p
        if n.kind in CallNodes:
          for i in 1..<n.len:
            if n[i].kind in AtomicNodes:
              n[i] = newCall(bindsym"float",n[i])
      n.p
      result = n
      echo result.treerepr
    var a = 1
    proc f(x:int) = echo "f_int ",x
    proc f(x:float) = echo "f_float ",x
    m f a
    

The compiler errors: 
    
    
    t_typedmacro.nim(16, 5) Error: internal error: genMagicExpr: mFloat
    No stack traceback available
    To create a stacktrace, rerun compilation with ./koch temp c <file>
    

I guess f is still the wrong symbol, so I tried the following, 
    
    
    import macros
    macro m(n:typed):stmt =
      echo n.treerepr
      proc p(n:NimNode) =
        for i in 0..<n.len: n[i].p
        if n.kind in CallNodes:
          n[0] = ident($n[0])
          for i in 1..<n.len:
            if n[i].kind in AtomicNodes:
              n[i] = newCall(bindsym"float",n[i])
      n.p
      result = n
      echo result.treerepr
    var a = 1
    proc f(x:int) = echo "f_int ",x
    proc f(x:float) = echo "f_float ",x
    m f a
    

Now the compiler segfaults: 
    
    
    SIGSEGV: Illegal storage access. (Attempt to read from nil?)
    

I guess the type is not rechecked? It works if I rebuild the call: 
    
    
    import macros
    proc c(x:int):float = float(x)
    macro m(n:typed):stmt =
      echo n.treerepr
      proc p(n:NimNode) =
        for i in 0..<n.len:
          n[i].p
        if n.kind in CallNodes:
          n[0] = ident($n[0])
          for i in 1..<n.len:
            if n[i].kind in AtomicNodes:
              n[i] = newCall(bindsym"c",n[i])
      n.p
      result = newCall("f")
      for i in 1..<n.len:
        result.add n[i]
      echo result.treerepr
    var a = 1
    proc f(x:int) = echo "f_int ",x
    proc f(x:float) = echo "f_float ",x
    m:
      # Try to change it into f(g(a))
      # Need the type of a to choose the correct g
      f a
    

With a statementlist 
    
    
    import macros
    proc c(x:int):float = float(x)
    macro m(n:typed):stmt =
      echo n.treerepr
      proc p(n:NimNode) =
        for i in 0..<n.len:
          n[i].p
        if n.kind in CallNodes:
          n[0] = ident($n[0])
          for i in 1..<n.len:
            if n[i].kind in AtomicNodes:
              n[i] = newCall(bindsym"c",n[i])
      proc recall(n:NimNode) =
        for i in 0..<n.len:
          n[i].recall
          if n[i].kind in CallNodes:
            var nn = newCall n[i][0]
            for j in 1..<n[i].len:
              nn.add n[i][j]
            n[i] = nn
      n.p
      n.recall
      result = n
      echo result.treerepr
    var a = 1
    proc f(x:int) = echo "f_int ",x
    proc f(x:float) = echo "f_float ",x
    m:
      # Try to change it into f(g(a))
      # Need the type of a to choose the correct g
      f a
      f a
    

it breaks again: 
    
    
    SIGSEGV: Illegal storage access. (Attempt to read from nil?)
    

I actually have to rebuild the statementlist for it to work: 
    
    
    import macros
    proc c(x:int):float = float(x)
    macro m(n:typed):stmt =
      echo n.treerepr
      proc p(n:NimNode) =
        for i in 0..<n.len:
          n[i].p
        if n.kind in CallNodes:
          n[0] = ident($n[0])
          for i in 1..<n.len:
            if n[i].kind in AtomicNodes:
              n[i] = newCall(bindsym"c",n[i])
      proc recall(n:NimNode) =
        for i in 0..<n.len:
          n[i].recall
          if n[i].kind in CallNodes:
            var nn = newCall n[i][0]
            for j in 1..<n[i].len:
              nn.add n[i][j]
            n[i] = nn
      n.p
      n.recall
      result = newstmtlist()
      for i in 0..<n.len: result.add n[i]
      echo result.treerepr
    var a = 1
    proc f(x:int) = echo "f_int ",x
    proc f(x:float) = echo "f_float ",x
    m:
      # Try to change it into f(g(a))
      # Need the type of a to choose the correct g
      f a
      f a
    

This seems to be a very contrived way of doing it. What is the standard 
practice of dealing with macros of typed arguments?

One more question: what does the return type of a macro mean? It doesn't seem 
to change anything, if I change it to typed or untyped.

Reply via email to