Reader records source line/column on list forms

The reader stamps 1-based :line/:column metadata on every list form (plus
:file when load-jolt-file is reading a file), and jolt.host/form-position
reads it back so the analyzer's :pos scaffold finally gets real data. A
left-to-right cursor counts newlines over the delta between successive forms,
so it stays O(n). Vector/map/set literals are untouched (their metadata is a
runtime value the analyzer would have to wrap in with-meta); empty () can't
carry meta. ^meta now merges onto the position keys instead of clobbering them.

Re-mint is byte-identical (the backend doesn't emit :pos), so this is a pure
scaffold for the error-location work that follows.
This commit is contained in:
Yogthos 2026-06-25 21:12:01 -04:00
parent bdf436e242
commit 824fb347a3
4 changed files with 85 additions and 16 deletions

View file

@ -169,17 +169,20 @@
;; skip the no-op form and continue to true end-of-string.
(define (load-jolt-file path)
(let* ((src (read-file-string path)) (end (string-length src)))
(let loop ((i 0))
(when (< i end)
(let-values (((form j) (rdr-read-form src i end)))
(when (> j i)
(unless (rdr-eof? form)
(when (getenv "JOLT_TRACE_LOAD")
(display " [load-form] " (current-error-port))
(display (jolt-pr-str form) (current-error-port)) (newline (current-error-port)))
(jolt-compile-eval-form (if data-readers-active (ldr-apply-readers form) form)
(chez-current-ns)))
(loop j)))))))
;; parameterize (not a bare set!) so a require nested in this file's ns form
;; restores path when control returns to the rest of this file.
(parameterize ((rdr-source-file path)) ; list forms read here carry :file = path
(let loop ((i 0))
(when (< i end)
(let-values (((form j) (rdr-read-form src i end)))
(when (> j i)
(unless (rdr-eof? form)
(when (getenv "JOLT_TRACE_LOAD")
(display " [load-form] " (current-error-port))
(display (jolt-pr-str form) (current-error-port)) (newline (current-error-port)))
(jolt-compile-eval-form (if data-readers-active (ldr-apply-readers form) form)
(chez-current-ns)))
(loop j))))))))
;; load-namespace: load `name`'s source once. Marked loaded BEFORE eval so a
;; dependency cycle terminates (Clojure's behavior). The caller's current ns is