;; Runtime compilation. ;; Since the core compositional language is implemented as a set of ;; macros, run-time compilation needs 'eval' and a namespace which ;; contains the compiler macros. (module rpn-eval mzscheme (require "rep.ss") (provide rpn-modules rpn-compile) ;; FIXME: Unfortunately, I can't get it to work properly with an ;; isolated namespace, so I just dump everything in the current ;; one. Since the modules used don't export anything else than the ;; compiler macros, this should be OK. If an isolated namespace is ;; necessary, use a sandbox or load (dynamic-require) the brood ;; modules in a separate namespace. (define *compilers* (current-namespace) ;;(make-namespace) ) ;; We postpone the dynamic require until the first rpn-eval is ;; executed, to prevent circular module loading, and collect module ;; names here. (define *modules* '()) (define (in-compilers thunk) (parameterize ((current-namespace *compilers*)) (thunk))) (define (rt-require) (in-compilers (lambda () (for-each (lambda (the-module) ;; (printf "rpn-eval: ~a\n" the-module) (dynamic-require the-module #f) (namespace-require the-module)) *modules*))) (set! *modules* '())) (define (rpn-modules . args) (set! *modules* (append args *modules*))) (define (rpn-compile src compiler) (in-compilers (lambda () (if (not (list? src)) (error 'src-not-a-list "rpn-compile: ~a ~a" src compiler)) (rt-require) (let* ((compiled (compile `(,compiler ,@src))) (evaled (eval compiled))) (unless (word? evaled) (error 'rpn-compile-not-a-word "~a" evaled)) (word-dynamic! evaled #t) ;; This is no longer used: all run time compilation saves ;; source code before it is compiled. Compilation itself is ;; fast enough. ;; (word-compiled! evaled compiled) evaled)))) )