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>