From 8437d4e13761623bed6a35858393c5eb2ce7662a Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Mon, 2 May 2016 23:47:50 -0400 Subject: [PATCH] Issue #40 - Allow splicing of library begin defs Allow definitions contained in a top-level define to be spliced into the same scope as the define. There is also a performance hack to force compiled macros when compiling (scheme base). That code may need to be revisited, although perhaps not because the only compiled macros are the ones that are provided directly by cyclone. User code will not contain them. --- cyclone.scm | 22 +++++++++++---------- scheme/cyclone/transforms.sld | 37 +++++++++++++++++++---------------- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/cyclone.scm b/cyclone.scm index 7505ad5d..1962c33b 100644 --- a/cyclone.scm +++ b/cyclone.scm @@ -144,21 +144,23 @@ (macro:load-env! *defined-macros* (create-environment '() '())) ;; Expand macros - ; New code, does not compile scheme/base.sld yet: + ;; In each case, the input is expanded in a way that ensures + ;; defines from any top-level begins are spliced correctly. (set! input-program (cond (program? (expand-lambda-body input-program (macro:get-env))) (else - (lambda->exp (car - (expand `(begin ,@input-program) (macro:get-env))))))) - ; Old code, works - ;(set! input-program - ; ((if program? - ; expand-lambda-body - ; expand) - ; input-program - ; (macro:get-env))) + (let ((expanded (expand `(begin ,@input-program) + (macro:get-env)))) + (cond + ((and (pair? expanded) + (tagged-list? 'lambda (car expanded))) + (lambda->exp (car expanded))) + ((tagged-list? 'define expanded) + (list expanded)) + (else + (error `(Unhandled expansion ,expanded)))))))) (trace:info "---------------- after macro expansion:") (trace:info input-program) ;pretty-print diff --git a/scheme/cyclone/transforms.sld b/scheme/cyclone/transforms.sld index ac19c241..a8f5d06b 100644 --- a/scheme/cyclone/transforms.sld +++ b/scheme/cyclone/transforms.sld @@ -801,23 +801,26 @@ `(define-syntax ,name ,(expand trans env)) env)) (else - (set! *defined-macros* (cons (cons name body) *defined-macros*)) - ;; Keep track of macros added during compilation. - ;; Previous list should eventually go away once macros are - ;; moved from that static list to libraries - (macro:add! name body) - (env:define-variable! name (list 'macro body) env) - ;; Keep as a 'define' form so available at runtime - ;; TODO: may run into issues with expanding now, before some - ;; of the macros are defined. may need to make a special pass - ;; to do loading or expansion of macro bodies - ;; TODO: would it be better to use *define-macros* directly instead - ;; of trying to define it here? that might help prevent issues where - ;; an expand is called here before all macros are defined yet - ;; - no, we need to do this here so code is carried though all transforms - ;; (alpha, cps, closure, etc). otherwise code has to be interpreted during expansion - ;; - `(define ,name ,(expand body env)))))) + ;; TODO: for now, do not let a compiled macro be re-defined. + ;; this is a hack for performance compiling (scheme base) + (let ((macro (env:lookup name env #f))) + (cond + ((and (tagged-list? 'macro macro) + (or (macro? (Cyc-get-cvar (cadr macro))) + (procedure? (cadr macro)))) + (trace:info `(DEBUG compiled macro ,name do not redefine))) + (else + ;; Use this to keep track of macros for filtering unused defines + (set! *defined-macros* (cons (cons name body) *defined-macros*)) + ;; Keep track of macros added during compilation. + ;; TODO: why in both places? + (macro:add! name body) + (env:define-variable! name (list 'macro body) env))) + ;; Keep as a 'define' form so available at runtime + ;; TODO: may run into issues with expanding now, before some + ;; of the macros are defined. may need to make a special pass + ;; to do loading or expansion of macro bodies + `(define ,name ,(expand body env))))))) ((app? exp) (cond ((symbol? (car exp))