name) (list (wrap `(immutable ,(syntax->datum #'name))) (guess-accessor-name #'name) #f)] [else (syntax-violation 'define-record-type "invalid field specifier" x)])) (map f fields)) (define-syntax define-record-type0 (lambda (stx) (define *unspecified* (cons #f #f)) (define (unspecified? obj) (eq? *unspecified* obj)) (syntax-case stx () ((_ (record-name constructor-name predicate-name) record-clause ...) (let loop ((_fields *unspecified*) (_parent *unspecified*) (_protocol *unspecified*) (_sealed *unspecified*) (_opaque *unspecified*) (_nongenerative *unspecified*) (_constructor *unspecified*) (_parent-rtd *unspecified*) (record-clauses #'(record-clause ...))) (syntax-case record-clauses (fields parent protocol sealed opaque nongenerative constructor parent-rtd) [() (let* ((fields (if (unspecified? _fields) '() _fields)) (field-names (list->vector (map car fields))) (field-accessors (fold-left (lambda (lst x c) (cons #`(define #,(cadr x) (record-accessor record-name #,c)) lst)) '() fields (sequence (length fields)))) (field-mutators (fold-left (lambda (lst x c) (if (caddr x) (cons #`(define #,(caddr x) (record-mutator record-name #,c)) lst) lst)) '() fields (sequence (length fields)))) (parent-cd (cond ((not (unspecified? _parent)) #`(record-constructor-descriptor #,_parent)) ((not (unspecified? _parent-rtd)) (cadr _parent-rtd)) (else #f))) (parent-rtd (cond ((not (unspecified? _parent)) #`(record-type-descriptor #,_parent)) ((not (unspecified? _parent-rtd)) (car _parent-rtd)) (else #f))) (protocol (if (unspecified? _protocol) #f _protocol)) (uid (if (unspecified? _nongenerative) #f _nongenerative)) (sealed? (if (unspecified? _sealed) #f _sealed)) (opaque? (if (unspecified? _opaque) #f _opaque))) #`(begin (define record-name (make-record-type-descriptor (quote record-name) #,parent-rtd #,uid #,sealed? #,opaque? #,field-names)) (define constructor-name (record-constructor (make-record-constructor-descriptor record-name #,parent-cd #,protocol))) (define dummy (let () (register-record-type (quote record-name) record-name (make-record-constructor-descriptor record-name #,parent-cd #,protocol)) 'dummy)) (define predicate-name (record-predicate record-name)) #,@field-accessors #,@field-mutators))] [((fields record-fields ...) . rest) (if (unspecified? _fields) (loop (process-fields #'record-name #'(record-fields ...)) _parent _protocol _sealed _opaque _nongenerative _constructor _parent-rtd #'rest) (raise (make-assertion-violation)))] [((parent parent-name) . rest) (if (not (unspecified? _parent-rtd)) (raise (make-assertion-violation)) (if (unspecified? _parent) (loop _fields #'parent-name _protocol _sealed _opaque _nongenerative _constructor _parent-rtd #'rest) (raise (make-assertion-violation))))] [((protocol expression) . rest) (if (unspecified? _protocol) (loop _fields _parent #'expression _sealed _opaque _nongenerative _constructor _parent-rtd #'rest) (raise (make-assertion-violation)))] [((sealed sealed?) . rest) (if (unspecified? _sealed) (loop _fields _parent _protocol #'sealed? _opaque _nongenerative _constructor _parent-rtd #'rest) (raise (make-assertion-violation)))] [((opaque opaque?) . rest) (if (unspecified? _opaque) (loop _fields _parent _protocol _sealed #'opaque? _nongenerative _constructor _parent-rtd #'rest) (raise (make-assertion-violation)))] [((nongenerative) . rest) (if (unspecified? _nongenerative) (loop _fields _parent _protocol _sealed _opaque #`(quote #,(datum->syntax #'record-name (gensym))) _constructor _parent-rtd #'rest) (raise (make-assertion-violation)))] [((nongenerative uid) . rest) (if (unspecified? _nongenerative) (loop _fields _parent _protocol _sealed _opaque #''uid _constructor _parent-rtd #'rest) (raise (make-assertion-violation)))] [((parent-rtd rtd cd) . rest) (if (not (unspecified? _parent)) (raise (make-assertion-violation)) (if (unspecified? _parent-rtd) (loop _fields _parent _protocol _sealed _opaque _nongenerative _constructor #'(rtd cd) #'rest) (raise (make-assertion-violation))))])))))) (define-syntax record-type-descriptor (lambda (stx) (syntax-case stx () ((_ name) #`(lookup-record-type-descriptor #,(datum->syntax stx (list 'quote (syntax->datum #'name)))))))) (define-syntax record-constructor-descriptor (lambda (stx) (syntax-case stx () ((_ name) #`(lookup-record-constructor-descriptor #,(datum->syntax stx (list 'quote (syntax->datum #'name)))))))) )