#263 #p pathname-literal reader macro unimplemented — corrupts the read (splices stray tokens)

closed
Opened by atgreen

src/cold/reader.lisp sharp-dispatch (reader-read-sharp-macro, ~line 1792) has cases for #: #\ #( #+ #- #' #. #| but NO #p / #P case; the fallthrough is (t -1) (line ~1825). So reading #p"/path/" does NOT construct a pathname — the -1 skip signal leaks and the following string token is spliced into the enclosing form, corrupting arg counts.

Repro (build/funcl REPL): (defvar rr nil) (push #p"/tmp/bar/" rr) => ; Error: invalid number of arguments: G25 expected 2, got 4 | in: PUSH (prin1 #p"/tmp/foo/") => ; Error: invalid number of arguments: PRIN1 expected 1, got 3

Impact: any code using #p pathname literals mis-reads. asdf/uiop and most .asd files in the wild use #p. Workaround: use plain strings (asdf central-registry accepts string dirs).

Fix: add a #p / #P arm to reader-read-sharp-macro that reads the following string and constructs a pathname via (pathname ) (parse-namestring), mirroring how the runtime pathname reader works. Gate record-vs-bv on ag-runtime-symbol-unification-p like #' does.

Comments (2)

atgreen3992785764

DEGRADED-BENIGN now (probe 2026-07-11): #p"/tmp/x" reads as NIL — no longer corrupts the surrounding read (earlier behavior spliced stray tokens). Still unimplemented: should produce a pathname object (parse-namestring of the string). Small reader-macro addition now that pathnames are real marker objects (cave#235 closed today).

atgreen3992796231

FIXED: #p"namestring" / #P"namestring" read as (PARSE-NAMESTRING ...) call forms — evaluated positions construct real pathname objects. (pathnamep #p"/tmp/") => T; namestring round-trips. Quoted-context literalness ('#p"x") documented as the v0 limitation, same as #(...).