Hello,
how would you add to Slime support for another interpreter? AFAIK, that means just writing a dedicated Swank module. By looking at Slime48, the module to support Scheme48 in Slime, there is quite a bit of code involved. Any directions about the required interface?
Thanks
* Elena Garrulo [2009-07-23 11:35+0200] writes:
Hello,
how would you add to Slime support for? another interpreter? AFAIK, that means just writing a dedicated Swank module.
Yep, that's mostly right. Depending on the language you might also want to write some ELisp code to figure out the correct module for a buffer and things like that.
By looking at Slime48, the module to support Scheme48 in Slime, there is quite a bit of code involved.
If you want to support all features it's going to take a lot of code, but at the beginning it only needs the protocol encoding and decoding and basically a way to call eval in the interpreter. That's almost enough to bring up the Slime REPL (without I/O redirection).
In the contrib directory are some less developed backends. Look at those for simpler examples.
Any directions about the required interface?
Depends where you want to go. The simplest Swank server only needs to handle the swank:interactive-eval and swank:listener-eval events.
For M-. your interpreter needs to have good source-location tracking and doubly so if the language has macros. If your interpreter cannot tell you where a in file a function was defined your out of luck.
Arglist display is also something that the interpreter must support.
C-c C-c usually requires special tricks because you need to tell the compiler that the source comes from the middle of a buffer.
For the debugger your interpreter more-or-less has to follow the CL model where the debugger runs "on-top" of the error, i.e. the stack must be alive. It's quite a miracle how the Clojure people managed to adapt the JVM exception model to Slime's expectations. Again, the interpreter need good source-location tracking for the frame-source-location command.
Interrupts will mostly likely be a challenge.
The inspector is probably not very demanding.
If your interpreter supports all that, than it probably already has a good IDE :-)
Helmut.
Helmut Eller heller@common-lisp.net writes:
For the debugger your interpreter more-or-less has to follow the CL model where the debugger runs "on-top" of the error, i.e. the stack must be alive. It's quite a miracle how the Clojure people managed to adapt the JVM exception model to Slime's expectations.
Java puts the backtrace in the Exception object that is thrown. So while the stack is actually unwinded, all the information is there for the Swank server to process the user requests from Slime like showing frame locals etc. (It can't support restarting a computation, of course.)
-T.
* Tobias C. Rittweiler [2009-07-23 13:35+0200] writes:
Java puts the backtrace in the Exception object that is thrown. So while the stack is actually unwinded, all the information is there for the Swank server to process the user requests from Slime like showing frame locals etc. (It can't support restarting a computation, of course.)
I'm pretty sure that arguments and locals aren't there. Well, maybe some JVMs include them, but java.lang.StackTraceElement has no methods to access them. It must already be expensive to fill in the limited stacktrace that is present in Sun's JVM so maybe it would be possible to include them. OTOH, a hacker could walk the stack to find security holes.
Helmut
Helmut Eller heller@common-lisp.net writes:
I'm pretty sure that arguments and locals aren't there. Well, maybe some JVMs include them, but java.lang.StackTraceElement has no methods to access them. It must already be expensive to fill in the limited stacktrace that is present in Sun's JVM so maybe it would be possible to include them.
Yeah true, but it seems that Java additionally provides a rather complete Debugger API which includes an ExceptionEvent that is invoked at the place an exception is thrown, and where you can get at StackFrame objects.
-T.
* Tobias C. Rittweiler [2009-07-23 19:10+0200] writes:
Yeah true, but it seems that Java additionally provides a rather complete Debugger API which includes an ExceptionEvent that is invoked at the place an exception is thrown, and where you can get at StackFrame objects.
Yes, I know, but Clojure's Swank doesn't use JDI. And of course, cloning the stack on every throw would be slow; too slow for production use.
[At the point of throw, JDI cannot decide whether the exception will be handled - for JDI try-finally is the same as try-catch - so it's necessary to let throw continue to see who is going to handle the exception. Despite that, the idiom: try {..} catch (Throwable e) {..} is not exactly uncommon in Java. The StackFrame mirror becomes useless after unwinding the real stack, so it would be necessary to copy the backtrace before unwinding.]
JDI more or less assumes that the debugger sets breakpoints before the error occurs. Ironically, Slime doesn't even support breakpoints (despite BREAK).
Helmut
Helmut Eller heller@common-lisp.net writes:
[At the point of throw, JDI cannot decide whether the exception will be handled - ...]
Hmm, yes, that's true. I'd have thought that you can subclass the StackTrace that is stuffed into Exceptions, and enrich its StackTraceFrames with information from the StackFrames in the ExceptionEvent.
I'm not sure how easily (if possible at all) you can influence the actual program data. The debugger API seems to be for observing purposes, mostly.
-T.