author | Alan Dipert
<alan@dipert.org> 2020-04-15 07:09:32 UTC |
committer | Alan Dipert
<alan@dipert.org> 2020-04-15 07:09:32 UTC |
parent | d8124102f82f5eb263d7d5c24d58ec7cbb35c510 |
RUN.md | +125 | -0 |
jacl-tests.lisp | +1 | -1 |
jacl.js | +2 | -2 |
repl-client/jacl-client.R | +13 | -2 |
diff --git a/RUN.md b/RUN.md new file mode 100644 index 0000000..45f0039 --- /dev/null +++ b/RUN.md @@ -0,0 +1,125 @@ +This document describes: + +* The purpose of various files in the distribution. +* How to run the JACL tests in a Web browser. +* How to connect to a JACL REPL, hosted in Google Chrome, from a + host terminal. +* How to connect to a JACL REPL from within + [Emacs](https://www.gnu.org/software/emacs/). + +# Files of Interest + +* `index.html` is Web page that includes the JACL runtime, compiler, + and test suite. Currently, JACL development is performed mostly by + making changes and reloading this file in a Web browser to see if + anything breaks. +* `jacl.js` contains the JACL runtime, compiler, and REPL + machinery. `jacl.js` will also fetch, compile, and evaluate any + `<script type='application/lisp' src=... />` tags found in `<head>` + in their order of appearance. Lisp script loading is why `index.html` + must be served from a Web browser and not simply from a `file://` + URL. JACL uses Ajax to fetch Lisp scripts. +* `boot.lisp` is where the `COMMON-LISP` package is populated from. It + is evaluated by `jacl.js` when `index.html` loads. +* `jacl-tests.lisp` contains Lisp unit tests and is evaluated after + `boot.lisp`. +* `repl/jacl-client.R` is a JACL REPL client written in R. It is + capable of connecting to the WebSocket interface presented by an + instance of Google Chrome with remote debugging enabled. It then + communicates with JACL over the debugging channel. +* `repl/jacl` is a shell wrapper around `jacl-client.R`. It is + designed to be symlinked from somewhere on your `$PATH` for use as + an Emacs + [inferior-lisp](https://www.gnu.org/software/emacs/manual/html_node/emacs/External-Lisp.html) + program. + +# Running JACL Tests + +First, you must start a local Web server on localhost:8000 to serve +this directory. There are many ways to do this, but on a typical Linux +system, one or both of the following commands will probably work: + + # If you have Python 2: + python -m SimpleHTTPServer + + # If you have Python 3: + python3 -m http.server + +Next, visit http://localhost:8000 with your Web browser of +choice. JACL development is performed primarily on Google Chrome, but +other browsers should work. + +You should see a page of test results. [QUnit](https://qunitjs.com/) + +The JACL runtime and compiler are contained in the file `jacl.js`. + +# Connect to a JACL REPL + +This task involves downloading R, several R packages, and starting +Google Chrome with remote debugging enabled. These instructions are +for Linux but likely work on macOS and Windows 10 with slight +modification. + +## Install R and required R Packages + +First, install the latest version of [R](https://www.r-project.org/) +for your platform. Then, install openssl for your platform: + +* deb: libssl-dev (Debian, Ubuntu, etc) +* rpm: openssl-devel (Fedora, CentOS, RHEL) +* csw: libssl_dev (Solaris) +* brew: openssl (Mac OSX) + +Next, start R with the `R` command. At the R prompt, evaluate the +following to install the `remotes` package package from CRAN, R's +primary package repository: + + install.packages(c("curl", "remotes")) + +Now you must install a development package, `chromote`, that is not +yet on CRAN. `chromote` may be installed from GitHub using the +`remotes` package you have just installed. At the R prompt, evaluate +the following: + + remotes::install_github("rstudio/chromote") + +After compilation completes, you will be returned to the `>` R +prompt. You can exit R with `q()`. You need not "Save workspace image" +when prompted. + +## Run Google Chrome with Remote Debugging + +If you haven't yet, start a local Web server using the instructions +under "Run JACL Tests". + +Then, start Google Chrome — or Chromium, an open-source alternative — +using the procedure documented here: +https://blog.chromium.org/2011/05/remote-debugging-with-chrome-developer.html + +Note that the `--user-data-dir` is required; Chrome will not start +properly unless this directory is specified, exists, and can be +created or is otherwise writable. + +After the browser opens, use it to navigate to +http://localhost:8000. You should see the JACL tests page. + +## Start `jacl` + +At this point, you may start a JACL REPL with the following command: + + ./repl-client/jacl + +# Connect to a JACL REPL from Emacs + +Follow the steps under "Connect to a JACL REPL". + +Then, open Emacs, and type `C-u M-x run-lisp` + +At the prompt, enter `jacl` + +You should be presented with an inferior-lisp buffer in which you may +evaluate JACL forms. + +You may also send forms from Lisp buffers to the JACL REPL for +evaluation. See the documentation for `lisp-mode` for details and +applicable key bindings. diff --git a/jacl-tests.lisp b/jacl-tests.lisp index 5c266e3..842f191 100644 --- a/jacl-tests.lisp +++ b/jacl-tests.lisp @@ -72,7 +72,7 @@ (tagbody start (when (> from 0) - (log @"from=" from) + ;; (log @"from=" from) (setq from (1- from)) (go start)))) diff --git a/jacl.js b/jacl.js index c64329d..6ad45d6 100644 --- a/jacl.js +++ b/jacl.js @@ -2180,11 +2180,11 @@ const startRepl = async () => { try { for await(const obj of replReader) { const node = optimize(analyze(emptyEnv, null, obj)); - console.log(node) + // console.log(node) const sb = new StringBuffer(); emitNode(sb.append.bind(sb), node); const code = sb.toString(); - console.log('code="',code,'"'); + // console.log('code="',code,'"'); const result = eval(code); console.log(result); } diff --git a/repl-client/jacl-client.R b/repl-client/jacl-client.R index 683f378..7a4b663 100755 --- a/repl-client/jacl-client.R +++ b/repl-client/jacl-client.R @@ -9,10 +9,21 @@ invisibly <- function(expr) { invisible() } +first_id <- function(r) { + ts <- r$Target$getTargets()$targetInfos + stopifnot(length(ts) > 0) + r$Target$getTargets()$targetInfos[[1]]$targetId +} + # TODO figure out how to use Log instead of deprecated Console invisibly({ - b <- ChromoteSession$new() - b$Page$navigate("http://rstudio.local:8000") + rc <- ChromeRemote$new(host = "localhost", port = 9222) + r <- Chromote$new(browser = rc) + tid <- first_id(r) + b <- r$new_session(targetId = tid) + # The below is for use with headless chrome: + #b <- ChromoteSession$new() + #b$Page$navigate("http://localhost:8000") b$Console$messageAdded(function (msg) { cat(msg$message$text) cat('\n> ')