-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcogen-ctors.scm
74 lines (70 loc) · 2.21 KB
/
cogen-ctors.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
;;; cogen-ctors.scm
;;; copyright © 1996, 1997, 1998 by Peter Thiemann
;;; non-commercial use is free as long as the original copright notice
;;; remains intact
;;; definitions that implement constructors
;;; example:
;;; (define-data type-name (nil) (cons car cdr))
;;; defines a datatype with two constructors, the nullary "nil" and
;;; the binary "cons", the selectors of the latter being "car" and "cdr"
(define-syntax define-data
(lambda (x r c)
(let* ((%begin (r 'begin))
(%car (r 'car))
(%define (r 'define))
(%equal? (r 'equal?))
(%if (r 'if))
(%list (r 'list))
(%list-ref (r 'list-ref))
(rest (cddr x))
(ctor-decls (if (pair? (car rest)) rest (cdr rest))))
(cons %begin
(apply append
(map (lambda (ctor-decl)
(let* ((ctor-name (car ctor-decl))
(ctor-test (string->symbol (string-append
(symbol->string
ctor-name) "?"))))
(cons
`(,%define
,ctor-decl
(,%list ',(car ctor-decl)
,@(cdr ctor-decl)))
(cons
`(,%define (,ctor-test arg)
(,%equal? (,%car arg) ',ctor-name))
(let loop ((sels (cdr ctor-decl)) (i 1))
(if (null? sels)
'()
(cons
`(,%define
(,(car sels) x)
(,%if (,ctor-test x)
(,%list-ref x ,i)
(error "bad selector ~A applied to ~S" ',(car sels) x)))
(loop (cdr sels) (+ i 1)))))))))
ctor-decls))))))
;;;
;;;(define-syntax defctor
;;; (lambda (x r c)
;;; `(,(r 'define)
;;; ,(cadr x)
;;; (,(r 'list) ,@(cddr x)))))
;;;
;;; define-syntax does not work as a single expression must expand to
;;; another single expression
;;; no there was a format error, furthermore the form (begin <define>
;;; ...) is explicitly allowed for (essential syntax)!
(define (ctors-make-test ctor)
(string->symbol (string-append (symbol->string ctor) "?")))
(define (ctors-generate-define defconstr-clause)
(map (lambda (ctor-decl)
(cons
`(define ,ctor-decl (list ',(car ctor-decl) ,@(cdr ctor-decl)))
(let loop ((sels (cdr ctor-decl)) (i 1))
(if (null? sels)
'()
(cons
`(define (,(car sels) x) (list-ref x ,i))
(loop (cdr sels) (+ i 1)))))))
(cdr defconstr-clause)))