diff --git a/libcompiler/simplifier.scm b/libcompiler/simplifier.scm index d692409..d483f46 100644 --- a/libcompiler/simplifier.scm +++ b/libcompiler/simplifier.scm @@ -100,6 +100,8 @@ (iter rst (cons (list var expr) bindings))] [`((define . ,_) . ,_) (error "Unrecognized define-form:" (first body))] + [`((begin . ,forms) . ,rst) + (iter (append forms rst) bindings)] [`(,form . ,rst) (if (null? bindings) (cons form (iter rst '())) @@ -175,6 +177,22 @@ ,@(filter-map second bindings) (,simple-op ,@(map first bindings))))) +; (let name ([var expr]...) bodyexpr...) +; => ((letrec ([name (lambda (var...) +; bodyexpr...)]) +; name) expr...) + +(define (simplify-named-let form) + (define (expand-binding binding) + (if (pair? binding) binding (list binding '#%undef))) + (define let-name (second form)) + (define bindings (map expand-binding (third form))) + (define bodyexprs (body->forms (cdddr form))) + + (simplify-form + `((letrec ([,let-name (lambda ,(map first bindings) ,@bodyexprs)]) ,let-name) + ,@(map second bindings)))) + ; (let ([var expr]...) bodyexpr...) ; first eval exprs, then assign bindings in parallel ; => (#%bind (tmp...) ; (#%set! tmp ,(simplify-form expr))... @@ -182,7 +200,7 @@ ; (#%set! var tmp)... ; bodyexpr...)) -(define (simplify-let form) +(define (simplify-unnamed-let form) (define (simplify-binding binding) (if (pair? binding) (list (first binding) (simplify-form (second binding))) @@ -215,6 +233,11 @@ (filter has-value? bindings)) ,@(map simplify-form bodyexprs)))) +(define (simplify-let form) + (if (symbol? (second form)) + (simplify-named-let form) + (simplify-unnamed-let form))) + ; (let* ...) ; eval exprs & bind variables serially ; => (let ([var-0 expr-0]) ; (let ([var-1 expr-1])