From d0772c2238af0261bb5f928b3446ece6fc4dfb12 Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Fri, 6 Oct 2017 18:43:30 -0400 Subject: [PATCH] Allow a program to have macros expand into a top-level `import` expression. --- CHANGELOG.md | 6 ++++++ cyclone.scm | 43 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20f72d84..5cf13d09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.7 - TBD + +Features + +- Allow a program to have macros expand into a top-level `import` expression. + ## 0.6.3 - September 16, 2017 Features diff --git a/cyclone.scm b/cyclone.scm index e226f4d5..68fdc262 100644 --- a/cyclone.scm +++ b/cyclone.scm @@ -29,7 +29,7 @@ ; c-compile-and-emit : (string -> A) exp -> void (define (c-compile-and-emit input-program program:imports/code - lib-deps src-file append-dirs prepend-dirs) + lib-deps change-lib-deps! src-file append-dirs prepend-dirs) (call/cc (lambda (return) (define globals '()) @@ -173,6 +173,36 @@ (trace:info "---------------- after macro expansion cleanup:") (trace:info input-program) ;pretty-print + ;; If a program, check to see if any macros expanded into top-level imports + (when program? + (let ((program:imports/code (import-reduction input-program (base-expander)))) + (when (not (null? (car program:imports/code))) +;(trace:info "debug") +;(trace:info program:imports/code) + (trace:info "-------------- macro expanded into import expression(s):") + (set! imports (append imports (car program:imports/code))) + (trace:info "imports:") + (trace:info imports) + (set! imported-vars (lib:imports->idb imports append-dirs prepend-dirs)) + (trace:info "resolved imports:") + (trace:info imported-vars) + (let ((meta (lib:resolve-meta imports append-dirs prepend-dirs))) + (set! *defined-macros* (append meta *defined-macros*)) + (trace:info "resolved macros:") + (trace:info meta)) + (set! input-program (cdr program:imports/code)) + ;(set! lib-deps (append lib-deps (lib:get-all-import-deps (car program:imports/code) append-dirs prepend-dirs))) + (let ((new-lib-deps (lib:get-all-import-deps (car program:imports/code) append-dirs prepend-dirs))) + (for-each + (lambda (dep) + (if (not (member dep lib-deps)) + (set! lib-deps (cons dep lib-deps)))) + new-lib-deps) + (change-lib-deps! lib-deps)) + (trace:info lib-deps) + ))) + ;; END additional top-level imports + ;; Separate global definitions from the rest of the top-level code (set! input-program (isolate-globals input-program program? lib-name rename-env)) @@ -531,8 +561,15 @@ (with-output-to-file src-file (lambda () - (c-compile-and-emit program program:imports/code - lib-deps in-file append-dirs prepend-dirs))))) + (c-compile-and-emit + program + program:imports/code + lib-deps + (lambda (new-lib-deps) + (set! lib-deps new-lib-deps)) + in-file + append-dirs + prepend-dirs))))) (result (create-c-file in-prog))) ;; Compile the generated C file