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
>>>>
>>>>
>>>
>