On 2013-02-18, at 10:41 AM, Alex Young alex@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