Make the REPL read multi-line forms and render real error messages
The REPL evaluated one line at a time, so a form split across lines (e.g. `(+` then `1 2)`) raised instead of waiting. The read loop now accumulates lines until delimiters are balanced — skipping string, char, regex and comment context — printing a `... ` continuation prompt for each extra line. Reader/runtime errors rendered as Chez's "attempt to apply non-procedure #[chez-pmap...]" instead of their real message. Two causes: jolt-throw raised the thrown value raw. When a throw crossed the host `eval` boundary, Chez re-wrapped the non-condition into a compound condition whose message extraction applies the value, losing the message and crashing on ex-info's empty-map :data. jolt-throw now raises a &jolt-throw condition wrapping the value; catch (lowered to `guard`), jolt-report-uncaught and jolt-render-throwable unwrap it back via jolt-unwrap-throw, so ex-data/ex-message and the backtrace tag survive. Every reader/post-prelude EOF-throw site used `(empty-pmap)` (with parens), applying the empty-map value as a procedure and crashing during ex-info construction before jolt-throw ran. Fixed to `empty-pmap`. Re-minted the seed; smoke 23/23, unit 574/574.
This commit is contained in:
parent
a58bca3bee
commit
240458d994
10 changed files with 225 additions and 132 deletions
|
|
@ -103,24 +103,25 @@
|
|||
;; Render an uncaught jolt throw (any value, not just a Chez condition) to a port:
|
||||
;; an ex-info shows its message + ex-data (+ a host cause); anything else is
|
||||
;; pr-str'd. Shared by the cli (cli.ss) and a built binary's launcher (build.ss).
|
||||
(define (jolt-render-throwable v port)
|
||||
(if (jolt=2 (jolt-get v jolt-kw-ex-type jolt-nil) jolt-kw-ex-info)
|
||||
(begin
|
||||
(display "Unhandled exception: " port)
|
||||
(display (jolt-str-render-one (jolt-get v jolt-kw-message jolt-nil)) port)
|
||||
(newline port)
|
||||
(let ((data (jolt-get v jolt-kw-data jolt-nil)))
|
||||
(unless (jolt-nil? data)
|
||||
(display " ex-data: " port) (display (jolt-pr-str data) port) (newline port)))
|
||||
(let ((cause (jolt-get v jolt-kw-cause jolt-nil)))
|
||||
(when (condition? cause)
|
||||
(display " cause: " port)
|
||||
(display (with-output-to-string (lambda () (display-condition cause))) port)
|
||||
(newline port))))
|
||||
(begin
|
||||
(display "Unhandled exception: " port)
|
||||
(display (if (condition? v) (with-output-to-string (lambda () (display-condition v))) (jolt-pr-str v)) port)
|
||||
(newline port))))
|
||||
(define (jolt-render-throwable raw port)
|
||||
(let ((v (jolt-unwrap-throw raw)))
|
||||
(if (jolt=2 (jolt-get v jolt-kw-ex-type jolt-nil) jolt-kw-ex-info)
|
||||
(begin
|
||||
(display "Unhandled exception: " port)
|
||||
(display (jolt-str-render-one (jolt-get v jolt-kw-message jolt-nil)) port)
|
||||
(newline port)
|
||||
(let ((data (jolt-get v jolt-kw-data jolt-nil)))
|
||||
(unless (jolt-nil? data)
|
||||
(display " ex-data: " port) (display (jolt-pr-str data) port) (newline port)))
|
||||
(let ((cause (jolt-get v jolt-kw-cause jolt-nil)))
|
||||
(when (condition? cause)
|
||||
(display " cause: " port)
|
||||
(display (with-output-to-string (lambda () (display-condition cause))) port)
|
||||
(newline port))))
|
||||
(begin
|
||||
(display "Unhandled exception: " port)
|
||||
(display (if (condition? v) (with-output-to-string (lambda () (display-condition v))) (jolt-pr-str v)) port)
|
||||
(newline port)))))
|
||||
|
||||
;; Render the throwable, then its Clojure backtrace when one maps. The caller adds
|
||||
;; any top-level source location (the runtime cli does; a built binary has none).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue