#lang s-exp "../lang.ss"
(require "anormal-frag-helpers.ss")
(require "elim-anon.ss")
(require "../../collects/moby/runtime/stx.ss")
(define (unbox-ids expr ids)
(let ([contents (stx-e expr)])
(cond
[(symbol? contents) (if (member contents ids)
(datum->stx false
(list 'unbox expr)
(stx-loc expr))
expr)]
[(cons? contents) (datum->stx false
(map (lambda (an-expr) (unbox-ids an-expr ids))
contents)
(stx-loc expr))]
[else expr])))
(define (box-locals expr)
(if (stx:atom? expr)
expr
(let* ([expr-list (stx-e expr)]
[first-elt (stx-e (first expr-list))])
(cond
[(equal? first-elt 'local)
(let* ([sugared-defs (map ensugar (stx-e (second expr-list)))]
[old-val-defs (filter (lambda (a-def)
(stx:atom? (second (stx-e a-def))))
sugared-defs)]
[val-ids (map (lambda (an-expr) (stx-e (second (stx-e an-expr))))
old-val-defs)]
[boxed-val-defs (map box-locals old-val-defs)]
[old-fun-defs (filter (lambda (a-def)
(stx:list? (second (stx-e a-def))))
sugared-defs)]
[boxed-fun-defs
(unbox-ids (datum->stx false
(map box-locals old-fun-defs)
(stx-loc (second expr-list)))
val-ids)])
(datum->stx
false
(list 'local
(datum->stx false
(append (stx-e boxed-fun-defs)
(map (lambda (symb)
`(define ,symb (box 'undefined)))
val-ids))
(stx-loc (second expr-list)))
(if (empty? boxed-val-defs)
(box-locals (third expr-list))
(cons 'begin
(foldr (lambda (a-def rest-expr)
(cons (list 'set-box!
(second (stx-e a-def))
(unbox-ids (third (stx-e a-def))
val-ids))
rest-expr))
(list (unbox-ids (box-locals (third expr-list))
val-ids))
boxed-val-defs))))
(stx-loc expr)))]
[(or (equal? first-elt 'quote)
(equal? first-elt 'define-struct)
(equal? first-elt 'require))
expr]
[else (datum->stx false
(map box-locals expr-list)
(stx-loc expr))]))))
(define (ready-anormalize expr)
(box-locals (datum->stx false
(map name-anon-procs (stx-e (lift-struct-defs expr)))
(stx-loc expr))))
(provide/contract
[ready-anormalize (stx:list? . -> . stx:list?)])