srfi-9
This commit is contained in:
parent
460a060423
commit
f61a6c2228
160
lib/srfi/srfi-9.scm
Normal file
160
lib/srfi/srfi-9.scm
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
; Copyright (c) 1993-2004 by Richard Kelsey and Jonathan Rees. See file COPYING.
|
||||||
|
|
||||||
|
|
||||||
|
; This knows about the implementation of records and creates the various
|
||||||
|
; accessors, mutators, etc. directly instead of calling the procedures
|
||||||
|
; from the record structure. This is done to allow the optional auto-inlining
|
||||||
|
; optimizer to inline the accessors, mutators, etc.
|
||||||
|
|
||||||
|
; LOOPHOLE is used to get a little compile-time type checking (in addition to
|
||||||
|
; the usual complete run-time checking).
|
||||||
|
|
||||||
|
(define-syntax define-record-type
|
||||||
|
(syntax-rules ()
|
||||||
|
((define-record-type ?id ?type
|
||||||
|
(?constructor ?arg ...)
|
||||||
|
(?field . ?field-stuff)
|
||||||
|
...)
|
||||||
|
(begin (define ?type (make-record-type '?id '(?field ...)))
|
||||||
|
(define-constructor ?constructor ?type
|
||||||
|
((?arg :value) ...)
|
||||||
|
(?field ...))
|
||||||
|
(define-accessors ?type () (?field . ?field-stuff) ...)))
|
||||||
|
((define-record-type ?id ?type
|
||||||
|
(?constructor ?arg ...)
|
||||||
|
?pred
|
||||||
|
?more ...)
|
||||||
|
(begin (define-record-type ?id ?type
|
||||||
|
(?constructor ?arg ...)
|
||||||
|
?more ...)
|
||||||
|
(define ?pred
|
||||||
|
(lambda (x)
|
||||||
|
(and (record? x)
|
||||||
|
(eq? ?type (record-ref x 0)))))))))
|
||||||
|
|
||||||
|
(define-syntax define-synchronized-record-type
|
||||||
|
(syntax-rules ()
|
||||||
|
((define-synchronized-record-type ?id ?type
|
||||||
|
(?constructor ?arg ...)
|
||||||
|
?pred
|
||||||
|
(?field . ?field-stuff)
|
||||||
|
...)
|
||||||
|
(define-synchronized-record-type ?id ?type
|
||||||
|
(?constructor ?arg ...)
|
||||||
|
(?field ...)
|
||||||
|
?pred
|
||||||
|
(?field . ?field-stuff)
|
||||||
|
...))
|
||||||
|
((define-synchronized-record-type ?id ?type
|
||||||
|
(?constructor ?arg ...)
|
||||||
|
(?sync-field ...)
|
||||||
|
?pred
|
||||||
|
(?field . ?field-stuff)
|
||||||
|
...)
|
||||||
|
(begin (define ?type (make-record-type '?id '(?field ...)))
|
||||||
|
(define-constructor ?constructor ?type
|
||||||
|
((?arg :value) ...)
|
||||||
|
(?field ...))
|
||||||
|
(define ?pred
|
||||||
|
(lambda (x)
|
||||||
|
(and (record? x)
|
||||||
|
(eq? ?type (record-ref x 0)))))
|
||||||
|
(define-accessors ?type (?sync-field ...)
|
||||||
|
(?field . ?field-stuff) ...)))))
|
||||||
|
|
||||||
|
; (define-constructor <id> <type> ((<arg> <arg-type>)*) (<field-name>*))
|
||||||
|
;
|
||||||
|
; Checks to see that there is an <arg> corresponding to every <field-name>.
|
||||||
|
|
||||||
|
(define-syntax define-constructor
|
||||||
|
(lambda (e r c)
|
||||||
|
(let ((%record (r 'record))
|
||||||
|
(%begin (r 'begin))
|
||||||
|
(%lambda (r 'lambda))
|
||||||
|
(%loophole (r 'loophole))
|
||||||
|
(%proc (r 'proc))
|
||||||
|
(%unspecific (r 'unspecific))
|
||||||
|
(name (cadr e))
|
||||||
|
(type (caddr e))
|
||||||
|
(args (map r (map car (cadddr e))))
|
||||||
|
(arg-types (map cadr (cadddr e)))
|
||||||
|
(fields (map r (caddr (cddr e)))))
|
||||||
|
(define (mem? name list)
|
||||||
|
(cond ((null? list) #f)
|
||||||
|
((c name (car list)) #t)
|
||||||
|
(else
|
||||||
|
(mem? name (cdr list)))))
|
||||||
|
(define (every? pred list)
|
||||||
|
(cond ((null? list) #t)
|
||||||
|
((pred (car list))
|
||||||
|
(every? pred (cdr list)))
|
||||||
|
(else #f)))
|
||||||
|
(if (every? (lambda (arg)
|
||||||
|
(mem? arg fields))
|
||||||
|
args)
|
||||||
|
`(define ,name
|
||||||
|
(,%loophole (,%proc ,arg-types ,type)
|
||||||
|
(,%lambda ,args
|
||||||
|
(,%record ,type . ,(map (lambda (field)
|
||||||
|
(if (mem? field args)
|
||||||
|
field
|
||||||
|
(list %unspecific)))
|
||||||
|
fields)))))
|
||||||
|
e)))
|
||||||
|
(record begin lambda loophole proc unspecific))
|
||||||
|
|
||||||
|
(define-syntax define-accessors
|
||||||
|
(lambda (e r c)
|
||||||
|
(let ((%define-accessor (r 'define-accessor))
|
||||||
|
(%begin (r 'begin))
|
||||||
|
(type (cadr e))
|
||||||
|
(sync-fields (caddr e))
|
||||||
|
(field-specs (cdddr e)))
|
||||||
|
(define (mem? name list)
|
||||||
|
(cond ((null? list) #f)
|
||||||
|
((c name (car list)) #t)
|
||||||
|
(else
|
||||||
|
(mem? name (cdr list)))))
|
||||||
|
(do ((i 1 (+ i 1))
|
||||||
|
(field-specs field-specs (cdr field-specs))
|
||||||
|
(ds '()
|
||||||
|
(cons `(,%define-accessor
|
||||||
|
,(mem? (caar field-specs)
|
||||||
|
sync-fields)
|
||||||
|
,type ,i ,@(cdar field-specs))
|
||||||
|
ds)))
|
||||||
|
((null? field-specs)
|
||||||
|
`(,%begin ,@ds)))))
|
||||||
|
(define-accessor begin))
|
||||||
|
|
||||||
|
(define-syntax define-accessor
|
||||||
|
(syntax-rules ()
|
||||||
|
((define-accessor ?sync? ?type ?index ?accessor)
|
||||||
|
(define ?accessor
|
||||||
|
(loophole (proc (?type) :value)
|
||||||
|
(lambda (r)
|
||||||
|
((ref-proc ?sync?) (loophole :record r) ?type ?index)))))
|
||||||
|
((define-accessor ?sync? ?type ?index ?accessor ?modifier)
|
||||||
|
(begin (define-accessor ?sync? ?type ?index ?accessor)
|
||||||
|
(define ?modifier
|
||||||
|
(loophole (proc (?type :value) :unspecific)
|
||||||
|
(lambda (r new)
|
||||||
|
((set-proc ?sync?)
|
||||||
|
(loophole :record r) ?type ?index new))))))
|
||||||
|
((define-accessor ?sync? ?type ?index)
|
||||||
|
(begin))))
|
||||||
|
|
||||||
|
(define-syntax ref-proc
|
||||||
|
(syntax-rules ()
|
||||||
|
((ref-proc #t)
|
||||||
|
provisional-checked-record-ref)
|
||||||
|
((ref-proc #f)
|
||||||
|
checked-record-ref)))
|
||||||
|
|
||||||
|
(define-syntax set-proc
|
||||||
|
(syntax-rules ()
|
||||||
|
((set-proc #t)
|
||||||
|
provisional-checked-record-set!)
|
||||||
|
((set-proc #f)
|
||||||
|
checked-record-set!)))
|
||||||
|
|
Loading…
Reference in a new issue