Skip to content
Browse files

handle presentations with substitute, not bquote

R's bquote doesn't handle nesting: bquote(bquote(.(x))) will evaluate
x when evaluating the outer bequote, not (as in CL) the inner one.
This means that the hilariously ugly strategy in `swank:listener-eval`
to handle lookup of presented objects wreaks havok on any user code
with backquotes in it.

A solution which I think works, and which is in fact marginally less
ugly, is to rewrite the read-eval calls into simple tokens, and
substitute those tokens for the values before calling eval().  This
actually has the right semantics, provided no user code has variables
whose names are small positive integers.  (We should work out how to
namespace these identifiers somehow, maybe with a package, or some
ersatz prefix/suffix.)
  • Loading branch information...
csrhodes committed Aug 3, 2019
1 parent 19c1311 commit e3fe25d720d192563ad078fc78befb5128d8da0f
Showing with 5 additions and 4 deletions.
  1. +5 −4 swank.R
@@ -341,12 +341,13 @@ sendReplResultFunction <- sendReplResult

`swank:listener-eval` <- function(slimeConnection, sldbState, string) {
## O how ugly
string <- gsub("#\\.\\(swank:lookup-presented-object-or-lose([^)]*)\\)", ".(`swank:lookup-presented-object-or-lose`(slimeConnection, sldbState,\\1))", string)
string <- gsub("#\\.\\(swank:lookup-presented-object-or-lose ([^)]*)\\.\\)", "`\\1`", string)
for(expr in parse(text=string)) {
expr <- expr
## O maybe this is even uglier
lookedup <-"bquote", list(expr))
tmp <- withVisible(eval(lookedup, envir = globalenv()))
if(exists("idToObject", envir=slimeConnection)) {
expr <-"substitute", list(expr, slimeConnection$idToObject))
tmp <- withVisible(eval(expr, envir = globalenv()))
if(tmp$visible) {
sendReplResultFunction(slimeConnection, tmp$value)

0 comments on commit e3fe25d

Please sign in to comment.
You can’t perform that action at this time.