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.