Say i have the following (obviously wrong, but let`s for the sake of argument pretend that i didn`t notice) code:
(defstruct foo (bar nil (type (or nil t))))
When i slime-load-file this code i get the following error condition signaled to me via SLDB:
Execution of a form compiled with errors. Form: (DEFSTRUCT FOO (BAR NIL (TYPE (OR NIL T)))) Compile-time-error: (during macroexpansion of (DEFSTRUCT FOO ...)) error while parsing arguments to DESTRUCTURING-BIND: odd number of elements in keyword/value list: ((TYPE (OR NIL T))) [Condition of type SB-INT:COMPILED-PROGRAM-ERROR]
Restarts: 0: [ABORT] Abort SLIME compilation. 1: [ABORT-REQUEST] Abort handling SLIME request. 2: [TERMINATE-THREAD] Terminate this thread (#<THREAD "worker" {B6888B1}>)
Backtrace: 0: ((SB-C::TOP-LEVEL-FORM (ERROR (QUOTE SB-INT:COMPILED-PROGRAM-ERROR) :MESSAGE "(during macroexpansion of (DEFSTRUCT FOO ...)) error while parsing arguments to DESTRUCTURING-BIND: odd number of elements in keyword/value list: ((TYPE (OR NIL T)))" #1="#<...>" . #1#))) 1: (SB-FASL::LOAD-FASL-GROUP #<SB-SYS:FD-STREAM for "file /home/deepfire/source/sdlsq/tmp.fasl" {B6D3F51}>) 2: (SB-FASL::LOAD-AS-FASL #<SB-SYS:FD-STREAM for "file /home/deepfire/source/sdlsq/tmp.fasl" {B6D3F51}> NIL #<unavailable argument>) 3: (SB-FASL::INTERNAL-LOAD #P"/home/deepfire/source/sdlsq/tmp.fasl" #P"/home/deepfire/source/sdlsq/tmp.fasl" :ERROR NIL NIL :BINARY NIL) 4: (SB-FASL::INTERNAL-LOAD #P"/home/deepfire/source/sdlsq/tmp.fasl" #P"/home/deepfire/source/sdlsq/tmp.fasl" :ERROR NIL NIL NIL :DEFAULT) 5: (LOAD #P"/home/deepfire/source/sdlsq/tmp.fasl")
...
So, what is the problem with that?
Thing is, you my argue that the error specification is precise enough.
However if i want to jump to the source code location which caused this error, after striking 'v' on /any/ entry in the debug stack, i get errors like this:
unhandled DEBUG-CONDITION: #<SB-DI::COMPILED-DEBUG-FUN (SB-C::TOP-LEVEL-FORM (ERROR (QUOTE SB-INT:COMPILED-PROGRAM-ERROR) :MESSAGE "(during macroexpansion of (DEFSTRUCT FOO ...)) error while parsing arguments to DESTRUCTURING-BIND: odd number of elements in keyword/value list: ((TYPE (OR NIL T)))" #1="#<...>" . #1#))> has no debug-block information.
In fact, observing the debug stack makes it clear that none of its entries bear direct relevance to the source at fault. It points into the guts of the SBCL macroexpander.
So this raises the question -- how do i jump to the source location of a syntax error?
regards, Samium Gromoff
* Samium Gromoff [2006-04-23 20:26+0200] writes:
In fact, observing the debug stack makes it clear that none of its entries bear direct relevance to the source at fault. It points into the guts of the SBCL macroexpander.
Those are actually the guts of the loader, not the macroexpander. AFAIK, SBCL still generates code for source with this kind of error but the code just signals the condition.
It might help, if you use slime-compile-file (without loading) so that you can see the compiler messages without getting disturbed by the errors during load time.
So this raises the question -- how do i jump to the source location of a syntax error?
Well, SBCL doesn't provide the source location for those errors so SLIME can't display it.
Below is a little patch to SBCL to pass the source context along.
If you are debugging your own (toplevel) macros, it often useful to eval (instead of compile) the code, because then the compiler doesn't catch the error and you can jump to the source of the macro expander from the backtrace.
Helmut.
--- sbcl-0.9.11/src/compiler/main.lisp 2005-11-21 04:53:21.000000000 +0100 +++ /tmp/main-patched.lisp 2006-04-24 23:24:57.384035032 +0200 @@ -1185,7 +1185,9 @@ ;; sequence of steps in ANSI's "3.2.3.1 Processing of ;; Top Level Forms". #-sb-xc-host - (let ((expanded (preprocessor-macroexpand-1 form))) + (let ((expanded + (let ((*current-path* path)) + (preprocessor-macroexpand-1 form)))) (cond ((eq expanded form) (when compile-time-too (eval-in-lexenv form *lexenv*))