X-Git-Url: http://christophe.rhodes.io/gitweb/?p=swankr.git;a=blobdiff_plain;f=swank.R;h=13164853c32efb8a4c0c4086229a7431c6d99516;hp=c0a3ce547c2574860ac46a9b3f13e72b9268166b;hb=eb2756730af853555a941d7acb595c07169f3524;hpb=1083f5377e8173da9f6b85e80a7e1b63098005ab diff --git a/swank.R b/swank.R index c0a3ce5..1316485 100644 --- 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) @@ -239,6 +259,12 @@ printToString <- function(val) { } `swank:swank-require` <- function (slimeConnection, sldbState, contribs) { + for(contrib in contribs) { + filename <- sprintf("%s.R", as.character(contrib)) + if(file.exists(filename)) { + source(filename, verbose=TRUE) + } + } list() } @@ -246,10 +272,23 @@ printToString <- function(val) { list("R", "R") } +sendReplResult <- function(slimeConnection, value) { + string <- printToString(value) + sendToEmacs(slimeConnection, + list(quote(`:write-string`), + paste(string, collapse="\n"), + quote(`:repl-result`))) +} + +sendReplResultFunction <- sendReplResult + `swank:listener-eval` <- function(slimeConnection, sldbState, string) { - val <- eval(parse(text=string), envir = globalenv()) - string <- printToString(val) - list(quote(`:values`), paste(string, collapse="\n")) + string <- gsub("#\\.\\(swank:lookup-presented-object-or-lose([^)]*)\\)", ".(`swank:lookup-presented-object-or-lose`(slimeConnection, sldbState,\\1))", string) + expr <- parse(text=string)[[1]] + lookedup <- do.call("bquote", list(expr)) + value <- eval(lookedup, envir = globalenv()) + sendReplResultFunction(slimeConnection, value) + list() } `swank:autodoc` <- function(slimeConnection, sldbState, rawForm, ...) { @@ -310,9 +349,8 @@ computeRestartsForEmacs <- function (sldbState) { if(is.null(srcfile)) { list(quote(`:error`), "no srcfile") } else { - filename <- get("filename", srcfile) list(quote(`:location`), - list(quote(`:file`), filename), + list(quote(`:file`), sprintf("%s/%s", srcfile$wd, srcfile$filename)), list(quote(`:line`), srcref[[1]], srcref[[2]]-1), FALSE) }