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 (define-foreign-procedure
27 define-foreign-procedures
29 define-simple-foreign-type
33 (define-syntax foreign-trampoline
35 ((_ trampoline resolve-name (pname ptype) ... -> type)
38 (pointer->procedure (type)
41 (trampoline pname ...)))))
43 (define-syntax define-foreign-procedure
45 ((define-foreign-procedure (name (pname ptype) ... -> type)
50 (foreign-trampoline trampoline resolve-name
51 (pname ptype) ... -> type))
52 (name (lambda (pname ...)
54 (let ((pname (ptype #:unwrap pname))
56 (type #:wrap (trampoline pname ...))))))
59 (define-syntax define-foreign-procedures
61 ((define-foreign-procedures ((name prototype ...) ...)
65 (define-foreign-procedure (name prototype ...)
70 (define-syntax define-foreign-type
72 ((_ name ffi-type unwrap wrap)
76 ((_ #:wrap x) (wrap x))
77 ((_ #:unwrap x) (unwrap x)))))))
79 (define-syntax define-simple-foreign-type
82 ;; We could dispatch through to define-foreign-type via:
84 ;; (define-foreign-type name
89 ;; However the resulting wrap expression:
91 ;; ((lambda (x) x) (trampoline arg ...))
93 ;; would not be in tail position, as the optimizer doesn't know
94 ;; that the foreign function just returns one value. This hack
95 ;; just passes the wrapped expression through, allowing it to be in
101 ((_ #:unwrap x) x))))))
103 (define-syntax-rule (define-enumeration enumerator (name value) ...)
104 (define-syntax enumerator
109 ((_ enum) (number? (syntax->datum #'enum))
112 (or (assq-ref '((name . value) ...)
113 (syntax->datum #'enum))
114 (syntax-violation 'enumerator "invalid enumerated value"
117 (define-syntax-rule (define-bitfield bitfield (name value) ...)
118 (define-syntax bitfield
127 (let ((datum (syntax->datum bit)))
130 (or (assq-ref '((name . value) ...) datum)
131 (syntax-violation 'bitfield "invalid bitfield value"
133 #'(bit (... ...)))))))))