You've summarized it very nicely, I think. I did a lot of messing about
with eval() and macroexpand(), but could not find a way to have julia
"correctly" fuse the two tuples U and P without resorting to the parse(). I
cannot get the U and P parts keep the (:tuple, (:curly ...), ...)
structure, which ccall seems to need in this context and at the same time
have the tuples concatenated. Any other way I tried, it was either
completely messed up, or either P or U were prematurely turned into
(Ptr{...}) in the AST.Nevermind that the macro errors are useless, with no real indication of where the error is happening, except for the source call site. On 24 November 2015 at 23:09, Jameson <[email protected]> wrote: > There's a bit of a mix in what you are doing, which is where it is getting > confusing. In general, you want to make sure all of the evaluation work is > happening at runtime and you only work with quoted expressions during macro > evaluation. This takes a bit of practice to get used to, since you have to > keep track of when you are intending each expression to be evaluated (and > in what scope). (ccall argument type expansion is a little bit too strict > about this -- most other places will accept a value spliced into the AST). > In the issue linked below, you had P as a tuple, but have U as an > expression. > > In this case, I think you want to check that `U.head === :tuple`, then > call `prepend!(U.args, [Ptr{Void},Ptr{Void}]); ccallTypes = U` > > > > On Tuesday, November 24, 2015 at 3:39:42 PM UTC-5, Dömötör Gulyás wrote: >> >> in case anyone is left wondering... I've found a hackish way to brute >> force this, essentially summarized in >> https://github.com/one-more-minute/ObjectiveC.jl/issues/8 >> >> Maybe a macro guru can find a still better way, one that doesn't require >> re-parsing stringified variables :) >> >> On 24 November 2015 at 01:34, Dömötör Gulyás <[email protected]> wrote: >> >>> So apparently, this: https://github.com/JuliaLang/julia/issues/14110 is >>> not a bug. Which leaves me with the question, how to accomplish >>> concatenating the argument types tuple for ccall()? There doesn't seem to >>> be a way to accomplish the concatenation (without also evaluating the type >>> parameters) in ways that result in a valid argument type list for ccall(). >>> The idea is to not have to eval() at runtime for every ccall(), as >>> ObjectiveC.jl currently does. >>> >>> A simplified core part of the above: >>> >>> julia> U = (Ptr{UInt8},) >>> >>> (Ptr{UInt8},) >>> >>> >>> julia> :((Ptr{Void},Ptr{Void})..., $U...) >>> >>> :(((Ptr{Void},Ptr{Void})...,(Ptr{UInt8},)...)) >>> >>> >>> julia> Meta.show_sexpr(:((Ptr{Void},Ptr{Void})..., $U...)) >>> >>> (:tuple, (:..., (:tuple, (:curly, :Ptr, :Void), (:curly, :Ptr, :Void))), >>> (:..., (Ptr{UInt8},))) >>> >>> >>> The suggestion is not evaluate the macro, which still leaves the >>> unexpanded (Ptr{UInt8},) in there, and ccall() complains about the >>> types. With some mucking about of objc_msgSendTupleConcat sometimes that >>> shows up as (:curly, :Ptr, :UInt8) but only in ways that fail at the >>> ccall or julia trying to evaluate the tuple concatenation. >>> >>> Is there another way of doing this? I wasn't able to get the intended >>> behavior with a templated function, either, but it feels like it should be >>> possible. >>> >> >>
