I am writing a nim to GLSL macro. In the following code c is global:
import vmath
var c: float32
proc svgMain*(gl_FragCoord: Vec4, fragColor: var Vec4) =
fragColor = vec4(c, 1, 1, 1)
When I walk svgMain tree I get a bunch of symbol nodes like fragColor, vec4, and c. Is there a way to know that c is not in current scope but fragColor is? I want to know which of the symbols are globals so that I can get their implementation and put them in GLSL before my code.
import macros
# ...
node.owner().symKind == nskModule # global
# or
node.owner() == yourProcNode
I remember trying to come up with a scheme to distinguish locals, constants and global variables so that I could have macro to capture the local variables (and not globals) in a scope to build my own custom closures for multithreading.
Ultimately I made it so that all local variables must be explicitly passed, because i couldn't find a way to do otherwise a year ago. There is the .owner from https://github.com/nim-lang/Nim/pull/8253 but I couldn't understand all the return values conditions. I also tried to find trickeries with declaredInScope.
Ultimately my macro creates {.nimcall, gcsafe.} which refuses to compile if there are any capture of non parameter variables.
proc transpose(M, N: int, bufIn, bufOut: ptr UncheckedArray[float32]) =
## Transpose a MxN matrix into a NxM matrix with nested for loops
parallelFor j in 0 ..< N:
captures: {M, N, bufIn, bufOut}
parallelFor i in 0 ..< M:
captures: {j, M, N, bufIn, bufOut}
bufOut[j*M+i] = bufIn[i*N+j]
So as a trick you could have your macro copy the body in a nimcall+gcsafe proc with arguments the arguments declared for your DSL. If you don't use generics, you don't need to call that proc for the semcheck to detect illegal captures. If it doesn't compile you know that at least something in the proc body is a global (and wasn't declared as one of the generated proc parameter).
Anyway, just to say that I feel your pain.
The n.owner().symKind == nskModule worked for me. It seems like exactly what I wanted.
Thank you @guibar.
Thank you everyone for trying to help, I will look into declaredInScope and liftlocals!