roc/crates/repl_wasm
Brendan Hansknecht cb191d3788
Split utils into error and command utils
Error utils pulls in snafu which requires procedural macros.
This means it can't start compiling until syn and macro related crates are compiled.
This deals compiling all crates that depend on commands like running zig for the bitcode.
The split enables those crates to run sooner.
2023-03-10 09:39:43 -08:00
..
src windows build fixes 2023-02-17 15:44:15 +01:00
.gitignore Move web REPL assets into www folder and build script into repl_wasm crate 2022-07-09 10:02:24 +01:00
architecture.png Move web REPL assets into www folder and build script into repl_wasm crate 2022-07-09 10:02:24 +01:00
build-www.sh moved benchmarks to nix 2022-10-17 17:40:35 +02:00
build.rs Split utils into error and command utils 2023-03-10 09:39:43 -08:00
Cargo.toml split up bitcode building to reduce dependency chains 2023-03-10 09:39:43 -08:00
README.md Add angle brackets to bare URLs 2022-09-09 01:12:30 -06:00
screenshot.png Move web REPL assets into www folder and build script into repl_wasm crate 2022-07-09 10:02:24 +01:00

Web REPL

Running locally

1. Build the Roc website

For a minimal build (when just working on the web REPL)

cp -r www/public www/build

Or, for a full build (with std lib documentation, downloadable source code, etc.)

www/build.sh

2. 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. You should run it from the project root directory.

crates/repl_wasm/build-www.sh
cp crates/repl_wasm/build/* www/build/repl/

2. Run a local HTTP server

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

cd www/build
python3 -m http.server

3. 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:

  • www/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