* FFI support for disjoint types
@ 2010-11-11 16:24 Ludovic Courtès
2010-11-20 21:59 ` Andy Wingo
2011-01-30 22:30 ` Ludovic Courtès
0 siblings, 2 replies; 4+ messages in thread
From: Ludovic Courtès @ 2010-11-11 16:24 UTC (permalink / raw)
To: guile-devel
Hello!
I’ve used the macro below in a couple of projects. It allows the
creation of disjoint Scheme types for disjoint C pointer types, and
takes care of preserving eq?-ness for equal C pointers.
Example:
--8<---------------cut here---------------start------------->8---
;; Create a wrapped pointer type `class?'.
(define-wrapped-pointer-type class?
wrap-class unwrap-class print-class)
(define lookup-class
(let ((f (libchop-function '* "class_lookup" ('*))))
(lambda (name)
(let ((ptr (f (string->pointer name))))
(if (null-pointer? ptr)
#f
;; Wrap the object pointer so that it appears as an object
;; that matches `class?' at the Scheme level.
(wrap-class ptr))))))
(define (class-name c)
;; C is a `class?' object, so unwrap it to get the underlying
;; pointer.
(let ((ptr (make-pointer (+ (pointer-address (unwrap-class c))
%offset-of-name))))
(pointer->string (dereference-pointer ptr))))
--8<---------------cut here---------------end--------------->8---
Code:
--8<---------------cut here---------------start------------->8---
(define-syntax define-wrapped-pointer-type
(lambda (stx)
(syntax-case stx ()
((_ pred wrap unwrap print) ;; hygiene
(with-syntax ((type-name (datum->syntax #'pred (gensym)))
(%wrap (datum->syntax #'wrap (gensym))))
#'(begin
(define-record-type type-name
(%wrap pointer)
pred
(pointer unwrap))
(define wrap
;; Use a weak hash table to preserve pointer identity, i.e.,
;; PTR1 == PTR2 <-> (eq? (wrap PTR1) (wrap PTR2)).
(let ((ptr->obj (make-weak-value-hash-table)))
(lambda (ptr)
(or (hash-ref ptr->obj ptr)
(let ((o (%wrap ptr)))
(hash-set! ptr->obj ptr o)
o)))))
(set-record-type-printer! type-name print))))
((_ type-name print) ;; lazyness
(let* ((type-name* (syntax->datum #'type-name))
(pred-name (datum->syntax #'type-name
(symbol-append type-name* '?)))
(wrap-name (datum->syntax #'type-name
(symbol-append 'wrap- type-name*)))
(%wrap-name (datum->syntax #'type-name
(symbol-append '%wrap- type-name*)))
(unwrap-name (datum->syntax #'type-name
(symbol-append 'unwrap-
type-name*))))
(with-syntax ((pred pred-name)
(wrap wrap-name)
(%wrap %wrap-name)
(unwrap unwrap-name))
#'(define-wrapped-pointer-type pred wrap unwrap print)))))))
--8<---------------cut here---------------end--------------->8---
The second pattern in the macro is convenient but unhygienic, so I’m
inclined to remove it.
Thoughts?
What about adding it to (system foreign), along with documentation?
Thanks,
Ludo’.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: FFI support for disjoint types
2010-11-11 16:24 FFI support for disjoint types Ludovic Courtès
@ 2010-11-20 21:59 ` Andy Wingo
2010-11-21 22:36 ` Ludovic Courtès
2011-01-30 22:30 ` Ludovic Courtès
1 sibling, 1 reply; 4+ messages in thread
From: Andy Wingo @ 2010-11-20 21:59 UTC (permalink / raw)
To: Ludovic Courtès; +Cc: guile-devel
On Thu 11 Nov 2010 17:24, ludo@gnu.org (Ludovic Courtès) writes:
> (define-wrapped-pointer-type class?
> wrap-class unwrap-class print-class)
Looks great! Would be a great addition to system foreign.
> (with-syntax ((type-name (datum->syntax #'pred (gensym)))
> (%wrap (datum->syntax #'wrap (gensym))))
> #'(begin
> (define-record-type type-name
> (%wrap pointer)
> pred
> (pointer unwrap))
You wouldn't need to do the gensym dance if we fixed Andreas' bug
(https://savannah.gnu.org/bugs/?31472), I don't think...
Andy
--
http://wingolog.org/
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: FFI support for disjoint types
2010-11-20 21:59 ` Andy Wingo
@ 2010-11-21 22:36 ` Ludovic Courtès
0 siblings, 0 replies; 4+ messages in thread
From: Ludovic Courtès @ 2010-11-21 22:36 UTC (permalink / raw)
To: guile-devel
Hi,
Andy Wingo <wingo@pobox.com> writes:
> On Thu 11 Nov 2010 17:24, ludo@gnu.org (Ludovic Courtès) writes:
>
>> (define-wrapped-pointer-type class?
>> wrap-class unwrap-class print-class)
>
> Looks great! Would be a great addition to system foreign.
Though I realized that some people might want a similar thing that uses
GOOPS objects instead of raw structs. Should we leave that to a
different macro or module?
Thanks,
Ludo’.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: FFI support for disjoint types
2010-11-11 16:24 FFI support for disjoint types Ludovic Courtès
2010-11-20 21:59 ` Andy Wingo
@ 2011-01-30 22:30 ` Ludovic Courtès
1 sibling, 0 replies; 4+ messages in thread
From: Ludovic Courtès @ 2011-01-30 22:30 UTC (permalink / raw)
To: guile-devel
Hello!
ludo@gnu.org (Ludovic Courtès) writes:
> (define-syntax define-wrapped-pointer-type
> (lambda (stx)
> (syntax-case stx ()
> ((_ pred wrap unwrap print) ;; hygiene
> (with-syntax ((type-name (datum->syntax #'pred (gensym)))
> (%wrap (datum->syntax #'wrap (gensym))))
> #'(begin
> (define-record-type type-name
> (%wrap pointer)
> pred
> (pointer unwrap))
> (define wrap
> ;; Use a weak hash table to preserve pointer identity, i.e.,
> ;; PTR1 == PTR2 <-> (eq? (wrap PTR1) (wrap PTR2)).
> (let ((ptr->obj (make-weak-value-hash-table)))
> (lambda (ptr)
> (or (hash-ref ptr->obj ptr)
> (let ((o (%wrap ptr)))
> (hash-set! ptr->obj ptr o)
> o)))))
> (set-record-type-printer! type-name print))))
> ((_ type-name print) ;; lazyness
> (let* ((type-name* (syntax->datum #'type-name))
> (pred-name (datum->syntax #'type-name
> (symbol-append type-name* '?)))
> (wrap-name (datum->syntax #'type-name
> (symbol-append 'wrap- type-name*)))
> (%wrap-name (datum->syntax #'type-name
> (symbol-append '%wrap- type-name*)))
> (unwrap-name (datum->syntax #'type-name
> (symbol-append 'unwrap-
> type-name*))))
> (with-syntax ((pred pred-name)
> (wrap wrap-name)
> (%wrap %wrap-name)
> (unwrap unwrap-name))
> #'(define-wrapped-pointer-type pred wrap unwrap print)))))))
I finally added the macro in (system foreign).
People looking for something similar with GOOPS capabilities can roll
their own.
Thanks,
Ludo’.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-01-30 22:30 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-11-11 16:24 FFI support for disjoint types Ludovic Courtès
2010-11-20 21:59 ` Andy Wingo
2010-11-21 22:36 ` Ludovic Courtès
2011-01-30 22:30 ` Ludovic Courtès
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).