The way to do this is by wrapping an @eval around the macro invocation and
splicing $n:

@eval @gentype $n UInt8


This might be necessary, e.g. if you're looping over various values of n:

for n = 1:10
    @eval @gentype $n UInt8
end




On Wed, Mar 11, 2015 at 2:52 PM, Kaj Wiik <[email protected]> wrote:

>
> Of course this was a simplified example to show the problem. A bad one, I
> admit.
>
> My question relates to the problem you (Simon) provided one answer
> already. I certainly have read Metaprogramming chapter and tried everything
> I could think of without luck. However, it could well be that I am just too
> thick...
>
> Returning to the real problem:
>
> julia> macro gentype(N, typename)
>            fields = [:($(symbol("I_$i"))::T) for i=1:N]
>            quote
>                immutable $(typename){T}
>                    $(fields...)
>                end
>            end
>        end
>
> julia> n = 3
> julia> @gentype n Uint8
> ERROR: `colon` has no method matching colon(::Int64, ::Symbol)
>
> julia> macroexpand(:(@gentype n Uint8))
> :($(Expr(:error, MethodError(colon,(1,:n)))))
>
>
> So, the problem seems to be that variable argument is treated as a symbol
> and is not interpolated in parse time, that lead me to try eval(), which is
> a no-no.
>
> If I replace N -> $N, i get "ERROR: error compiling anonymous: syntax:
> prefix $ in non-quoted expression"
>
> Any suggestions are appreciated, there must be a way....
>
> Thanks,
> Kaj
>
> On Wednesday, March 11, 2015 at 3:40:38 PM UTC+2, Simon Danisch wrote:
>>
>> This is most likely not the right place to use eval!
>> You need to define your problem better. What you describe here doesn't
>> need a macro whatsoever.
>> Macros are for manipulating the syntax tree, which is why the arguments
>> are not the values, but expressions.
>> What a macro is intended to do is more something like this:
>>
>> macro testmacro(N)
>> quote
>>     for i = 1:$N
>>         println("Hello!")
>>     end
>> end
>> end
>> n = 10
>>
>> @testmacro n
>>
>> So all the code inside a macro should be used to transform an expression,
>> which than replaces the original expression that you gave the macro via its
>> arguments
>>
>> Am Mittwoch, 11. März 2015 13:37:55 UTC+1 schrieb Kaj Wiik:
>>>
>>> I have a problem in using variables as argument for macros. Consider a
>>> simple macro:
>>>
>>> macro testmacro(N)
>>>     for i = 1:N
>>>         println("Hello!")
>>>     end
>>> end
>>>
>>> @testmacro 2
>>>
>>> Hello!
>>> Hello!
>>>
>>>
>>> So, all is good. But if I use a variable as an argument,
>>>
>>> n = 2
>>> @testmacro n
>>>
>>>
>>> I get an (understandable) error message "ERROR: `colon` has no method
>>> matching colon(::Int64, ::Symbol)".
>>>
>>> Is this the correct place to use eval() in macros, like
>>>
>>> macro testmacro(N)
>>>     for i = 1:eval(N)
>>>         println("Hello!")
>>>     end
>>> end
>>>
>>> This seems to work as expected. I tried multitude of combinations of
>>> dollar signs, esc, quotes and brackets, none of them worked :-), got
>>> "ERROR: error compiling anonymous: syntax: prefix $ in non-quoted
>>> expression"...
>>>
>>> Are there better ways to do this, is it OK to use eval() in this context?
>>>
>>> Thanks,
>>> Kaj
>>>
>>>

Reply via email to