I have a problem with writing a macro. The code looks like this:
import macros
type
Phase = enum
phaseA, phaseB
SubStructure = object
scalar: int
arrarray: array[10, int]
Structure = array[Phase, SubStructure]
macro frankensteins(structName, parameter: untyped): untyped =
result = parseExpr($toStrLit(quote do: `structName`[phase]) & "." & $toStrLit(quote do: `parameter`))
echo result.toStrLit # prints "strooo[phase].scalar" / "strooo[phase].arrarray[5]"
template addValue(
value: var int,
structure: Structure,
parameter: untyped
) =
for phase in Phase:
value += frankensteins(structure, parameter) # here the error occurs that confuses me:
# "Error: undeclared identifier: 'phase'" even though phase is clearly a known identifier here
var
strooo: Structure
i = 0
i.addValue(strooo, scalar) # being able to do something like this
i.addValue(strooo, arrarray[5]) # would reduce a lot of code duplication in my case
My main question is why this fails compiles with the error that I also mentioned in the comments:
Hint: used config file '/playground/nim/config/nim.cfg' [Conf]
Hint: used config file '/playground/nim/config/config.nims' [Conf]
...........................................................
strooo[phase].scalar
/usercode/in.nim(28, 2) template/generic instantiation of `addValue` from here
/usercode/in.nim(21, 31) template/generic instantiation of `frankensteins` from here
/playground/nim/lib/core/macros.nim(533, 8) Error: undeclared identifier: 'phase'
candidates (edit distance, scope distance); see '--spellSuggest':
(1, 3): 'Phase' [type declared in /usercode/in.nim(4, 3)]
(1, 3): 'phaseA' [enumField declared in /usercode/in.nim(5, 5)]
(1, 3): 'phaseB' [enumField declared in /usercode/in.nim(5, 13)]
I know that I could maybe solve the issue by redesigning the data structures. This would however require a lot of refactoring, so I would prefer if this could work.