Incorporated mflatt's magical suggestion for namespace construction; repl compilation should be fast now.

This commit is contained in:
Danny Yoo 2013-02-28 16:35:32 -07:00
parent 374703cb4e
commit cb2aea9e5a
2 changed files with 31 additions and 16 deletions

View File

@ -64,3 +64,4 @@
(syntax/loc stx (syntax/loc stx
(define-struct id (fields ...) new-options ...))))])) (define-struct id (fields ...) new-options ...))))]))

View File

@ -1,28 +1,42 @@
#lang racket/base #lang racket/base
(provide repl-compile)
(define this-namespace (make-base-empty-namespace)) (define this-namespace (make-base-empty-namespace))
(define (make-repl-namespace [module-path 'racket/base]) ;; Somewhat magical.
;; See: http://lists.racket-lang.org/users/archive/2013-February/056664.html.
(define make-fresh-namespace
(eval '(lambda ()
(variable-reference->empty-namespace
(#%variable-reference)))
(make-base-namespace)))
;; make-repl-namespace: [module-path] -> namespace
;; Creates a clean namespace for the given module path.
;;
;; Note that we cache prior instantiations of the language
;; to speed up construction of the namespace,
;; so don't let people call make-repl-namespace with arbitrary values.
(define (make-repl-namespace [language-module-path 'racket/base])
(parameterize ([current-namespace this-namespace]) (parameterize ([current-namespace this-namespace])
(dynamic-require module-path 0)) (dynamic-require language-module-path 0))
(define ns (make-empty-namespace)) (define ns (make-fresh-namespace))
(parameterize ([current-namespace ns]) (parameterize ([current-namespace ns])
(namespace-attach-module this-namespace module-path) (namespace-attach-module this-namespace language-module-path)
(namespace-require/copy module-path)) (namespace-require language-module-path))
ns) ns)
(define memoized-table (make-weak-hash)) ;; repl-compile: any [#:lang module-path] -> compiled-bytecode
(define (repl-compile body #:lang [module-path 'racket/base]) ;; Compiles the given body in a toplevel context under the given language.
(define key (cons body module-path)) (define (repl-compile body #:lang [language-module-path 'racket/base])
(hash-ref memoized-table key (lambda () (parameterize ([current-namespace (make-repl-namespace language-module-path)])
(parameterize ([current-namespace (make-repl-namespace module-path)]) (compile body)))
(define compiled (compile body))
(hash-set! memoized-table key compiled)
compiled))))
(for ([i 10]) ;(for ([i 10])
(time (repl-compile '(* x 3) #:lang 'whalesong/lang/whalesong)) ; (time (repl-compile '(* x 3) #:lang 'whalesong/lang/whalesong))
(time (repl-compile '(/ x 3) #:lang 'whalesong/lang/whalesong))) ; (time (repl-compile '(/ x 3) #:lang 'whalesong/lang/whalesong)))