Great! It works.<div><br></div><div>I've made this little variation to allow different scheme-type and c-type names:</div><div><br></div><div><div>(define-macro</div><div><div> (import-enum-constants scheme-type c-type . names)</div>
<div> (define (interval lo hi)</div><div> (if (< lo hi) (cons lo (interval (+ lo 1) hi)) '()))</div><div> (let ((c-type-str (symbol->string c-type))</div><div> (nb-names (length names))</div><div> (wrapper (gensym)))</div>
<div> `(begin</div><div> (define ,wrapper</div><div> (c-lambda (int)</div><div> ,scheme-type</div><div> ,(string-append</div><div> "static " c-type-str " _tmp_[] = {\n"</div>
<div> (apply string-append</div><div> (map (lambda (i name)</div><div> (let ((name-str (symbol->string name)))</div><div> (string-append</div>
<div> (if (> i 0) "," "")</div><div> name-str)))</div><div> (interval 0 nb-names)</div>
<div> names))</div><div> "};\n"</div><div> "___ASSIGN_NEW_WITH_INIT(___result_voidstar," c-type-str ",_tmp_[___arg1]);\n")))</div>
<div> ,@(map (lambda (i name)</div><div> `(define ,name (,wrapper ,i)))</div><div> (interval 0 nb-names)</div><div> names))))</div></div><div><br></div><div><br></div><div><br>
</div><br><div class="gmail_quote">On Mon, Feb 6, 2012 at 9:30 PM, Marc Feeley <span dir="ltr"><<a href="mailto:feeley@iro.umontreal.ca" target="_blank">feeley@iro.umontreal.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><br>
On 2012-02-06, at 1:04 PM, REPLeffect wrote:<br>
<br>
> 2012/2/6 Marc Feeley <<a href="mailto:feeley@iro.umontreal.ca" target="_blank">feeley@iro.umontreal.ca</a>>:<br>
>><br>
>> On 2012-02-06, at 9:59 AM, Įlvaro Castro-Castilla wrote:<br>
>><br>
>>> Thank you Marc. Those are all better solutions than my wrapper function.<br>
>>><br>
>>> Best regards<br>
>>><br>
>>> Įlvaro<br>
>><br>
>> Actually, using a wrapper function is a good idea to reduce code size. Its intricacies can be hidden in a macro which generates the appropriate Scheme and C code. I've written something like this in the past and even posted an example to the Gambit mailing list (unfortunately my mail system's search function is broken right now so I can't find the message).<br>
>><br>
>> Marc<br>
>><br>
><br>
> Marc,<br>
><br>
> Is this the message you're referring to?<br>
><br>
> <a href="https://mercure.iro.umontreal.ca/pipermail/gambit-list/2011-November/005445.html" target="_blank">https://mercure.iro.umontreal.ca/pipermail/gambit-list/2011-November/005445.html</a><br>
<br>
</div>Yes. Using that macro as an inspiration, I wrote the following import-enum-constants macro which imports a number of enum constants without using a wrapper function:<br>
<div><br>
(c-declare #<<end-of-c-declare<br>
<br>
#include <stdio.h><br>
<br>
</div>typedef enum { A0, B0, C0, D0, E0, F0, G0, H0, I0, J0,<br>
A1, B1, C1, D1, E1, F1, G1, H1, I1, J1,<br>
A2, B2, C2, D2, E2, F2, G2, H2, I2, J2,<br>
A3, B3, C3, D3, E3, F3, G3, H3, I3, J3,<br>
A4, B4, C4, D4, E4, F4, G4, H4, I4, J4,<br>
A5, B5, C5, D5, E5, F5, G5, H5, I5, J5,<br>
A6, B6, C6, D6, E6, F6, G6, H6, I6, J6,<br>
A7, B7, C7, D7, E7, F7, G7, H7, I7, J7,<br>
A8, B8, C8, D8, E8, F8, G8, H8, I8, J8,<br>
A9, B9, C9, D9, E9, F9, G9, H9, I9, J9 } foo;<br>
<div><br>
void f(foo x) { printf("%d\n", x); }<br>
<br>
end-of-c-declare<br>
)<br>
<br>
;;;---------------------------------------------------------------------------<br>
<br>
</div>(define-macro (import-enum-constants type . names)<br>
(let ((type-str (symbol->string type)))<br>
`(begin<br>
,@(map (lambda (name)<br>
(let ((name-str (symbol->string name)))<br>
`(define ,name<br>
((c-lambda ()<br>
,type<br>
,(string-append<br>
"___ASSIGN_NEW_WITH_INIT(___result_voidstar,"<br>
type-str<br>
","<br>
name-str<br>
");"))))))<br>
names))))<br>
<br>
;;;---------------------------------------------------------------------------<br>
<br>
(c-define-type foo "foo")<br>
<br>
(import-enum-constants foo<br>
A0 B0 C0 D0 E0 F0 G0 H0 I0 J0<br>
A1 B1 C1 D1 E1 F1 G1 H1 I1 J1<br>
A2 B2 C2 D2 E2 F2 G2 H2 I2 J2<br>
A3 B3 C3 D3 E3 F3 G3 H3 I3 J3<br>
A4 B4 C4 D4 E4 F4 G4 H4 I4 J4<br>
A5 B5 C5 D5 E5 F5 G5 H5 I5 J5<br>
A6 B6 C6 D6 E6 F6 G6 H6 I6 J6<br>
A7 B7 C7 D7 E7 F7 G7 H7 I7 J7<br>
A8 B8 C8 D8 E8 F8 G8 H8 I8 J8<br>
A9 B9 C9 D9 E9 F9 G9 H9 I9 J9<br>
<div>)<br>
<br>
(define f (c-lambda (foo) void "f"))<br>
<br>
</div>(f A0)<br>
(f F6)<br>
(f J9)<br>
<br>
<br>
When a wrapper function is used, the macro can be implemented like this:<br>
<br>
;;;---------------------------------------------------------------------------<br>
<br>
(define-macro (import-enum-constants type . names)<br>
<br>
(define (interval lo hi)<br>
(if (< lo hi) (cons lo (interval (+ lo 1) hi)) '()))<br>
<br>
(let ((type-str (symbol->string type))<br>
(nb-names (length names))<br>
(wrapper (gensym)))<br>
`(begin<br>
(define ,wrapper<br>
(c-lambda (int)<br>
,type<br>
,(string-append<br>
"static " type-str " _tmp_[] = {\n"<br>
(apply string-append<br>
(map (lambda (i name)<br>
(let ((name-str (symbol->string name)))<br>
(string-append<br>
(if (> i 0) "," "")<br>
name-str)))<br>
(interval 0 nb-names)<br>
names))<br>
"};\n"<br>
"___ASSIGN_NEW_WITH_INIT(___result_voidstar," type-str ",_tmp_[___arg1]);\n")))<br>
,@(map (lambda (i name)<br>
`(define ,name (,wrapper ,i)))<br>
(interval 0 nb-names)<br>
names))))<br>
<br>
;;;---------------------------------------------------------------------------<br>
<br>
The version with the wrapper function is much more compact. On Mac OS X with LLVM gcc the first version compiles to a 80kb file (roughly 700 bytes of machine code per enum constant that is imported), and the version with a wrapper function compiles to a 20kb file (roughly a factor of 5 times more compact).<br>
<span><font color="#888888"><br>
Marc<br>
</font></span><div><div><br>
_______________________________________________<br>
Gambit-list mailing list<br>
<a href="mailto:Gambit-list@iro.umontreal.ca" target="_blank">Gambit-list@iro.umontreal.ca</a><br>
<a href="https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list" target="_blank">https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list</a><br>
</div></div></blockquote></div><br></div>