Removing the hack of freevar.ss in preference for the proper usage of syntax/free-vars. This should also decrease the size of closures, because it is accurate, whereas the other was not.
svn: r11222
This commit is contained in:
parent
7c6d9bfb58
commit
962fea6513
|
@ -21,4 +21,7 @@
|
||||||
(compose #;(lambda (stx) (values stx empty))
|
(compose #;(lambda (stx) (values stx empty))
|
||||||
defun
|
defun
|
||||||
elim-callcc
|
elim-callcc
|
||||||
(make-anormal-term elim-letrec-term))))))
|
(make-anormal-term elim-letrec-term)
|
||||||
|
#;(make-anormal-term (lambda (x) x))
|
||||||
|
#;elim-letrec-term
|
||||||
|
)))))
|
||||||
|
|
|
@ -38,7 +38,8 @@
|
||||||
(list* (cons key val)
|
(list* (cons key val)
|
||||||
(filter (lambda (k*v) (not (equal? key (car k*v))))
|
(filter (lambda (k*v) (not (equal? key (car k*v))))
|
||||||
(let-values ([(current)
|
(let-values ([(current)
|
||||||
(continuation-mark-set->list (current-continuation-marks web-prompt) the-save-cm-key)])
|
(continuation-mark-set->list (current-continuation-marks web-prompt)
|
||||||
|
the-save-cm-key)])
|
||||||
(if (empty? current)
|
(if (empty? current)
|
||||||
empty
|
empty
|
||||||
(first current)))))))
|
(first current)))))))
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
#lang scheme/base
|
#lang scheme/base
|
||||||
(require (for-template scheme/base)
|
(require (for-template scheme/base)
|
||||||
syntax/kerncase
|
syntax/kerncase
|
||||||
#;syntax/free-vars
|
syntax/free-vars
|
||||||
"freevars.ss"
|
|
||||||
mzlib/list
|
mzlib/list
|
||||||
mzlib/plt-match
|
mzlib/plt-match
|
||||||
"util.ss"
|
"util.ss"
|
||||||
|
|
|
@ -77,68 +77,74 @@
|
||||||
(#%plain-app current-saved-continuation-marks-and #,ke-prime #,me-prime)
|
(#%plain-app current-saved-continuation-marks-and #,ke-prime #,me-prime)
|
||||||
#,be-prime)))))]
|
#,be-prime)))))]
|
||||||
[(#%plain-app call/cc w)
|
[(#%plain-app call/cc w)
|
||||||
(let-values ([(cm ref-to-cm) (generate-formal 'current-marks)]
|
(let-values ([(cm ref-to-cm) (generate-formal 'current-marks stx)]
|
||||||
[(x ref-to-x) (generate-formal 'x)])
|
[(x ref-to-x) (generate-formal 'x stx)])
|
||||||
(markit
|
(markit
|
||||||
(quasisyntax/loc stx
|
(quasisyntax/loc stx
|
||||||
(#%plain-app #,(elim-callcc #'w)
|
(#%plain-app
|
||||||
(#%plain-app (#%plain-lambda (#,cm)
|
#,(elim-callcc #'w)
|
||||||
(#%plain-lambda #,x
|
(#%plain-app
|
||||||
(#%plain-app abort
|
(#%plain-lambda
|
||||||
(#%plain-lambda () (#%plain-app resume #,ref-to-cm #,ref-to-x)))))
|
(#,cm)
|
||||||
(#%plain-app activation-record-list))))))]
|
(#%plain-lambda #,x
|
||||||
|
(#%plain-app abort
|
||||||
|
(#%plain-lambda () (#%plain-app resume #,ref-to-cm #,ref-to-x)))))
|
||||||
|
(#%plain-app activation-record-list))))))]
|
||||||
[(#%plain-app call-with-values (#%plain-lambda () prod) cons)
|
[(#%plain-app call-with-values (#%plain-lambda () prod) cons)
|
||||||
(let ([cons-prime (datum->syntax #f (gensym 'cons))])
|
(let-values ([(consumer ref-to-consumer) (generate-formal 'consumer stx)])
|
||||||
(quasisyntax/loc stx
|
(quasisyntax/loc stx
|
||||||
(let-values ([(#,cons-prime) #,(mark-lambda-as-safe (elim-callcc #'cons))])
|
(let-values ([(#,consumer) #,(mark-lambda-as-safe (elim-callcc #'cons))])
|
||||||
#,(markit
|
#,(markit
|
||||||
(quasisyntax/loc stx
|
(quasisyntax/loc stx
|
||||||
(#%plain-app call-with-values
|
(#%plain-app
|
||||||
#,(mark-lambda-as-safe
|
call-with-values
|
||||||
(quasisyntax/loc stx
|
#,(mark-lambda-as-safe
|
||||||
(#%plain-lambda ()
|
(quasisyntax/loc stx
|
||||||
#,(elim-callcc/mark
|
(#%plain-lambda ()
|
||||||
(lambda (x)
|
#,(elim-callcc/mark
|
||||||
(quasisyntax/loc stx
|
(lambda (x)
|
||||||
(with-continuation-mark the-cont-key #,cons-prime #,x)))
|
(quasisyntax/loc stx
|
||||||
#'prod))))
|
(with-continuation-mark the-cont-key #,ref-to-consumer #,x)))
|
||||||
#,cons-prime))))))]
|
#'prod))))
|
||||||
|
#,ref-to-consumer))))))]
|
||||||
[(#%plain-app w (#%plain-app . stuff))
|
[(#%plain-app w (#%plain-app . stuff))
|
||||||
(with-syntax ([e #'(#%plain-app . stuff)])
|
(with-syntax ([e #'(#%plain-app . stuff)])
|
||||||
(syntax-case #'w (#%plain-lambda case-lambda)
|
(syntax-case #'w (#%plain-lambda case-lambda)
|
||||||
[(#%plain-lambda formals body)
|
[(#%plain-lambda formals body)
|
||||||
(let ([w-prime (datum->syntax #f (gensym 'l))])
|
(let-values ([(w-prime ref-to-w-prime) (generate-formal 'l stx)])
|
||||||
(quasisyntax/loc stx
|
(quasisyntax/loc stx
|
||||||
(let-values ([(#,w-prime) #,(elim-callcc #'w)])
|
(let-values ([(#,w-prime) #,(elim-callcc #'w)])
|
||||||
#,(markit
|
#,(markit
|
||||||
(quasisyntax/loc stx
|
(quasisyntax/loc stx
|
||||||
(#%plain-app #,w-prime
|
(#%plain-app #,ref-to-w-prime
|
||||||
#,(elim-callcc/mark
|
#,(elim-callcc/mark
|
||||||
(lambda (x)
|
(lambda (x)
|
||||||
(quasisyntax/loc stx
|
(quasisyntax/loc stx
|
||||||
(with-continuation-mark the-cont-key #,w-prime #,x)))
|
(with-continuation-mark the-cont-key #,ref-to-w-prime #,x)))
|
||||||
#'e)))))))]
|
#'e)))))))]
|
||||||
[(case-lambda [formals body] ...)
|
[(case-lambda [formals body] ...)
|
||||||
(let ([w-prime (datum->syntax #f (gensym 'cl))])
|
(let-values ([(w-prime ref-to-w-prime) (generate-formal 'cl stx)])
|
||||||
(quasisyntax/loc stx
|
(quasisyntax/loc stx
|
||||||
(let-values ([(#,w-prime) #,(elim-callcc #'w)])
|
(let-values ([(#,w-prime) #,(elim-callcc #'w)])
|
||||||
#,(markit
|
#,(markit
|
||||||
(quasisyntax/loc stx
|
(quasisyntax/loc stx
|
||||||
(#%plain-app #,w-prime
|
(#%plain-app #,ref-to-w-prime
|
||||||
#,(elim-callcc/mark
|
#,(elim-callcc/mark
|
||||||
(lambda (x)
|
(lambda (x)
|
||||||
(quasisyntax/loc stx
|
(quasisyntax/loc stx
|
||||||
(with-continuation-mark the-cont-key #,w-prime #,x)))
|
(with-continuation-mark the-cont-key #,ref-to-w-prime #,x)))
|
||||||
#'e)))))))]
|
#'e)))))))]
|
||||||
[_else
|
[_else
|
||||||
(let ([w-prime (elim-callcc #'w)])
|
(let-values ([(w-prime ref-to-w-prime) (generate-formal 'other stx)])
|
||||||
(markit
|
(quasisyntax/loc stx
|
||||||
(quasisyntax/loc stx
|
(let ([#,w-prime #,(elim-callcc #'w)])
|
||||||
(#%plain-app #,w-prime
|
(markit
|
||||||
#,(elim-callcc/mark
|
(quasisyntax/loc stx
|
||||||
(lambda (x)
|
(#%plain-app #,ref-to-w-prime
|
||||||
#`(with-continuation-mark the-cont-key #,w-prime #,x))
|
#,(elim-callcc/mark
|
||||||
#'e)))))]))]
|
(lambda (x)
|
||||||
|
#`(with-continuation-mark the-cont-key #,ref-to-w-prime #,x))
|
||||||
|
#'e)))))))]))]
|
||||||
[(#%plain-app w rest ...)
|
[(#%plain-app w rest ...)
|
||||||
(markit
|
(markit
|
||||||
(quasisyntax/loc stx
|
(quasisyntax/loc stx
|
||||||
|
|
|
@ -34,22 +34,32 @@
|
||||||
(syntax/loc stx
|
(syntax/loc stx
|
||||||
(let-values ([(v ...) ve] ...) be ...)))]
|
(let-values ([(v ...) ve] ...) be ...)))]
|
||||||
[(letrec-values ([(v ...) ve] ...) be ...)
|
[(letrec-values ([(v ...) ve] ...) be ...)
|
||||||
(let ([new-ids (apply append ids (map syntax->list (syntax->list #'((v ...) ...))))])
|
(let ([new-ids (apply append ids (map syntax->list (syntax->list #'((v ...) ...))))]
|
||||||
(with-syntax ([((nv ...) ...) (map (compose generate-temporaries syntax->list) (syntax->list #'((v ...) ...)))]
|
[gfss (map (lambda (vs)
|
||||||
[((nv-box ...) ...) (map (lambda (nvs)
|
(map (lambda (v)
|
||||||
(map (lambda (x) (syntax/loc x (#%plain-app box the-undef)))
|
(define-values (v-def v-ref) (generate-formal (syntax->datum v) v))
|
||||||
(syntax->list nvs)))
|
(cons v-def v-ref))
|
||||||
(syntax->list #`((v ...) ...)))]
|
(syntax->list vs)))
|
||||||
[(ve ...) (map (elim-letrec new-ids) (syntax->list #'(ve ...)))]
|
(syntax->list #'((v ...) ...)))])
|
||||||
[(be ...) (map (elim-letrec new-ids) (syntax->list #'(be ...)))])
|
(with-syntax
|
||||||
; XXX Optimize special case of one nv
|
([((nv-def ...) ...)
|
||||||
|
(map (lambda (gfs) (map car gfs)) gfss)]
|
||||||
|
[((nv-ref ...) ...)
|
||||||
|
(map (lambda (gfs) (map cdr gfs)) gfss)]
|
||||||
|
[((nv-box ...) ...) (map (lambda (nvs)
|
||||||
|
(map (lambda (x) (syntax/loc x (#%plain-app box the-undef)))
|
||||||
|
(syntax->list nvs)))
|
||||||
|
(syntax->list #`((v ...) ...)))]
|
||||||
|
[(ve ...) (map (elim-letrec new-ids) (syntax->list #'(ve ...)))]
|
||||||
|
[(be ...) (map (elim-letrec new-ids) (syntax->list #'(be ...)))])
|
||||||
(syntax/loc stx
|
(syntax/loc stx
|
||||||
(let-values ([(v ...)
|
(let-values ([(v ...)
|
||||||
(#%plain-app values nv-box ...)] ...)
|
(#%plain-app values nv-box ...)] ...)
|
||||||
(begin (#%plain-app call-with-values
|
(begin (#%plain-app call-with-values
|
||||||
(#%plain-lambda () ve)
|
(#%plain-lambda () ve)
|
||||||
(#%plain-lambda (nv ...)
|
(#%plain-lambda
|
||||||
(#%plain-app set-box! v nv) ...))
|
(nv-def ...)
|
||||||
|
(#%plain-app set-box! v nv-ref) ...))
|
||||||
...
|
...
|
||||||
be ...)))))]
|
be ...)))))]
|
||||||
[(#%plain-lambda formals be ...)
|
[(#%plain-lambda formals be ...)
|
||||||
|
|
|
@ -1,130 +0,0 @@
|
||||||
#lang scheme/base
|
|
||||||
(require (for-template scheme/base)
|
|
||||||
syntax/kerncase
|
|
||||||
mzlib/list
|
|
||||||
syntax/toplevel
|
|
||||||
mzlib/plt-match
|
|
||||||
syntax/stx
|
|
||||||
"util.ss")
|
|
||||||
(provide free-vars)
|
|
||||||
|
|
||||||
;; free-vars: syntax -> (listof identifier)
|
|
||||||
;; Find the free variables in an expression
|
|
||||||
(define (free-vars stx)
|
|
||||||
(kernel-syntax-case
|
|
||||||
stx (transformer?)
|
|
||||||
[(begin be ...)
|
|
||||||
(free-vars* (syntax->list #'(be ...)))]
|
|
||||||
[(begin0 be ...)
|
|
||||||
(free-vars* (syntax->list #'(be ...)))]
|
|
||||||
[(set! v ve)
|
|
||||||
(union (free-vars #'v)
|
|
||||||
(free-vars #'ve))]
|
|
||||||
[(let-values ([(v ...) ve] ...) be ...)
|
|
||||||
(union (free-vars* (syntax->list #'(ve ...)))
|
|
||||||
(set-diff (free-vars* (syntax->list #'(be ...)))
|
|
||||||
(apply append (map syntax->list (syntax->list #'((v ...) ...))))))]
|
|
||||||
[(letrec-values ([(v ...) ve] ...) be ...)
|
|
||||||
(set-diff (union (free-vars* (syntax->list #'(ve ...)))
|
|
||||||
(free-vars* (syntax->list #'(be ...))))
|
|
||||||
(apply append (map syntax->list (syntax->list #'((v ...) ...)))))]
|
|
||||||
[(#%plain-lambda formals be ...)
|
|
||||||
(set-diff (free-vars* (syntax->list #'(be ...)))
|
|
||||||
(formals-list #'formals))]
|
|
||||||
[(case-lambda [formals be ...] ...)
|
|
||||||
(apply union*
|
|
||||||
(map (lambda (fs bes)
|
|
||||||
(set-diff (free-vars* (syntax->list bes))
|
|
||||||
(formals-list fs)))
|
|
||||||
(syntax->list #'(formals ...))
|
|
||||||
(syntax->list #'((be ...) ...))))]
|
|
||||||
[(if te ce ae)
|
|
||||||
(free-vars* (syntax->list #'(te ce ae)))]
|
|
||||||
[(quote datum)
|
|
||||||
empty]
|
|
||||||
[(quote-syntax datum)
|
|
||||||
empty]
|
|
||||||
[(with-continuation-mark ke me be)
|
|
||||||
(free-vars* (syntax->list #'(ke me be)))]
|
|
||||||
[(#%plain-app e ...)
|
|
||||||
(free-vars* (syntax->list #'(e ...)))]
|
|
||||||
[(#%top . v)
|
|
||||||
#;(printf "Not including top ~S in freevars~n" (syntax->datum #'v))
|
|
||||||
empty]
|
|
||||||
[(#%variable-reference . id)
|
|
||||||
(let ([i-bdg (identifier-binding #'id)])
|
|
||||||
(cond
|
|
||||||
[(eqv? 'lexical i-bdg)
|
|
||||||
(list #'id)]
|
|
||||||
[(not i-bdg)
|
|
||||||
(list #'id)]
|
|
||||||
[else
|
|
||||||
#;(printf "Not including var-reference ~S with binding ~S in freevars~n" (syntax->datum #'id) i-bdg)
|
|
||||||
empty]))]
|
|
||||||
[id (identifier? #'id)
|
|
||||||
(let ([i-bdg (identifier-binding #'id)])
|
|
||||||
#;(printf "ID ~S with binding ~S in freevars~n" (syntax->datum #'id) i-bdg)
|
|
||||||
(cond
|
|
||||||
[(eqv? 'lexical i-bdg)
|
|
||||||
(list #'id)]
|
|
||||||
[(not i-bdg)
|
|
||||||
(list #'id)]
|
|
||||||
[else
|
|
||||||
#;(printf "Not including id ~S with binding ~S in freevars~n" (syntax->datum #'id) i-bdg)
|
|
||||||
empty]))]
|
|
||||||
[(letrec-syntaxes+values ([(sv ...) se] ...)
|
|
||||||
([(vv ...) ve] ...)
|
|
||||||
be ...)
|
|
||||||
(free-vars #'(letrec-values ([(vv ...) ve] ...) be ...))]
|
|
||||||
[(#%expression d)
|
|
||||||
(free-vars #'d)]
|
|
||||||
[_
|
|
||||||
(raise-syntax-error 'freevars "Dropped through:" stx)]))
|
|
||||||
|
|
||||||
;; free-vars*: (listof expr) -> (listof identifier)
|
|
||||||
;; union the free variables that occur in several expressions
|
|
||||||
(define (free-vars* exprs)
|
|
||||||
(foldl
|
|
||||||
(lambda (expr acc) (union (free-vars expr) acc))
|
|
||||||
empty exprs))
|
|
||||||
|
|
||||||
;; union: (listof identifier) (listof identifier) -> (listof identifier)
|
|
||||||
;; produce the set-theoretic union of two lists
|
|
||||||
(define (union l1 l2)
|
|
||||||
(cond
|
|
||||||
[(null? l1) l2]
|
|
||||||
[else (insert (car l1) (union (cdr l1) l2))]))
|
|
||||||
|
|
||||||
(define (union* . ll)
|
|
||||||
(foldl union
|
|
||||||
empty
|
|
||||||
ll))
|
|
||||||
|
|
||||||
;; insert: symbol (listof identifier) -> (listof symbol)
|
|
||||||
;; insert a symbol into a list without creating a duplicate
|
|
||||||
(define (insert sym into)
|
|
||||||
(unless (identifier? sym)
|
|
||||||
(raise-syntax-error 'insert "Not identifier" sym))
|
|
||||||
(cond
|
|
||||||
[(null? into) (list sym)]
|
|
||||||
[(free-identifier=? sym (car into)) into]
|
|
||||||
[else (cons (car into) (insert sym (cdr into)))]))
|
|
||||||
|
|
||||||
;; set-diff: (listof identifier) (listof identifier) -> (listof identifier)
|
|
||||||
;; produce the set-theoretic difference of two lists
|
|
||||||
(define (set-diff s1 s2)
|
|
||||||
(cond
|
|
||||||
[(null? s2) s1]
|
|
||||||
[else (set-diff (sans s1 (car s2)) (cdr s2))]))
|
|
||||||
|
|
||||||
;; sans: (listof identifier) symbol -> (listof identifier)
|
|
||||||
;; produce the list sans the symbol
|
|
||||||
(define (sans s elt)
|
|
||||||
(unless (identifier? elt)
|
|
||||||
(raise-syntax-error 'sans "Not identifier" elt))
|
|
||||||
(cond
|
|
||||||
[(null? s) empty]
|
|
||||||
[(free-identifier=? (car s) elt)
|
|
||||||
(cdr s)] ;; if we maintain the no-dupe invariant then we don't need to recur
|
|
||||||
[else (cons (car s)
|
|
||||||
(sans (cdr s) elt))]))
|
|
|
@ -27,12 +27,12 @@
|
||||||
(lambda (stx)
|
(lambda (stx)
|
||||||
(datum->syntax stx 'error))))
|
(datum->syntax stx 'error))))
|
||||||
|
|
||||||
(define (generate-formal sym-name)
|
(define (generate-formal sym-name [stx-base #f])
|
||||||
(let ([name (datum->syntax #f (gensym sym-name))])
|
(let ([name (datum->syntax stx-base (gensym sym-name))])
|
||||||
(with-syntax ([(lambda (formal) ref-to-formal)
|
(with-syntax ([(#%plain-lambda (formal) ref-to-formal)
|
||||||
(if (syntax-transforming?)
|
(if (syntax-transforming?)
|
||||||
(local-expand #`(lambda (#,name) #,name) 'expression empty)
|
(local-expand #`(#%plain-lambda (#,name) #,name) 'expression empty)
|
||||||
#`(lambda (#,name) #,name))])
|
#`(#%plain-lambda (#,name) #,name))])
|
||||||
(values #'formal #'ref-to-formal))))
|
(values #'formal #'ref-to-formal))))
|
||||||
|
|
||||||
(define (formals-list stx)
|
(define (formals-list stx)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user