[gambit-list] Returning a symbol to scheme from C
Marc Feeley
feeley at iro.umontreal.ca
Tue Feb 19 17:17:09 EST 2013
On 2013-02-18, at 10:41 AM, Alex Young <alex at blackkettle.org> wrote:
> Hi there,
>
> I asked this question over on StackOverflow yesterday, but it's not had
> any joy so far.
>
> I've got a C function behind a c-lambda which needs to do some grubbing
> around with a select(2) call and decide on a scheme symbol to return as
> an indication of what it did, and whether an error condition occurred.
> Basically I want to use that symbol as a signal to drive a transition in
> a state machine.
>
> How one gets hold of a named symbol as a ___SCMOBJ (or anything more
> appropriate) from C isn't explained in the docs, and the wiki seems to
> have fallen over. It's also not immediately obvious from gambit.h
> whether there's a macro for this purpose.
>
> I've tried doing this:
>
> (define (foo) 'bar)
>
> and taking a look at the C it generates, but it looks to me like
> following this pattern only works if you know the offset into the symbol
> table in advance.
>
> Is this possible out of the box? My workaround at the moment is to pass
> in returnable symbols as arguments to the function, but with a larger
> set of symbols I want to be able to return, that's going to get very
> unwieldy very quickly.
>
> Thanks,
> --
> Alex
Others on this list have proposed correct solutions to the problem of using Scheme symbol litterals in C code. However, the solutions have a runtime cost (if string->symbol or the equivalent runtime function in C is called) or they maintain a table of symbols, which is tedious and error prone. This is unfortunate, because the Gambit-C compiler generates for each file compiled a table of the symbols it uses. Accessing this table from C is currently a problem because an index into the table must be used. For example, an access to the symbol "foobar" will get translated to the macro call ___SYM(42,___S_foobar) which is usually expanded to ___sym_tbl[42]. A similar indexing approach is used for keywords, global variables and primitive functions.
In order to simplify accessing symbols, keywords, global variables and primitive functions from C, I have modified the Gambit-C back-end so that it generates macro definitions for these things. For example, it will generate
#define ___SYM_foobar ___SYM(42,___S_foobar)
which means that C code can reference one of the Scheme source file symbols simply by prefixing the name with ___SYM_ . Here is an example :
(define (sign x)
(cond ((< x 0) 'negative)
((> x 0) 'positive)
(else 'zero)))
(define sign-in-c
(c-lambda (int)
scheme-object
"
if (___arg1 < 0) ___result = ___SYM_negative;
else if (___arg1 > 0) ___result = ___SYM_positive;
else ___result = ___SYM_zero;
"))
(define (test x)
(pp (list x (sign x) (sign-in-c x))))
(for-each test '(-5 0 10))
;; output:
;;
;; (-5 negative negative)
;; (0 zero zero)
;; (10 positive positive)
This is now available on the Gambit repo.
Marc
More information about the Gambit-list
mailing list