instead of using print(), use str(). Also, be even more cautious
about cleaning up in printToString; previously, errors in printing
would lead to a sink to a closed fifo...
Printing is still not really right, and I forsee that we will end up
writing our own printer to get something more lispy. But at least
this approach tends not to dump huge tables into the REPL.
in readPacket, call socketSelect() before actually trying to read on
the connection. This seems to allow R to update graphics windows and
other such niceties.
It would be nice to be able to preserve the (inferior) R REPL as well,
but I haven't yet discovered whether that's possible.
A simple implementation, only looking for a single function
definition (no methods, whether S3 or S4, or indeed anything else).
Enough to support M-., though.
initial implementation of support for REPL presentations
There's a lot here that's ugly, unfinished or just downright horrible.
Most notably, presentation support depends on swank-side read-time
evaluation (indicated with Common Lisp syntax, which hilariously is a
comment in R). We can't support that in general, but we can
special-case the presentation-specific operator.
But then the next difficulty comes along; actually performing that
read-time evaluation needs to happen in a different environment than
the evaluation of the REPL form. In order to achieve this, we abuse
bquote() the equivalent of Lisp's backquote facility, by calling what
in CL terms would be its macro-function on the parsed, preprocessed
expression; only after doing that (and hence resolving the `read-time'
evaluations) do we evaluate the call itself.
The implementation of presentation protocol messages is also slightly
ugly; having to implement cl:nth-value is particulraly horrible, but
the lack of weak references / weak tables in R (at least as far as I
can tell at the moment) is a cause of niggling concern.
use an environment holding the Slime I/O connection
Rather than having a bare io argument everywhere, encapsulate it in an
environment. (An environment is just about the only thing I can find
in R that isn't copy-on-write; this isn't helpful for the i/o
connection, but will be once we start implementing inspectors and
presentations...)
implement swank:interactive-eval and swank:eval-and-grab-output
This allows C-c : and C-u C-c : to work, modulo the printing of an
unnecessary [1]. The evaluation semantics of R are not what a Lisper might
expect; printToString(eval(parse(...))) does not necessarily perform the
evaluation before altering the output stream with sink() -- so capturing
all sorts of incidental output if something goes wrong.
Implement swank:frame-locals-and-catch-tags. There are problems:
1. it seems that some names can be present in an environment but not have
a value, causing eval to blow up;
2. the default printing routines aren't really adapted to the constraints
of rendering in sldb;
3. trying to display locals of some of the swank frames (perhaps anything
with a tryCatch or similar block?) causes R to complain about a promise
already in the process of evaluation;
4. (probably) other things I haven't yet found
Rather than do complicated stuff to keep track of where we are in the
stack, simply store the interesting frames and calls in the sldb state
structure.
R doesn't have much in the way of dynamic binding; you can fake it by
messing with environments, but that's not fun.
So instead, pass around the connection (`io') and an object
representing the SLDB state (`sldbState') to all functions.
Poor-man's explicit continuation-passing-style...
We need to call some of the mainLoop internal functions from elsewhere
now, so make them not-internal any more.
Fix ridiculous thinko in the logical branch of writeSexpToString
use simpleCondition rather than simpleError in swank:throw-to-toplevel
implement swank:debugger-info-for-emacs
Now `q' in sldb (sldb-quit) works. Things that don't work:
1. the backtrace is the wrong way up.
2. calling any restarts
3. frame locals
4. returning from frames (dunno if R actually supports this)
5. zoom to source
6. probably other things
We get far enough to start up a swank server in R and connect to it from
emacs; we get a REPL which formats the R-style results from parsing and
evaluating the input it receives. Debugging, stepping, documentation,
arglist and so on is basically entirely missing.