summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-04-19 07:23:47 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-04-19 07:23:47 -0700
commit39f9e7f49d5f1c6fa699f182f0488fd66568dac2 (patch)
treee5432da40b2175742b3a1b62feb0ed7adb550109
parentd631db74c3a572a893f6ffd4de368431bfae9a28 (diff)
downloadtxr-39f9e7f49d5f1c6fa699f182f0488fd66568dac2.tar.gz
txr-39f9e7f49d5f1c6fa699f182f0488fd66568dac2.tar.bz2
txr-39f9e7f49d5f1c6fa699f182f0488fd66568dac2.zip
compile/eval: print compiler error on *stderr*.
* share/txr/stdlib/error.tl (compile-error): Print the error message on *stderr*, like we do with warnings. This allows the programming environment to pick up the error message and navigate to that line accordingly. The error message is also output by the unhandled exception logic but with a prefix that prevents parsing by the tooling. To avoid sending double error messages to the interactive user, we only issue the *stderr* message if *load-recursive* is true. * tests/common.tl (macro-time-let): New macro. This lets us bind special variables around the macro-expansion of the body, which is useful when expansion-time logic reacts to values of special variables. * tests/012/ifa.tl: Use macro-time-let to suppress *stderr* around the expansion of the erroneous ifa form. We now needs this because the error situation spits out a message on *stderr*, in addition to throwing.
-rw-r--r--share/txr/stdlib/error.tl5
-rw-r--r--tests/012/ifa.tl3
-rw-r--r--tests/common.tl7
3 files changed, 13 insertions, 2 deletions
diff --git a/share/txr/stdlib/error.tl b/share/txr/stdlib/error.tl
index 42d5d6b9..a7885c3f 100644
--- a/share/txr/stdlib/error.tl
+++ b/share/txr/stdlib/error.tl
@@ -39,7 +39,10 @@
(loc (sys:loc nctx))
(name (sys:ctx-name nctx)))
(dump-deferred-warnings *stderr*)
- (throwf 'eval-error `@loc: ~s: @fmt` name . args)))
+ (let ((msg (fmt `@loc: ~s: @fmt` name . args)))
+ (when *load-recursive*
+ (put-line msg *stderr*))
+ (throw 'eval-error msg))))
(defun compile-warning (ctx fmt . args)
(let* ((nctx (sys:dig ctx))
diff --git a/tests/012/ifa.tl b/tests/012/ifa.tl
index 45a2939b..05b47ab3 100644
--- a/tests/012/ifa.tl
+++ b/tests/012/ifa.tl
@@ -14,7 +14,8 @@
(test (let ((x 1) (y 0)) (ifa (> x y) it)) 1)
;; multiple it-candidates: error
-(test (let (x y) (ifa (> (* x x) (* y y)) it)) :error)
+(macro-time-let ((*stderr* *stdnull*))
+ (test (let (x y) (ifa (> (* x x) (* y y)) it)) :error))
;; "it" is (+ 3 (* 2 x))
(test (let ((x 5))
diff --git a/tests/common.tl b/tests/common.tl
index cdfc6c6a..accbf1f7 100644
--- a/tests/common.tl
+++ b/tests/common.tl
@@ -39,3 +39,10 @@
(caseql (os-symbol)
((:linux :solaris :macos :android) (dlopen nil))
((:cygwin) (dlopen "cygwin1.dll"))))
+
+(defmacro macro-time-let (:env env bindings . body)
+ (with-gensyms (invoke)
+ ^(macrolet ((,invoke ()
+ (let ,bindings
+ (expand '(progn ,*body) ,env))))
+ (,invoke))))