* [PATCH] Compile in a fresh module by default
@ 2009-08-17 20:41 Ludovic Courtès
2009-09-20 22:44 ` Ludovic Courtès
0 siblings, 1 reply; 6+ messages in thread
From: Ludovic Courtès @ 2009-08-17 20:41 UTC (permalink / raw)
To: guile-devel
[-- 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
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] Compile in a fresh module by default
2009-08-17 20:41 [PATCH] Compile in a fresh module by default Ludovic Courtès
@ 2009-09-20 22:44 ` Ludovic Courtès
2009-10-14 2:26 ` Julian Graham
0 siblings, 1 reply; 6+ messages in thread
From: Ludovic Courtès @ 2009-09-20 22:44 UTC (permalink / raw)
To: guile-devel
Hello!
ludo@gnu.org (Ludovic Courtès) writes:
> The attached patch makes `compile' and friends use fresh module rather
> than the current module as the default compile-time environment.
I committed a slightly modified version in
87c595c757b7db84ffdcfda96f736ab235e674a8.
Thanks,
Ludo’.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] Compile in a fresh module by default
2009-09-20 22:44 ` Ludovic Courtès
@ 2009-10-14 2:26 ` Julian Graham
2009-10-14 8:11 ` Ludovic Courtès
0 siblings, 1 reply; 6+ messages in thread
From: Julian Graham @ 2009-10-14 2:26 UTC (permalink / raw)
To: Ludovic Courtès; +Cc: guile-devel
Hi Ludovic,
Naive question (and I realize I'm a bit late here): What if there are
bindings in the current module that need to be present for expansion
and compilation to succeed? I ask because I'm working on a macro that
transforms R6RS library expressions, which contain nested `define'
calls, into Guile modules. My code rewrites these defines as location
declarations that get exported as part of a module interface (at
least, in theory -- right now it just erases them).
When I bind my `library' macro in the REPL after building from the
current HEAD of master and then load and compile a source file
containing an R6RS library form, I get a syncase error during
compilation about defines in expression context; when I revert the
effects of this patch, the error goes away.
Regards,
Julian
2009/9/20 Ludovic Courtès <ludo@gnu.org>:
> Hello!
>
> ludo@gnu.org (Ludovic Courtès) writes:
>
>> The attached patch makes `compile' and friends use fresh module rather
>> than the current module as the default compile-time environment.
>
> I committed a slightly modified version in
> 87c595c757b7db84ffdcfda96f736ab235e674a8.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] Compile in a fresh module by default
2009-10-14 2:26 ` Julian Graham
@ 2009-10-14 8:11 ` Ludovic Courtès
2009-10-15 9:42 ` Andy Wingo
0 siblings, 1 reply; 6+ messages in thread
From: Ludovic Courtès @ 2009-10-14 8:11 UTC (permalink / raw)
To: Julian Graham; +Cc: guile-devel
Hi Julian,
Julian Graham <joolean@gmail.com> writes:
> Naive question (and I realize I'm a bit late here): What if there are
> bindings in the current module that need to be present for expansion
> and compilation to succeed?
Just specify ‘(compile EXP #:env (current-module))’. This is what
‘repl-compile’ in ‘(system repl common)’ does, so that one can define
macros at the REPL and actually use them.
> I ask because I'm working on a macro that transforms R6RS library
> expressions, which contain nested `define' calls, into Guile modules.
> My code rewrites these defines as location declarations that get
> exported as part of a module interface (at least, in theory -- right
> now it just erases them).
Can you give an example of the macro transformation?
> When I bind my `library' macro in the REPL after building from the
> current HEAD of master and then load and compile a source file
> containing an R6RS library form, I get a syncase error during
> compilation about defines in expression context; when I revert the
> effects of this patch, the error goes away.
Can you post a simplified example that reproduces the problem?
Thanks,
Ludo’.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] Compile in a fresh module by default
2009-10-14 8:11 ` Ludovic Courtès
@ 2009-10-15 9:42 ` Andy Wingo
2009-10-15 11:51 ` Ludovic Courtès
0 siblings, 1 reply; 6+ messages in thread
From: Andy Wingo @ 2009-10-15 9:42 UTC (permalink / raw)
To: Ludovic Courtès; +Cc: guile-devel
On Wed 14 Oct 2009 10:11, ludo@gnu.org (Ludovic Courtès) writes:
>> I ask because I'm working on a macro that transforms R6RS library
>> expressions, which contain nested `define' calls, into Guile modules.
>> My code rewrites these defines as location declarations that get
>> exported as part of a module interface (at least, in theory -- right
>> now it just erases them).
>
> Can you give an example of the macro transformation?
(define-syntax foo ...)
(load "file-that-needs-foo")
The load needs to be done relative to the current module, which it is --
unless it's autocompiling, in which case we go through the autocompile
case in boot-9.scm:924 (not the one in load.c), which is missing an
#:env (current-module).
Probably needs to be fixed before today's release.
Andy
--
http://wingolog.org/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] Compile in a fresh module by default
2009-10-15 9:42 ` Andy Wingo
@ 2009-10-15 11:51 ` Ludovic Courtès
0 siblings, 0 replies; 6+ messages in thread
From: Ludovic Courtès @ 2009-10-15 11:51 UTC (permalink / raw)
To: Andy Wingo; +Cc: guile-devel
Andy Wingo <wingo@pobox.com> writes:
> (define-syntax foo ...)
> (load "file-that-needs-foo")
>
> The load needs to be done relative to the current module, which it is --
> unless it's autocompiling, in which case we go through the autocompile
> case in boot-9.scm:924 (not the one in load.c), which is missing an
> #:env (current-module).
>
> Probably needs to be fixed before today's release.
Yes indeed.
Thanks,
Ludo'.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2009-10-15 11:51 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-17 20:41 [PATCH] Compile in a fresh module by default Ludovic Courtès
2009-09-20 22:44 ` 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
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).