[Slime-devel] M-. vs readtable on SBCL

Gábor Melis mega at retes.hu
Mon Jan 26 21:59:25 UTC 2015


Compile a file with these contents:

-------------------------------------

(cl:defpackage :xxx
  (:use #:common-lisp))

(in-package :xxx)

(named-readtables:in-readtable pythonic-string-reader:pythonic-string-syntax)

(defun foo ()
  """   "#<>"   """)

(defun bar ())

-------------------------------------

Press M-. on BAR, it works. Open the scratch buffer, type XXX::BAR and
press M-. on it to get (with *DEBUG-SWANK-BACKEND* T):

-------------------------------------

illegal sharp macro character: #\<

  Line: 9, Column: 11, File-Position: 167

  Stream: #<SB-IMPL::STRING-INPUT-STREAM {102387D1B3}>
   [Condition of type SB-INT:SIMPLE-READER-ERROR]

Restarts:
 0: [*ABORT] Return to SLIME's top level.
 1: [ABORT] abort thread (#<THREAD "worker" RUNNING {102386D683}>)

Backtrace:
  0: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGING-ENVIRONMENT :IN "/home/mega/quicklisp/local-projects/slime/swank/sbcl.lisp") #<FUNCTION (LAMBDA NIL :IN SWANK::DEBUG-IN-EMACS) {1007266DEB}>)
  1: (SWANK::DEBUG-IN-EMACS #<SB-INT:SIMPLE-READER-ERROR "illegal sharp macro character: ~S" {102387D713}>)
  2: (SWANK:INVOKE-SLIME-DEBUGGER #<SB-INT:SIMPLE-READER-ERROR "illegal sharp macro character: ~S" {102387D713}>)
  3: (SWANK/SBCL::CALL-WITH-BREAK-HOOK #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK:SWANK-DEBUGGER-HOOK) {102387E08B}>)
  4: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGER-HOOK :IN "/home/mega/quicklisp/local-projects/slime/swank/sbcl.lisp") #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK:SWANK-DEBUGGER-HOOK)..
  5: (SWANK:SWANK-DEBUGGER-HOOK #<SB-INT:SIMPLE-READER-ERROR "illegal sharp macro character: ~S" {102387D713}> #<unavailable argument>)
  6: (SB-DEBUG::RUN-HOOK *DEBUGGER-HOOK* #<SB-INT:SIMPLE-READER-ERROR "illegal sharp macro character: ~S" {102387D713}>)
  7: (INVOKE-DEBUGGER #<SB-INT:SIMPLE-READER-ERROR "illegal sharp macro character: ~S" {102387D713}>)
  8: (ERROR SB-INT:SIMPLE-READER-ERROR :STREAM #<SB-IMPL::STRING-INPUT-STREAM {102387D1B3}> :FORMAT-CONTROL "illegal sharp macro character: ~S" :FORMAT-ARGUMENTS (#\<))
  9: (SB-INT:SIMPLE-READER-ERROR #<SB-IMPL::STRING-INPUT-STREAM {102387D1B3}> "illegal sharp macro character: ~S" #\<)
 10: (SB-IMPL::SHARP-ILLEGAL #<SB-IMPL::STRING-INPUT-STREAM {102387D1B3}> #\< #<unavailable argument>)
 11: (SB-IMPL::READ-MAYBE-NOTHING #<SB-IMPL::STRING-INPUT-STREAM {102387D1B3}> #\#)
 12: (SB-IMPL::READ-LIST #<SB-IMPL::STRING-INPUT-STREAM {102387D1B3}> #<unavailable argument>)
 13: (SB-IMPL::READ-MAYBE-NOTHING #<SB-IMPL::STRING-INPUT-STREAM {102387D1B3}> #\()
 14: (SB-IMPL::%READ-PRESERVING-WHITESPACE #<SB-IMPL::STRING-INPUT-STREAM {102387D1B3}> T (NIL) T)
 15: (SB-IMPL::%READ-PRESERVING-WHITESPACE #<SB-IMPL::STRING-INPUT-STREAM {102387D1B3}> T (NIL) NIL)
 16: (SB-IMPL::%READ-PRESERVING-WHITESPACE #<SB-IMPL::STRING-INPUT-STREAM {102387D1B3}> T (NIL) NIL) [tl,external]
 17: (READ #<SB-IMPL::STRING-INPUT-STREAM {102387D1B3}> T NIL NIL)
 18: (SWANK/SOURCE-PATH-PARSER::SKIP-TOPLEVEL-FORMS 4 #<SB-IMPL::STRING-INPUT-STREAM {102387D1B3}>)
 19: (SWANK/SOURCE-PATH-PARSER:READ-SOURCE-FORM 4 #<SB-IMPL::STRING-INPUT-STREAM {102387D1B3}>)
 20: (SWANK/SOURCE-PATH-PARSER::SOURCE-PATH-STREAM-POSITION (4) #<SB-IMPL::STRING-INPUT-STREAM {102387D1B3}>)
 21: (SWANK/SOURCE-PATH-PARSER:SOURCE-PATH-STRING-POSITION (4) "(cl:defpackage :xxx ..)
 22: (SWANK/SBCL::CALL-WITH-DEBOOTSTRAPPING #<CLOSURE (LAMBDA NIL :IN SWANK/SBCL::SOURCE-FILE-POSITION) {102387D19B}>)
 23: (SWANK/SBCL::SOURCE-FILE-POSITION "/home/mega/own/mgl-pax/src/x.lisp" 3631296724 (4))
 24: (SWANK/SBCL::DEFINITION-SOURCE-FILE-LOCATION #S(SB-INTROSPECT:DEFINITION-SOURCE :PATHNAME #P"/home/mega/own/mgl-pax/src/x.lisp" :FORM-PATH (4) :CHARACTER-OFFSET 177 :FILE-WRITE-DATE 3631296724 :PLIST ..
 25: ((FLET SWANK/BACKEND:FIND-DEFINITIONS :IN "/home/mega/quicklisp/local-projects/slime/swank/sbcl.lisp") XXX::BAR)
 26: (SWANK:FIND-DEFINITIONS-FOR-EMACS "xxx::bar")
 27: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK:FIND-DEFINITIONS-FOR-EMACS "xxx::bar") #<NULL-LEXENV>)
 28: (EVAL (SWANK:FIND-DEFINITIONS-FOR-EMACS "xxx::bar"))
 29: (SWANK:EVAL-FOR-EMACS (SWANK:FIND-DEFINITIONS-FOR-EMACS "xxx::bar") "COMMON-LISP-USER" 381)

-------------------------------------

So the source location has the index of the top-level form in the file
(4) and swank tries to skip some forms by reading which, even with
*READ-SUPPRESS* T, fails on #<.

There are three options that I can see:

A. Make SOURCE-FILE-POSITION find the right readtable for the file.
   Currently has logic for SB! only.

B. Record the absolute position of the form in the file.

C. Apply some heuristics to SKIP-TOPLEVEL-FORMS.

OK. C is ugly and fragile, B is just fragile, A requires changes in both
NAMED-READTABLES and SLIME/SWANK. Perhaps, you have better ideas?

Cheers,
Gabor




More information about the slime-devel mailing list