[functional tests] more work on the binary-format macro

This commit is contained in:
Joe Thornber
2017-08-10 15:07:20 +01:00
parent 78488e8909
commit d0040a169d
4 changed files with 59 additions and 38 deletions

View File

@ -1,7 +1,14 @@
(library
(binary-format)
(export binary-format)
(import (rnrs))
(export size-type binary-format le32 le64 bytes)
(import (rnrs)
(list-utils))
(define-syntax size-type
(syntax-rules (le32 le64 bytes)
((_ le32) 4)
((_ le64) 8)
((_ (bytes count)) count)))
(define-syntax unpack-type
(syntax-rules (le32 le64 bytes)
@ -16,26 +23,34 @@
(bytevector-copy! bv offset copy 0 count)
copy))))
(define (size-type t)
(syntax-case t (le32 le64 bytes)
(le32 #'4)
(le64 #'8)
((bytes count) #'count)))
;;; FIXME: (bytes <count>) has to use a literal rather than a symbol.
(define-syntax binary-format
(lambda (x)
(syntax-case x ()
((_ (name pack-name unpack-name) (field type) ...)
(with-syntax ((((t o) ...)
(let f ((acc 0) (types #'(type ...)))
(if (null? types)
'()
(cons (list (car types) acc)
(f (+ (syntax->datum (size-type (car types))) acc) (cdr types)))))))
#`(begin
(define-record-type name (fields field ...))
(syntax-rules ()
((_ (name pack-name unpack-name) (field type) ...)
(begin
(define-record-type name (fields field ...))
(define (unpack-name bv offset)
(let ((offset offset))
(define (inc-offset n v)
(set! offset (+ offset n))
v)
((record-constructor (record-constructor-descriptor name))
(inc-offset (size-type type) (unpack-type bv offset type)) ...)))))))
;;; since le32, le64 and bytes are used as auxiliary keywords, we must export
;;; definitions of them as well.
;;; FIXME: use a macro to remove duplication
(define-syntax le32
(lambda (x)
(syntax-violation 'le32 "misplaced auxiliary keyword" x)))
(define-syntax le64
(lambda (x)
(syntax-violation 'le64 "misplaced auxiliary keyword" x)))
(define-syntax bytes
(lambda (x)
(syntax-violation 'bytes "misplaced auxiliary keyword" x))))
(define (unpack-name bv offset)
((record-constructor (record-type-descriptor name))
(unpack-type bv (+ offset o) t) ...)))))))))