Break up lets into SCCs before typechecking
[scheme.git] / ast.scm
diff --git a/ast.scm b/ast.scm
index a0899192e21a1d44b0fe3296e380604133a3f1d2..a38a01257aea179e4638d376400fcc77e1c9318e 100644 (file)
--- a/ast.scm
+++ b/ast.scm
     ('if `(if ,@(map f (cdr x))))
     (else x)))
 
+(define (ast-collect f x)
+  (define (inner y) (ast-collect f y))
+  (case (ast-type x)
+    ['let (append (f x)
+                 (fold-map inner (let-bindings x))
+                 (fold-map inner (let-body x)))]
+    ['app (append (f x)
+                 (fold-map inner x))]
+    ['lambda (append (f x)
+                    (inner (lambda-body x)))]
+    ['if (append (f x)
+                (fold-map inner (cdr x)))]
+    [else (f x)]))
+
 (define let-bindings cadr)
 (define let-body cddr)
 
 ; for use elsewhere
 (define lambda-args cadr)
 (define lambda-body caddr)
+
+; utils
+(define (fold-map f x) (fold-left append '() (map f x)))
+(define (repeat x n) (if (<= n 0) '()
+                        (cons x (repeat x (- n 1)))))
+
+
+(define-syntax push!
+  (syntax-rules ()
+    ((_ s x) (set! s (cons x s)))))
+
+(define-syntax pop!
+  (syntax-rules ()
+    ((_ s) (let ([x (car s)])
+            (set! s (cdr s))
+            x))))