As you might know, I am working on the this opengl macros library here: 
[https://github.com/krux02/opengl-sandbox](https://github.com/krux02/opengl-sandbox)

One of its most important features is, that I can simply use values from the 
current scope, and pass them to shaders as uniforms, and the macro library 
handles the stuff to generate the uniform section in the glsl part, and the 
code that is required to pass the uniform. One piece in the puzzle to get this 
done, is a mapping from nim types to their names in glsl, and some other 
attributes that I just leave out for now. You can see how such a mapping is 
implemented here:

[https://github.com/krux02/opengl-sandbox/blob/master/includes/typeinfo.nim](https://github.com/krux02/opengl-sandbox/blob/master/includes/typeinfo.nim)

I am not sure if that is the best way to do it, but it gets the job done for 
the current use case. To evaluate each attribute at compile time for each 
attribute, I actually use a two layer macro with one outer layer and one inner 
layer. The outer layer is just there to provide a nice looking dsl, it then 
generates an ast that gen be type checked. And this type checked ast is then 
passed to the inner layer macro, where all the actual logic takes place. What I 
am doing at the moment to evaluate these attributs at compile time, is I 
generate calls for each attribute to these templates from the outer macro. The 
inner macro then will not see the call to the template anymore. The template 
will be resolved.

  * [Here is where I generate a call to such a 
template](https://github.com/krux02/opengl-sandbox/blob/master/includes/shadingDsl.nim#L599)
  * [Here I am accessing this 
attribute](https://github.com/krux02/opengl-sandbox/blob/master/includes/shadingDsl.nim#L238)



The big advantage of these templates is, it is extensible. Whenever I realize, 
that a certain type is not supported, I can simply add the templates, and it 
will work. Extensibility is also an important thing, because there are 
definitively use cases where I want to add the support for a type from the 
library user side. It has to do with the 
[attribNormalized](https://github.com/krux02/opengl-sandbox/blob/master/includes/typeinfo.nim#L72)
 flag. I don't want to go into detail here, but the point is, a switch 
statement inside a macro over the symbol would not quite do it.

The limitation I have right now, is that this approach I used so far seems to 
not work well together with struct attributes (objects/tuples). For struct 
attributes I would be required to get these strings on a per member basis. But 
I can't iterate on member in the outer macro, so I can't generate the code to 
the template calls. And in the inner macro, I just have a `NimNode` of kind 
`nnkSym`. I tried to use 
[macros.getAst](https://nim-lang.org/docs/macros.html#getAst,untyped) but 
unfortunately getAst does not have static overload resolution (at the moment).

I can't think of a suitable solution right now. Maybe you have an idea that 
could help me, if you understood my problem. I really hope so. Any feedback is 
welcome right now.

Reply via email to