From: ludo@gnu.org (Ludovic Courtès)
To: guile-devel@gnu.org
Subject: [PATCH] Compile in a fresh module by default
Date: Mon, 17 Aug 2009 22:41:00 +0200 [thread overview]
Message-ID: <87ws52i36r.fsf@gnu.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 556 bytes --]
Hello Guilers!
The attached patch makes `compile' and friends use fresh module rather
than the current module as the default compile-time environment.
The intent is to make sure macro definitions and side-effects made at
expansion time do not (to some extents) clutter the current module's
name space.
However, assignments to global variables made at expansion time do have
a visible effect on the running system. This is because the compiler
and "compilee" share the whole module hierarchy, down to the pre-module
obarray.
Comments?
Thanks,
Ludo'.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: the patch --]
[-- Type: text/x-patch, Size: 6010 bytes --]
From 8879fa894377fc062f30358eb428c5ec757c43ab Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Ludovic=20Court=C3=A8s?= <ludo@gnu.org>
Date: Fri, 14 Aug 2009 19:30:14 +0200
Subject: [PATCH 1/2] Compile in a fresh module by default.
* module/system/base/compile.scm (make-compilation-module,
language-default-environment): New procedures.
(read-and-compile, compile): Have ENV default to
`(language-default-environment from)'.
(compile-and-load): Compile in `(current-module)'.
* test-suite/tests/compiler.test ("psyntax")["compile uses a fresh module by
default", "compile-time definitions are isolated"]: New tests.
["compile in current module"]: Specify `#:env (current-module)'.
["redefinition"]: Adjust.
* test-suite/tests/bytevectors.test (c&e): Explicitly compile in the
current module so that its imports are visible.
---
module/system/base/compile.scm | 26 +++++++++++++++++++++++---
test-suite/tests/bytevectors.test | 5 +++--
test-suite/tests/compiler.test | 31 ++++++++++++++++++++++---------
3 files changed, 48 insertions(+), 14 deletions(-)
diff --git a/module/system/base/compile.scm b/module/system/base/compile.scm
index 8470f39..f3557cb 100644
--- a/module/system/base/compile.scm
+++ b/module/system/base/compile.scm
@@ -158,7 +158,8 @@
(define* (compile-and-load file #:key (from 'scheme) (to 'value) (opts '()))
(read-and-compile (open-input-file file)
- #:from from #:to to #:opts opts))
+ #:from from #:to to #:opts opts
+ #:env (current-module)))
\f
;;;
@@ -187,6 +188,23 @@
(else
(lp (cdr in) (caar in))))))
+(define (make-compilation-module)
+ "Return a fresh module to be used as the compilation environment."
+
+ ;; Ideally we'd duplicate the whole module hierarchy so that `set!',
+ ;; `fluid-set!', etc. don't have any effect in the current environment.
+
+ (let ((m (make-module)))
+ (beautify-user-module! m)
+ m))
+
+(define (language-default-environment lang)
+ "Return the default compilation environment for source language LANG."
+ (if (or (eq? lang 'scheme)
+ (eq? lang (lookup-language 'scheme)))
+ (make-compilation-module)
+ #f))
+
(define* (read-and-compile port #:key
(env #f)
(from (current-language))
@@ -196,7 +214,8 @@
(to (ensure-language to)))
(let ((joint (find-language-joint from to)))
(with-fluids ((*current-language* from))
- (let lp ((exps '()) (env #f) (cenv env))
+ (let lp ((exps '()) (env #f)
+ (cenv (or env (language-default-environment from))))
(let ((x ((language-reader (current-language)) port)))
(cond
((eof-object? x)
@@ -225,7 +244,8 @@
warnings))))
(receive (exp env cenv)
- (compile-fold (compile-passes from to opts) x env opts)
+ (let ((env (or env (language-default-environment from))))
+ (compile-fold (compile-passes from to opts) x env opts))
exp))
\f
diff --git a/test-suite/tests/bytevectors.test b/test-suite/tests/bytevectors.test
index 8b336bb..c0f5196 100644
--- a/test-suite/tests/bytevectors.test
+++ b/test-suite/tests/bytevectors.test
@@ -31,12 +31,13 @@
(begin (pass-if (string-append test-name " (eval)")
(primitive-eval 'exp))
(pass-if (string-append test-name " (compile)")
- (compile 'exp #:to 'value))))
+ (compile 'exp #:to 'value #:env (current-module)))))
((_ (pass-if-exception test-name exc exp))
(begin (pass-if-exception (string-append test-name " (eval)")
exc (primitive-eval 'exp))
(pass-if-exception (string-append test-name " (compile)")
- exc (compile 'exp #:to 'value))))))
+ exc (compile 'exp #:to 'value
+ #:env (current-module)))))))
(define-syntax with-test-prefix/c&e
(syntax-rules ()
diff --git a/test-suite/tests/compiler.test b/test-suite/tests/compiler.test
index f9fabd7..2eb0e78 100644
--- a/test-suite/tests/compiler.test
+++ b/test-suite/tests/compiler.test
@@ -30,18 +30,23 @@
\f
(with-test-prefix "psyntax"
- (pass-if "redefinition"
- ;; In this case the locally-bound `round' must have the same value as the
- ;; imported `round'. See the same test in `syntax.test' for details.
+ (pass-if "compile uses a fresh module by default"
+ (begin
+ (compile '(define + -))
+ (eq? (compile '+) +)))
+
+ (pass-if "compile-time definitions are isolated"
(begin
- (compile '(define round round))
- (compile '(eq? round (@@ (guile) round)))))
+ (compile '(define foo-bar #t))
+ (not (module-variable (current-module) 'foo-bar))))
(pass-if "compile in current module"
(let ((o (begin
- (compile '(define-macro (foo) 'bar))
- (compile '(let ((bar 'ok)) (foo))))))
- (and (module-ref (current-module) 'foo)
+ (compile '(define-macro (foo) 'bar)
+ #:env (current-module))
+ (compile '(let ((bar 'ok)) (foo))
+ #:env (current-module)))))
+ (and (macro? (module-ref (current-module) 'foo))
(eq? o 'ok))))
(pass-if "compile in fresh module"
@@ -52,4 +57,12 @@
(compile '(define-macro (foo) 'bar) #:env m)
(compile '(let ((bar 'ok)) (foo)) #:env m))))
(and (module-ref m 'foo)
- (eq? o 'ok)))))
+ (eq? o 'ok))))
+
+ (pass-if "redefinition"
+ ;; In this case the locally-bound `round' must have the same value as the
+ ;; imported `round'. See the same test in `syntax.test' for details.
+ (let ((m (make-module)))
+ (beautify-user-module! m)
+ (compile '(define round round) #:env m)
+ (eq? round (module-ref m 'round)))))
--
1.6.1.3
next reply other threads:[~2009-08-17 20:41 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-17 20:41 Ludovic Courtès [this message]
2009-09-20 22:44 ` [PATCH] Compile in a fresh module by default Ludovic Courtès
2009-10-14 2:26 ` Julian Graham
2009-10-14 8:11 ` Ludovic Courtès
2009-10-15 9:42 ` Andy Wingo
2009-10-15 11:51 ` Ludovic Courtès
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87ws52i36r.fsf@gnu.org \
--to=ludo@gnu.org \
--cc=guile-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).