18 ('closure 'closure) ; only available in codegen
19 ('static-string 'static-string) ; only available in codegen
21 ((builtin? x) 'builtin)
23 ((integer? x) 'int-literal)
24 ((boolean? x) 'bool-literal)
25 ((string? x) 'string-literal)))
27 (define (ast-traverse f x)
29 ('let `(let ,(map (lambda (x) (list (car x) (f (cadr x))))
31 ,@(map f (let-body x))))
33 ('lambda `(lambda ,(lambda-args x) ,(f (lambda-body x))))
34 ('if `(if ,@(map f (cdr x))))
37 (define (ast-collect f x)
38 (define (inner y) (ast-collect f y))
41 (flat-map inner (let-bindings x))
42 (flat-map inner (let-body x)))]
45 ['lambda (append (f x)
46 (inner (lambda-body x)))]
48 (flat-map inner (cdr x)))]
51 (define (ast-find p x)
52 (define (inner y) (ast-find p y))
53 (define (any p x) (fold-left
54 (lambda (acc y) (if acc #t (p y)))
60 (apply either (cdr fs)))))
64 (any inner (let-bindings x))
65 (any inner (let-body x)))]
68 ['lambda (either (p x)
69 (inner (lambda-body x)))]
70 ['if (either (p x) (any inner (cdr x)))]
73 (define (let-bindings e)
74 (define (pattern-match x body)
75 (if (eqv? (ast-type x) 'var)
77 (let* ([constructor (car x)]
78 [destructor (lambda (i) (dtor-name constructor i))])
79 (flat-map (lambda (y i)
80 (pattern-match y (list (destructor i) body)))
82 (range 0 (length (cdr x)))))))
83 (flat-map (lambda (x) (pattern-match (car x) (cdr x))) (cadr e)))
84 (define let-body cddr)
87 (and (list? x) (eq? (car x) 'lambda)))
90 (define (statement-type x)
93 (eqv? (car x) 'data)) 'data]
95 (eqv? (car x) 'define)) 'define]
98 (define (program-datas program)
99 (filter (lambda (x) (eqv? (statement-type x) 'data))
102 (define (program-defines program)
103 (filter (lambda (x) (eqv? (statement-type x) 'defines))
106 (define (program-body program)
108 ,@(filter (lambda (x) (eqv? (statement-type x) 'expr))
111 ; gets both constructors and destructors
112 ; (data A (foo Int Bool)
116 ; (foo . (abs Int (abs Bool A)))
117 ; (foo~0 . (abs A Int)
118 ; (foo~1 . (abs A Bool)
119 ; (bar . (abs Bool A)
120 ; (bar~0 . (abs A Bool)
122 (define (data-tors data-def)
123 (define (constructor-type t products)
124 (fold-right (lambda (x acc) `(abs ,x ,acc)) t products))
126 (define (destructor ctor-name prod-type part-type index)
127 (let ([name (dtor-name ctor-name index)])
128 (cons name `(abs ,prod-type ,part-type))))
130 (let ([type-name (cadr data-def)]
131 [ctors (cddr data-def)])
134 (let* ([ctor-name (car ctor)]
135 [products (cdr ctor)]
137 [maker (cons ctor-name (constructor-type type-name products))]
139 [dtors (map (lambda (t i) (destructor ctor-name type-name t i))
141 (range 0 (length products)))])
143 (cons maker (append dtors acc))))
147 (define (dtor-name ctor-name index)
149 (string-append (symbol->string ctor-name)
151 (number->string index))))
153 ; for use in normalized form
154 (define lambda-arg caadr)
156 (define lambda-args cadr)
157 (define lambda-body caddr)
162 (append (range s (- n 1))
163 (list (+ s (- n 1))))))
165 (define (flat-map f . xs) (fold-left append '() (apply map (cons f xs))))
166 (define (repeat x n) (if (<= n 0) '()
167 (cons x (repeat x (- n 1)))))
172 ((_ s x) (set! s (cons x s)))))
176 ((_ s) (let ([x (car s)])