; c-type.ss - C-Type interface ; ; Copyright (c) 2009 Higepon(Taro Minowa) ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions ; are met: ; ; 1. Redistributions of source code must retain the above copyright ; notice, this list of conditions and the following disclaimer. ; ; 2. Redistributions in binary form must reproduce the above copyright ; notice, this list of conditions and the following disclaimer in the ; documentation and/or other materials provided with the distribution. ; ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED ; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ; ; $Id: c-type.ss 621 2008-11-09 06:22:47Z higepon $ ;;;; DONT USE THIS library. (library (mosh c-type) (export define-c-struct define-c-struct-accessors c-type-test) (import (mosh ffi) (mosh) (mosh c-type helper) (mosh test) (rnrs)) ;; (define-c-struct-accessors struct-name (int a) offset) => (bytevector-int-ref bv 0 (native-endianness)) (define-syntax define-c-struct-accessors (lambda (x) (syntax-case x () [(_ struct-name (type var) offset) (with-syntax ([getter (gen-id #'struct-name #'var)]) #'(define getter (lambda (bv) (bytevector-s32-ref bv offset (native-endianness)))))]))) #;(define-syntax define-c-struct (lambda (x) (define (size-of type) (let ([size (os-constant (string->symbol (format "size-of-~a" type)))]) (assert size) size)) (define (calc-struct-size field-spec*) (let loop ([size 0] [spec* field-spec*]) (cond [(null? spec*) size] [else (loop (+ size (size-of (caar spec*))) (cdr spec*))]))) (syntax-case x (struct) [(_ name (struct field-spec* ...)) (with-syntax ([size-getter (gen-id 'size-of #'name)] [struct-size (calc-struct-size (syntax->datum #'(field-spec* ...)))] [constructor (datum->syntax #'name (string->symbol (string-append "make-" (symbol->string (syntax->datum #'name)))))]) #'(begin (define size-getter (lambda () struct-size)) (define constructor (lambda () (make-bytevector struct-size)))))]))) (define-syntax define-c-struct-accessor* (lambda (x) (syntax-case x () [(_ (type var offset) ...) #'(begin (define-c-struct-accessor type var offset) (define-c-struct-accessor* ...))]))) (define-syntax define-c-struct (lambda (x) (syntax-case x (struct) [(_ name (struct field-spec* ...)) (let-values ([(struct-size field*) (process-c-struct-field* (syntax->datum #'(field-spec* ...)))]) (with-syntax ([struct-size struct-size] [size-getter (gen-id 'size-of #'name)] [constructor (gen-id 'make #'name)] [(f* ...) (datum->syntax #'name field*)]) #`(begin (define-c-struct-accessor* #,@#'f*) (define size-getter (lambda () struct-size)) (define constructor (lambda () (make-bytevector struct-size))))))]))) (define (c-type-test) (test-begin "c-type tests") (let () (define-c-struct-accessors struct1 (int a) 0) (test-assert struct1-a) (test-true (procedure? struct1-a)) #t) (test-end)) )