ffi/unsafe: match i
, o
, or io
as symbols
Changes `_ptr`, `_list`, and `_vector` syntax to be more permissive. Matching by symbol rather than binding is usually the wrong choice, but the position where `i`, `o`, or `io` is recognized in `_ptr` and company is not an expression position. Also, `i`, `o`, and `io` are not otherwise bound. So, it's difficult to justify the current behavior. If `_ptr` and company were defined today, we'd use keywords like `#:i` instead of symbols like `i`. A potential drawback of this change is that a `i`, `o`, or `io` might be written with the intent of referring to a binding, and this change makes such a reference silently allwowed instead of an errror. That seems relatively unlikely, however, while having to avoid `i`, `o`, or `io` as a binding is occassionally a pain --- something I've run into once or maybe twice. Closes #887
This commit is contained in:
parent
6d06086dad
commit
1655b6e2bb
|
@ -1016,7 +1016,7 @@ Examples:
|
|||
|
||||
Creates a C pointer type, where @racket[mode] indicates input or
|
||||
output pointers (or both). The @racket[mode] can be one of the
|
||||
following:
|
||||
following (matched as a symbol independent of binding):
|
||||
|
||||
@itemize[
|
||||
|
||||
|
@ -1058,7 +1058,11 @@ following type:
|
|||
|
||||
creates a function that calls the foreign function with a fresh
|
||||
integer pointer, and use the value that is placed there as a second
|
||||
return value.}
|
||||
return value.
|
||||
|
||||
@history[#:changed "7.7.0.6" @elem{The modes @racket[i], @racket[o],
|
||||
and @racket[io] match as symbols
|
||||
instead of free identifiers.}]}
|
||||
|
||||
|
||||
@defform[(_box type)]{
|
||||
|
@ -1124,7 +1128,10 @@ return two values, the vector and the boolean.
|
|||
-> (values vec res))
|
||||
]
|
||||
|
||||
@history[#:changed "7.7.0.2" @elem{Added @racket[maybe-mode].}]}
|
||||
@history[#:changed "7.7.0.2" @elem{Added @racket[maybe-mode].}]
|
||||
#:changed "7.7.0.6" @elem{The modes @racket[i], @racket[o],
|
||||
and @racket[io] match as symbols
|
||||
instead of free identifiers.}]}
|
||||
|
||||
@defform[(_vector mode type maybe-len maybe-mode)]{
|
||||
|
||||
|
@ -1145,7 +1152,10 @@ Examples:
|
|||
|
||||
See @racket[_list] for more explanation about the examples.
|
||||
|
||||
@history[#:changed "7.7.0.2" @elem{Added @racket[maybe-mode].}]}
|
||||
@history[#:changed "7.7.0.2" @elem{Added @racket[maybe-mode].}
|
||||
#:changed "7.7.0.6" @elem{The modes @racket[i], @racket[o],
|
||||
and @racket[io] match as symbols
|
||||
instead of free identifiers.}]}
|
||||
|
||||
|
||||
@defform*[#:id _bytes
|
||||
|
|
|
@ -1145,6 +1145,22 @@
|
|||
(define-serializable-cstruct _serializable-example-1 ([a _int]))
|
||||
(test 17 serializable-example-1-a (deserialize (serialize (make-serializable-example-1 17))))
|
||||
|
||||
;; ----------------------------------------
|
||||
;; Check that `i`, `o`, and `io` are matched as symbols, not by binding:
|
||||
|
||||
(let ([i 'no]
|
||||
[o 'no]
|
||||
[io 'no])
|
||||
(test #t ctype? (_ptr i _int))
|
||||
(test #t ctype? (_ptr o _int))
|
||||
(test #t ctype? (_ptr io _int))
|
||||
(test #t ctype? (_list i _int))
|
||||
(test #t ctype? (_list o _int 10))
|
||||
(test #t ctype? (_list io _int 10))
|
||||
(test #t ctype? (_vector i _int))
|
||||
(test #t ctype? (_vector o _int 10))
|
||||
(test #t ctype? (_vector io _int 10)))
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
(define-cpointer-type _foo)
|
||||
|
|
|
@ -1054,13 +1054,19 @@
|
|||
(define-fun-syntax _?
|
||||
(syntax-id-rules () [(_ . xs) ((type: #f) . xs)] [_ (type: #f)]))
|
||||
|
||||
(begin-for-syntax
|
||||
(define-syntax-rule (syntax-rules/symbol-literals (lit ...) [pat tmpl] ...)
|
||||
(lambda (stx)
|
||||
(syntax-case* stx (lit ...) (lambda (a b) (eq? (syntax-e a) (syntax-e b)))
|
||||
[pat (syntax-protect (syntax/loc stx tmpl))] ...))))
|
||||
|
||||
;; (_ptr <mode> <type>)
|
||||
;; This is for pointers, where mode indicates input or output pointers (or
|
||||
;; both). If the mode is `o' (output), then the wrapper will not get an
|
||||
;; argument for it, instead it generates the matching argument.
|
||||
(provide _ptr)
|
||||
(define-fun-syntax _ptr
|
||||
(syntax-rules (i o io)
|
||||
(syntax-rules/symbol-literals (i o io)
|
||||
[(_ i t) (type: _pointer
|
||||
pre: (x => (let ([p (malloc t)]) (ptr-set! p t x) p)))]
|
||||
[(_ o t) (type: _pointer
|
||||
|
@ -1090,7 +1096,7 @@
|
|||
;; the C function will most likely require.
|
||||
(provide _list)
|
||||
(define-fun-syntax _list
|
||||
(syntax-rules (i o io)
|
||||
(syntax-rules/symbol-literals (i o io)
|
||||
[(_ i t ) (type: _pointer
|
||||
pre: (x => (list->cblock x t)))]
|
||||
[(_ i t mode) (type: _pointer
|
||||
|
@ -1112,7 +1118,7 @@
|
|||
;; Same as _list, except that it uses Scheme vectors.
|
||||
(provide _vector)
|
||||
(define-fun-syntax _vector
|
||||
(syntax-rules (i o io)
|
||||
(syntax-rules/symbol-literals (i o io)
|
||||
[(_ i t ) (type: _pointer
|
||||
pre: (x => (vector->cblock x t)))]
|
||||
[(_ i t mode) (type: _pointer
|
||||
|
|
Loading…
Reference in New Issue
Block a user