Christophe Weblog Wiki Code Publications Music
implement a mini code-walker to support nested function calls in :emacs-rex
[swankr.git] / swank.R
diff --git a/swank.R b/swank.R
index c0a3ce547c2574860ac46a9b3f13e72b9268166b..b9d89cbc6959c37b59a0e2c16ec7d064ee677a7b 100644 (file)
--- a/swank.R
+++ b/swank.R
@@ -59,12 +59,32 @@ sendToEmacs <- function(slimeConnection, obj) {
   cat(sprintf("%06x", nchar(payload)), payload, sep="")
 }
 
+callify <- function(form) {
+  ## we implement here the conversion from Lisp S-expression (or list)
+  ## expressions of code into our own, swankr, calling convention,
+  ## with slimeConnection and sldbState as first and second arguments.
+  ## as.call() gets us part of the way, but we need to walk the list
+  ## recursively to mimic CL:EVAL; we need to avoid converting R
+  ## special operators which we are punning (only `quote`, for now)
+  ## into this calling convention.
+  if(is.list(form)) {
+    if(form[[1]] == quote(quote)) {
+      as.call(form)
+    } else {
+      as.call(c(list(form[[1]], quote(slimeConnection), quote(sldbState)), lapply(form[-1], callify)))
+    }
+  } else {
+    form
+  }
+}
+
 emacsRex <- function(slimeConnection, sldbState, form, pkg, thread, id, level=0) {
   ok <- FALSE
   value <- NULL
   tryCatch({
     withCallingHandlers({
-      value <- do.call(eval(form[[1]]), c(list(slimeConnection), list(sldbState), form[-1]))
+      call <- callify(form)
+      value <- eval(call)
       ok <- TRUE
     }, error=function(c) {
       newSldbState <- makeSldbState(c, if(is.null(sldbState)) 0 else sldbState$level+1, id)
@@ -249,7 +269,8 @@ printToString <- function(val) {
 `swank:listener-eval` <- function(slimeConnection, sldbState, string) {
   val <- eval(parse(text=string), envir = globalenv())
   string <- printToString(val)
-  list(quote(`:values`), paste(string, collapse="\n"))
+  sendToEmacs(slimeConnection, list(quote(`:write-string`), paste(string, collapse="\n"), quote(`:repl-result`)))
+  list()
 }
 
 `swank:autodoc` <- function(slimeConnection, sldbState, rawForm, ...) {