(module finite-types mzscheme
(provide define-enumerated-type define-finite-type)
(require (lib "9.ss" "srfi")
(lib "60.ss" "srfi"))
(define-syntax define-enumerated-type
(syntax-rules ()
((define-enumerated-type dispatcher type
predicate instance-vector name-accessor index-accessor
(instance-name ...))
(define-finite-type dispatcher type ()
predicate instance-vector name-accessor index-accessor
((instance-name) ...)))))
(define-syntax define-finite-type
(syntax-rules ()
((define-finite-type dispatcher type field-tags
predicate instance-vector name-accessor index-accessor
field-clauses ... instances)
(gen-names
(dispatcher type field-tags
predicate instance-vector name-accessor index-accessor
field-clauses ...)
instances))))
(define-syntax gen-names
(syntax-rules ()
((gen-names proto instances)
(gen-names proto instances () ()))
((gen-names proto ((instance-name . fvs) . more) named n)
(gen-names proto more
((%instance-name (+ . n) instance-name . fvs) . named)
(1 . n)))
((gen-names proto () named n)
(gen-names proto () named))
((gen-names proto ordered-instances (instance . more))
(gen-names proto (instance . ordered-instances) more))
((gen-names proto ordered-instances ())
(define-finite-type* proto ordered-instances))))
(define-syntax define-finite-type*
(syntax-rules ()
((define-finite-type*
(dispatcher type
(field-tag-1 ...)
predicate instance-vector name-accessor index-accessor
(field-tag-2 accessor . ?modifier)
...)
((%instance-name instance-id instance-name field-value ...) ...))
(begin
(define-record-type type (make-instance index field-tag-1 ...)
predicate
(index index)
(field-tag-2 accessor . ?modifier) ...)
(define %instance-name (make-instance instance-id field-value ...))
...
(define-syntax dispatcher
(syntax-rules (instance-name ...)
((dispatcher instance-name) %instance-name) ...))
(define instance-vector (vector (dispatcher instance-name) ...))
(define name-accessor
(let ((name-vector (apply vector '(instance-name ...))))
(lambda (instance)
(vector-ref name-vector (index instance)))))
(define index-accessor index)))))
)