2 ;;; Copyright (C) 2013 Andy Wingo <wingo@pobox.com>
4 ;;; Figl is free software: you can redistribute it and/or modify it
5 ;;; under the terms of the GNU Lesser General Public License as
6 ;;; published by the Free Software Foundation, either version 3 of the
7 ;;; License, or (at your option) any later version.
9 ;;; Figl is distributed in the hope that it will be useful, but WITHOUT
10 ;;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 ;;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
12 ;;; Public License for more details.
14 ;;; You should have received a copy of the GNU Lesser General Public
15 ;;; License along with this program. If not, see
16 ;;; <http://www.gnu.org/licenses/>.
20 ;; figl is the Foreign Interface to GL.
24 (define-module (figl runtime)
25 #:use-module (system foreign)
26 #:export (current-resolver
27 define-foreign-procedure
28 define-foreign-procedures
30 define-simple-foreign-type))
32 (define (default-resolver name)
33 (dynamic-pointer name (dynamic-link)))
35 (define current-resolver
36 (make-parameter default-resolver))
38 (define (resolve name)
39 ((current-resolver) name))
41 (define-syntax foreign-trampoline
45 name (pname ptype) ... -> type)
46 (with-syntax ((sname (symbol->string (syntax->datum #'name))))
48 (let ((ptr (resolve sname)))
50 (pointer->procedure (type)
53 (trampoline pname ...))))))))
55 (define-syntax define-foreign-procedure
57 ((define-foreign-procedure (name (pname ptype) ... -> type)
61 (foreign-trampoline trampoline
62 name (pname ptype) ... -> type))
63 (name (lambda (pname ...)
65 (let ((pname (ptype #:unwrap pname))
67 (type #:wrap (trampoline pname ...))))))
70 (define-syntax define-foreign-procedures
72 ((define-foreign-procedures ((name prototype ...) ...)
75 (define-foreign-procedure (name prototype ...)
79 (define-syntax define-foreign-type
81 ((_ name ffi-type unwrap wrap)
85 ((_ #:wrap x) (wrap x))
86 ((_ #:unwrap x) (unwrap x)))))))
88 (define-syntax define-simple-foreign-type
91 ;; We could dispatch through to define-foreign-type via:
93 ;; (define-foreign-type name
98 ;; However the resulting wrap expression:
100 ;; ((lambda (x) x) (trampoline arg ...))
102 ;; would not be in tail position, as the optimizer doesn't know
103 ;; that the foreign function just returns one value. This hack
104 ;; just passes the wrapped expression through, allowing it to be in
110 ((_ #:unwrap x) x))))))