X-Git-Url: http://git.lukelau.me/?a=blobdiff_plain;f=ast.scm;h=8a986173d675f43eb58cd0c5f7c6c7c679175d9f;hb=c4a5f8ab1efce20f0e1181ffe34639facb19594a;hp=6b546ac6f4214a2a9891e10da74ea8df7b5c1ed0;hpb=7be98b67cbad421a0b041d20e0f4620e70bd4cd6;p=scheme.git diff --git a/ast.scm b/ast.scm index 6b546ac..8a98617 100644 --- a/ast.scm +++ b/ast.scm @@ -75,19 +75,31 @@ ['stack (either (p x) (inner (caddr x)))] [else (p x)])) -(define (let-bindings e) - (define (pattern-match binding body) - (if (eqv? (ast-type binding) 'var) - (list (cons binding body)) - (let* ([constructor (car binding)] - [destructor (lambda (i) (dtor-name constructor i))]) - (flat-map (lambda (y i) - (pattern-match y `((,(destructor i) ,@body)))) - (cdr binding) - (range 0 (length (cdr binding))))))) - (flat-map (lambda (x) (pattern-match (car x) (cdr x))) (cadr e))) +(define let-bindings cadr) (define let-body cddr) + ; (let ([(foo a b) (foo 123 345)]) a) + ; | + ; v + ; (let ([a (foo~0 (foo 123 345)] + ; [b (foo~1 (foo 123 345)]) a) +(define (expand-pattern-matches x) + (define (pattern-match binding) + (let ([binding-name (car binding)] + [body (cadr binding)]) + (if (eqv? (ast-type binding-name) 'var) + (list (list binding-name body)) + (let* ([sum-name (car binding-name)] + [destructor (lambda (i) (dtor-name sum-name i))]) + (flat-map (lambda (y i) + (pattern-match (list y `(,(destructor i) ,body)))) + (cdr binding-name) + (range 0 (length (cdr binding-name)))))))) + (case (ast-type x) + ['let `(let ,(flat-map pattern-match (let-bindings x)) + ,@(map expand-pattern-matches (let-body x)))] + [else (ast-traverse expand-pattern-matches x)])) + (define (lambda? x) (and (list? x) (eq? (car x) 'lambda))) @@ -112,24 +124,32 @@ (filter (lambda (x) (eqv? (statement-type x) 'defines)) program)) +(define (program-map-exprs f program) + (map (lambda (x) + (case (statement-type x) + ['expr (f x)] + [else x])) + program)) + (define (program-body program) ; hack to have multi-expression bodies `(let () ,@(filter (lambda (x) (eqv? (statement-type x) 'expr)) program))) - - - ; gets both constructors and destructors + ; a data tor is either a constructor or destructor for an ADT + ; data-tors returns constructors and destructors for a data-layout ; (data A (foo Int Bool) ; (bar Bool)) ; | ; v - ; (foo . (constructor . (abs Int (abs Bool A)))) - ; (foo~0 . (0 . (abs A Int))) - ; (foo~1 . (1 . (abs A Bool))) - ; (bar . (constructor . (abs Bool A))) - ; (bar~0 . (0 . (abs A Bool))) + ; (foo . ((A foo constructor) . (abs Int (abs Bool A)))) + ; (foo~0 . ((A foo 0) . (abs A Int))) + ; (foo~1 . ((A foo 1) . (abs A Bool))) + ; (bar . ((A bar constructor) . (abs Bool A))) + ; (bar~0 . ((A bar 0) . (abs A Bool))) + ; ------+------------------------------------- + ; tor | info | type (define (data-tors data-layout) (define (constructor-type t products) @@ -137,7 +157,7 @@ (define (destructor ctor-name prod-type part-type index) (let ([name (dtor-name ctor-name index)]) - (cons name (cons index `(abs ,prod-type ,part-type))))) + (cons name (cons (list prod-type ctor-name index) `(abs ,prod-type ,part-type))))) (let ([type-name (car data-layout)] [ctors (cdr data-layout)]) @@ -146,7 +166,7 @@ (let* ([ctor-name (car ctor)] [products (cdr ctor)] - [maker (cons ctor-name (cons 'constructor (constructor-type type-name products)))] + [maker (cons ctor-name (cons (list type-name ctor-name 'constructor) (constructor-type type-name products)))] [dtors (map (lambda (t i) (destructor ctor-name type-name t i)) products @@ -156,7 +176,7 @@ ctors))) ; creates a type environment for a given adt definition -(define (data-tors-env data-layout) +(define (data-tors-type-env data-layout) (map (lambda (x) (cons (car x) (cddr x))) (data-tors data-layout))) (define (dtor-name ctor-name index)