Converting simply.scm to simply-scheme.ss. Danny Yoo (dyoo@hkn.eecs.berkeley.edu) There are two classes of names in simply.scm: 1. Defined and set!-ed names that don't collide with any of the existing definitions in mzscheme. 2. Defined and set!-ed names that do collide with existing definitions in mzscheme. Class 2 presents a big problem when we want to convert simply.scm to a mzscheme Module, because we're not allowed to re-define or re-set! a name from our initial import. We need to somehow transform all the names from Class 2 to Class 1. We can simplify the problem by reducing all the expressions to mzscheme primitive syntax, by using: (syntax-object->datum (expand expr)) which means that the resulting datums will have a nice simple form: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; top-level-expr is one of general-top-level-expr (module identifier name (#%plain-module-begin module-level-expr ...)) (begin top-level-expr ...) module-level-expr is one of general-top-level-expr (provide provide-spec ...) (begin module-level-expr ...) general-top-level-expr is one of expr (define-values (variable ...) expr) (define-syntaxes (variable ...) expr) (require require-spec ...) (require-for-syntax require-spec ...) expr is one of variable (lambda formals expr ...1) (case-lambda (formals expr ...1) ...) (if expr expr) (if expr expr expr) (begin expr ...1) (begin0 expr expr ...) (let-values (((variable ...) expr) ...) expr ...1) (letrec-values (((variable ...) expr) ...) expr ...1) (set! variable expr) (quote datum) (quote-syntax datum) (with-continuation-mark expr expr expr) (#%app expr ...1) (#%datum . datum) (#%top . variable) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (This comes from http://download.plt-scheme.org/doc/209/html/mzscheme/mzscheme-Z-H-12.html#node_sec_12.6.1) So here's a plan to convert simply.scm to simply-scheme.ss: 1. Collect list of all variables names created with define-values, as well as the free variables assigned by set!. Let's define this as our renamed-variables. Once we have this set, we create new defined variables with the appropriate prefixes. For example, if we know that number->string is free, then we'll add the following to our prologue: (define simply-scheme:number->string number->string) TODO: we don't know off-hand which variable names are really primitive. Is there a good way of finding this out? 2. Transform all define-values to set!'s. For example: (define-values (number->string) (let ((old-ns number->string) (string? string?)) (lambda args (if (string? (car args)) (car args) (apply old-ns args))))) is translated to: (set! number->string (let ((old-ns number->string) (string? string?)) (lambda args (if (string? (car args)) (car args) (apply old-ns args))))) 3. Transform all references to free variables, as well as set!'s, to the renamed-vars. For example: (set! simply-scheme:number->string (let ((old-ns simply-scheme:number->string) (string? string?)) (lambda args (if (string? (car args)) (car args) (apply old-ns args))))) 4. Finally, add an epilogue that remaps the renamed-vars back to their original free names. For example: (provide (rename simply-scheme:number->string number->string)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; I also had to manually add a reference to trace.ss to provide TRACE and UNTRACE. I modified simply-scheme.ss manually with the following: (require (lib "trace.ss")) in the prologue, and (provide (all-from (lib "trace.ss"))) in the epilogue.