summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--stdlib/compiler.tl26
-rw-r--r--txr.164
2 files changed, 64 insertions, 26 deletions
diff --git a/stdlib/compiler.tl b/stdlib/compiler.tl
index 504d3ea8..c5d00612 100644
--- a/stdlib/compiler.tl
+++ b/stdlib/compiler.tl
@@ -2609,15 +2609,17 @@
(@else (error "~s: cannot compile ~s" 'compile else))))
(defmacro usr:with-compile-opts (:form form . clauses)
- (with-gensyms (co)
- ^(let* ((,co (copy *compile-opts*))
- (*compile-opts* ,co))
- ,*(collect-each ((cl clauses))
- (match-case cl
- ((@(as op @(or nil t :warn :error)) . @syms)
- (each ((s syms))
- (unless (member s %warning-syms%)
- (compile-error form "~s isn't a recognized warning option" s)))
- ^(set ,*(mappend (ret ^((qref ,co ,@1) ,op)) syms)))
- (@(or @(atom) (@(not @(keywordp)) . @nil)) cl)
- (@nil (compile-error form "unrecognized clause syntax: ~s" cl)))))))
+ (match-case clauses
+ (() ())
+ (((@(as op @(or nil t :warn :error)) . @syms) . @rest)
+ (each ((s syms))
+ (unless (member s %warning-syms%)
+ (compile-error form
+ "~s isn't a recognized warning option" s)))
+ ^(compiler-let ((*compile-opts* (let ((co (copy *compile-opts*)))
+ (set ,*(mappend (ret ^(co.,@1 ,op))
+ syms))
+ co)))
+ ,*(if rest ^((with-compile-opts ,*rest)))))
+ ((@first . @rest)
+ ^(progn ,first ,*(if rest ^((with-compile-opts ,*rest)))))))
diff --git a/txr.1 b/txr.1
index e8cbfc60..b18b529f 100644
--- a/txr.1
+++ b/txr.1
@@ -88166,27 +88166,52 @@ The
macro takes zero or more arguments. Each argument is either a clause
which affects compiler options or else an ordinary
.meta form
-which is evaluated in a context in which the
+which is processed in a context in which the
.code *compile-options*
variable has been affected by all of the previous clauses.
-The
+It is unspecified whether the clauses operate destructively on
+.code *compile-options*
+or freshly bind it. However, the macro dynamically binds
+.code *compile-options*
+at least once, so that when it terminates, its previous value is restored.
+This binding is performed using
+.codn compiler-let .
+
+When
.code with-compile-opts
-macro arranges for
+occurs in code processed by the compiler, all of the clause-driven compile
+option manipulation is performed in the compiler's own context. The changes
+to the
.code *compile-options*
-to be freshly bound, as if by the
-.code let
-operator. The variable is then given a value which is a copy of the
-previous binding.
-The option-affecting clauses then operate destructively on this copy.
-When the macro terminates, the binding is undone and thus the
-prior value of
+variable are not visible to the code being compiled. Thus the macro may be
+used to transparently change compiler options over individual subexpressions in
+compiled code.
+
+When
+.code with-compile-opts
+occurs in interpreted code, the manipulations of
.code *compile-options*
-is restored.
+are visible to the
+.metn form s.
+This allows interpreted build steps to configure compiler options
+around functions such as
+.codn compile-file .
-The clauses which operate on options have the syntax of a value followed by one
-or more symbols which must be the names of options which are compatible with
-that value. The clause indicates that all those options take on that value.
+The clauses which operate on options have list syntax consisting of a value
+followed by one or more symbols which must be the names of options which are
+compatible with that value. The clause indicates that all those options take on
+that value.
+
+The possible values are:
+.codn nil ,
+.codn t ,
+.code :warn
+and
+.codn :error .
+These values are documented under the description of the
+.code compile-opts
+structure.
.TP* Example:
@@ -88198,12 +88223,23 @@ treated as error, but unused variable checking disabled. Then compile
with unused variable checking enabled.
.verb
+ ;; this form must be interpreted in order for
+ ;; the compile-file call to "see" the effect of the
+ ;; option manipulation.
(with-compile-opts
(:error shadow-var shadow-fun)
(nil unused)
(compile-file "foo.tl")
(:warn unused)
(compile-file "bar.tl"))
+
+ ;; when the following form is compiled, the unused
+ ;; variable warning will be disabled just around
+ ;; the (let (y) x).
+ (lambda (x)
+ (with-compile-opts (nil unused)
+ (let (y) x)))
+
.brev
.coNP Operator @ compiler-let