Break up lets into SCCs before typechecking
[scheme.git] / ast.scm
1 (define (ast-type x)
2   (define (builtin? x)
3     (case x
4       ('+ #t)
5       ('- #t)
6       ('* #t)
7       ('! #t)
8       ('= #t)
9       ('bool->int #t)
10       ('print #t)
11       (else #f)))
12   (cond
13    ((list? x)
14     (case (car x)
15       ('if 'if)
16       ('let 'let)
17       ('lambda 'lambda)
18       ('closure 'closure) ; only available in codegen
19       ('static-string 'static-string) ; only available in codegen
20       (else 'app)))
21    ((builtin? x) 'builtin)
22    ((symbol? x) 'var)
23    ((integer? x) 'int-literal)
24    ((boolean? x) 'bool-literal)
25    ((string? x) 'string-literal)))
26
27 (define (ast-traverse f x)
28   (case (ast-type x)
29     ('let `(let ,(map (lambda (x) (list (car x) (f (cadr x))))
30                       (let-bindings x))
31              ,@(map f (let-body x))))
32     ('app (map f x))
33     ('lambda `(lambda ,(lambda-args x) ,(f (lambda-body x))))
34     ('if `(if ,@(map f (cdr x))))
35     (else x)))
36
37 (define (ast-collect f x)
38   (define (inner y) (ast-collect f y))
39   (case (ast-type x)
40     ['let (append (f x)
41                   (fold-map inner (let-bindings x))
42                   (fold-map inner (let-body x)))]
43     ['app (append (f x)
44                   (fold-map inner x))]
45     ['lambda (append (f x)
46                      (inner (lambda-body x)))]
47     ['if (append (f x)
48                  (fold-map inner (cdr x)))]
49     [else (f x)]))
50
51 (define let-bindings cadr)
52 (define let-body cddr)
53
54 (define (lambda? x)
55   (and (list? x) (eq? (car x) 'lambda)))
56
57 ; for use in normalized form
58 (define lambda-arg caadr)
59 ; for use elsewhere
60 (define lambda-args cadr)
61 (define lambda-body caddr)
62
63 ; utils
64 (define (fold-map f x) (fold-left append '() (map f x)))
65 (define (repeat x n) (if (<= n 0) '()
66                          (cons x (repeat x (- n 1)))))
67
68
69 (define-syntax push!
70   (syntax-rules ()
71     ((_ s x) (set! s (cons x s)))))
72
73 (define-syntax pop!
74   (syntax-rules ()
75     ((_ s) (let ([x (car s)])
76              (set! s (cdr s))
77              x))))