From 8309025e187c3e0f0f8fda6933dfdd89dc17ae1d Mon Sep 17 00:00:00 2001 From: WillClinger Date: Mon, 3 Jul 2017 09:03:33 -0400 Subject: [PATCH] Libraries now invoked only once under all circumstances (ticket #655). --- lib/R6RS/r6rs-expander.sch | 30 +++++++++++++++++++++++------- lib/R6RS/r6rsmode.sch | 17 +---------------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/lib/R6RS/r6rs-expander.sch b/lib/R6RS/r6rs-expander.sch index cac51757..12e01308 100644 --- a/lib/R6RS/r6rs-expander.sch +++ b/lib/R6RS/r6rs-expander.sch @@ -2876,16 +2876,32 @@ ;; For importing and evaluating stuff in the persistent ;; interactive environment, see REPL above. - ;; FIXME: Since expand-toplevel-sequence calls eval on every - ;; library in the sequence, the following procedure calls eval - ;; on every library twice. That can double the compile time. - + ;; NOTE: expand-toplevel-sequence calls eval on every library + ;; in the sequence. (It calls scan-sequence, which calls + ;; expand-library, which calls expand-library-or-program, + ;; which calls eval on the expanded library.) That's why + ;; run-r6rs-sequence calls eval only on the expressions + ;; obtained by expanding the program, if present. + ;; See ticket #655. + (define (run-r6rs-sequence forms) (with-toplevel-parameters (lambda () - (for-each (lambda (exp) (eval exp (interaction-environment))) - (expand-toplevel-sequence (normalize forms)))))) - + (let* ((forms (normalize forms))) + (call-with-values + (lambda () + (partition (lambda (form) + (and (pair? form) + (eq? 'program (car form)))) + forms)) + (lambda (pgms libs) + (expand-toplevel-sequence libs) + (if (not (null? pgms)) + (let* ((exps (expand-toplevel-sequence pgms))) + (for-each (lambda (exp) + (eval exp (interaction-environment))) + exps))))))))) + (define (run-r6rs-program filename) (run-r6rs-sequence (read-file filename))) diff --git a/lib/R6RS/r6rsmode.sch b/lib/R6RS/r6rsmode.sch index a7d694e4..05567684 100644 --- a/lib/R6RS/r6rsmode.sch +++ b/lib/R6RS/r6rsmode.sch @@ -441,26 +441,11 @@ ; loaded by load-r6rs-program. The target-filename can be ; compiled before it is loaded. ; -; FIXME: This uses a hack to avoid compiling a library twice -; in systems that compile on eval. If the file contains only -; one library, and nothing else, then we can compile to a file -; and then load the file instead of calling eval on the result -; of expansion. That doesn't work if the file contains two -; libraries and the second one imports from the first. -; ; FIXME: The io here should be protected against errors. (define (expand-r6rs-program filename target-filename) (larceny:load-r6rs-package) - (let ((nlibs (call-with-input-file - filename - (lambda (in) - (do ((x (read in) (read in)) - (n 0 (if (pair? x) (+ n 1) n))) - ((or (eof-object? x) (> n 1)) - n)))))) - (parameterize ((larceny:r6rs-expand-only (= nlibs 1))) - (ex:expand-file filename target-filename)))) + (ex:expand-file filename target-filename)) ; This parameter determines whether expanded libraries ; and programs are evaluated immediately, as in van Tonder's