On Nov 15, 2010, at 3:02 PM, John Clements wrote:
The documentation for '_enum says this:
3.8 Enumerations and Masks
Although the constructors below are describes as procedures, they are
implemented as syntax, so that error messages can report a type name where
the syntactic context implies one.
(_enum symbols [basetype]) → ctype?
symbols : list?
basetype : ctype? = _ufixint
Takes a list of symbols and generates an enumeration type. The enumeration
maps between a symbol in the given symbols list and corresponding integers,
counting from0.
The list symbols can also set the values of symbols by putting '= and an
exact integer after the symbol. For example, the list '(x y = 10 z) maps 'x
to 0, 'y to 10, and 'z to11.
The basetype argument specifies the base type to use.
This says nothing about what happens when using racket-C on a symbol that's
not mentioned by the enumeration, or what happens when using C-racket on a
number that's not mentioned in the enumeration.
Based on my tests, it appears that the conversion signals an error in the
racket-C direction, but simply returns #f in the C-racket direction.
Should I document the current behavior, or would it make more sense to change
it to signal an error rather than returning #f?
Okay the existing behavior was bothering me because (post-conversion to #f)
there's no way to recover the problematic integer. I therefore changed it so
it signals an error instead, like this:
. . . plt/collects/racket/private/more-scheme.rkt:265:2: enum:int-_my-enum:
expected a known integer from C, got: 6
That error comes from linking to a file with this C function:
int tester(int x){
return x+2;
}
... using this racket program:
#lang racket
(require ffi/unsafe)
(define lib (ffi-lib /tmp/tester.dylib))
(define _my-enum
(_enum
'(chicken = 3
monkey = 4
duck = 5)))
(define tester
(get-ffi-obj tester lib (_fun _my-enum - _my-enum)))
(tester 'monkey)
... and finally, here's the diff:
pcp062767pcs:~/plt/collects/ffi clements$ git diff unsafe.rkt
diff --git a/collects/ffi/unsafe.rkt b/collects/ffi/unsafe.rkt
index 66fd34a..99e0d7f 100644
--- a/collects/ffi/unsafe.rkt
+++ b/collects/ffi/unsafe.rkt
@@ -765,6 +765,8 @@
(define int-sym '())
(define s-c
(if name (string-symbol (format enum:~a-int name)) 'enum-int))
+ (define c-s
+(if name (string-symbol (format enum:int-~a name)) 'int-enum))
(let loop ([i 0] [symbols symbols])
(unless (null? symbols)
(let-values ([(i rest)
@@ -784,7 +786,11 @@
(if a
(cdr a)
(raise-type-error s-c (format ~a (or name enum)) x
-(lambda (x) (cond [(assq x int-sym) = cdr] [else #f]
+(lambda (x) (cond [(assq x int-sym) = cdr]
+ [else
+ (error c-s
+ expected a known integer from C, got: ~s
+ x)]
;; Macro wrapper -- no need for a name
(provide _enum)
Let me know if it's okay to commit this. If I don't hear back in a couple of
days, I'll just go ahead :).
John
smime.p7s
Description: S/MIME cryptographic signature
_
For list-related administrative tasks:
http://lists.racket-lang.org/listinfo/dev