No problem – glad we got to the bottom of it! On Wed, Mar 11, 2015 at 4:39 PM, Kaj Wiik <[email protected]> wrote:
> That was it! > > This is a great community, many thanks for your time all! > > Cheers. > Kaj > > > On Wednesday, March 11, 2015 at 8:56:26 PM UTC+2, Stefan Karpinski wrote: >> >> 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 >>>>> >>>>> >>
