I was finally able to write a macro that generates a composite type, in 
fact it was far simpler than I thought (unless there are pitfalls that I 
haven't noticed)...

I am writing an interface to a library that has C structs containing char 
arrays (they are NOT pointers): 

typedef struct
   {
    char starname[SIZE_OF_OBJ_NAME];
    char catalog[SIZE_OF_CAT_NAME];
    long int starnumber;
...

I first tried to define bitstypes of correct size and then fill them with 
Uint8 chars. However the bitstype variables were OK before new() in the 
inner constructor but in the resulting composite, contents were mangled 
(the size was correct, inspected using dump()).

What worked was defining a 'fake' array consisting of correct number of 
fields (in fact suggested by Clang.jl interface generator):

immutable Array_51_Uint8
    d1::Uint8
    d2::Uint8
    d3::Uint8
...

Writing by hand that kind of composites is error prone and tedious, so I 
decided to learn some macro programming. In fact it was quite easy after 
really understanding what is happening :-) :

macro fakearray(name, prefix, _type, size)
    composite = "immutable $name;";
    for i = 1:size
        composite = composite*"$prefix$i::$_type;"
    end
    composite = composite*"end"
    esc(parse(composite))
end

This is probably very naïve and brute force approach: first form a string 
containing the code and then parse() it, but it seems to work.

I wrote a gist giving a full example:
https://gist.github.com/KajWiik/1885ab2f2ec1a6db9063

hexDump C code from http://tinyurl.com/qe5g7b7 was very useful in debugging 
the structs.

Any suggestions how to accomplish this in other (and better) ways are 
welcome!

Kaj



On Saturday, March 7, 2015 at 3:53:25 AM UTC+2, Isaiah wrote:
>
> You are right, I had defined it earlier and apparently the redefinition 
> restriction does not apply to empty immutables. Anyway, this should work:
>
> macro deftype(name)
>   esc(:(immutable $name end))
> end
>
>
>
> On Fri, Mar 6, 2015 at 8:19 PM, Kaj Wiik <[email protected] <javascript:>> 
> wrote:
>
>> Thanks for the reply!
>>
>> Hmm, well my intention was to build the definition piecewise inserting 
>> the fields after this line without end, now I see that it will not work. 
>> Perhaps I should make a template and push! fields to ex.args[3].args?
>>
>> In fact your suggestion does not work in my Julia:
>> julia> macro deftype(name)
>>         ex1 = :(immutable $name end)
>>        end
>>
>> julia> @deftype foo
>>
>> julia> foo()
>> ERROR: foo not defined
>>
>>
>>
>> The reason is:
>> julia> macroexpand(:(@deftype foo))
>> :(immutable #133#foo
>>     end)
>>
>>
>> I.e. the type name is modified... How to escape it?
>>
>> Thanks,
>> Kaj
>>
>> julia> versioninfo()
>> Julia Version 0.3.6
>> Commit a05f87b* (2015-01-08 22:33 UTC)
>> Platform Info:
>>   System: Linux (x86_64-linux-gnu)
>>   CPU: AMD A6-4455M APU with Radeon(tm) HD Graphics
>>   WORD_SIZE: 64
>>   BLAS: libopenblas (NO_LAPACK NO_LAPACKE DYNAMIC_ARCH NO_AFFINITY)
>>   LAPACK: liblapack.so.3
>>   LIBM: libopenlibm
>>   LLVM: libLLVM-3.3
>>
>>
>> On Friday, March 6, 2015 at 5:35:23 PM UTC+2, Isaiah wrote:
>>>
>>> Missing an `end` in both expressions.
>>>
>>>>
>>> julia> macro deftype(name)
>>>
>>>>            ex1 = :(immutable $name end)
>>>          end
>>> julia> @deftype foo
>>> julia> foo()
>>>
>>> On Thu, Mar 5, 2015 at 5:02 AM, Kaj Wiik <[email protected]> wrote:
>>>
>>>> I have been trying to write a macro that would generate fields in a 
>>>> for-loop.
>>>>
>>>> However, when I try to generate the first line I get an error:
>>>>
>>>> julia> macro deftype(name,artype,num)
>>>>        ex1 = :(esc( immutable $name))
>>>> ERROR: syntax: unexpected ")"
>>>>
>>>> julia> macro deftype(name,artype,num)
>>>>        ex1 = :(esc(quote immutable $name end))
>>>> ERROR: syntax: extra token ")" after end of expression
>>>>
>>>>
>>>> There must be a way to do this, I cannot find how...
>>>>
>>>> Thanks,
>>>> Kaj
>>>>
>>>>
>>>
>

Reply via email to