roc/crates/repl_wasm
Anton-4 0e91eca9c8
website has moved to https://github.com/roc-lang/www.roc-lang.org (#8094)
* website has moved to https://github.com/roc-lang/www.roc-lang.org

* CI remove website build

Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com>

* remove website build script CI

Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com>

* additional cleanup

---------

Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com>
2025-07-22 18:53:15 +02:00
..
src
architecture.png
build-www.sh website has moved to https://github.com/roc-lang/www.roc-lang.org (#8094) 2025-07-22 18:53:15 +02:00
build.rs
Cargo.toml
README.md website has moved to https://github.com/roc-lang/www.roc-lang.org (#8094) 2025-07-22 18:53:15 +02:00
screenshot.png

Web REPL

Running locally

1. Build the web REPL

This builds the compiler as a .wasm file, and generates JS glue code. It will cargo install the wasm-pack command line tool if you don't already have it.

crates/repl_wasm/build-www.sh

For website folder see https://github.com/roc-lang/www.roc-lang.org

mkdir -p website/public/repl
cd website/public/repl
ln -s ../../../crates/repl_wasm/build/roc_repl_wasm_bg.wasm
ln -s ../../../crates/repl_wasm/build/roc_repl_wasm.js

These symlinks are ignored by Git.

This is a bit different from the production build, where we copy all the files to website/build/. But for development, it's convenient to have just one copy of files like website/public/repl/repl.js. You can make changes, reload your browser to see them, and commit them to Git, without getting mixed up between different copies of the same file.

3. Run a local HTTP server

Browsers won't load .wasm files over the file:// protocol, so you need to serve the files in ./website/build/ from a local web server. Any server will do, but this example should work on any system that has Python 3 installed:

cd website/public
python3 -m http.server

4. Open your browser

You should be able to find the Roc REPL at http://127.0.0.1:8000/repl (or whatever port your web server mentioned when it started up.)

Warning: This is work in progress! Not all language features are implemented yet, error messages don't look nice yet, up/down arrows don't work for history, etc.

Screenshot

How it works

  • User types text into the HTML <input /> tag
  • JS detects the onchange event and passes the input text to the Roc compiler WebAssembly module
  • Roc compiler WebAssembly module
    • Parses the text (currently just a single line)
    • Type checks
    • Monomorphizes
    • Generates WebAssembly using the development backend (not LLVM)
    • Returns a slice of bytes to JavaScript
  • JavaScript
    • Takes the slice of bytes and creates a WebAssembly.Instance
    • Runs the WebAssembly app
    • Gets the memory address of the result and makes a copy of the app's entire memory buffer
    • Passes the result address and the memory buffer to the compiler for analysis
  • Roc compiler WebAssembly module
    • Analyses the bytes of the result, based on the known return type from earlier
    • Traverses the copied memory buffer to find any child values
    • Produces a user-friendly String and passes it to JavaScript
  • JavaScript
    • Displays the input and output text on the web page

High-level diagram

There are several directories/packages involved here:

  • website/public/repl/index.html: The web page with its JavaScript and a build script
  • crates/repl_wasm: The Rust crate that becomes the "compiler" WebAssembly module
  • crates/repl_eval: REPL logic shared between crates/repl_cli and crates/repl_wasm