roc/crates/repl_wasm/README.md

88 lines
2.9 KiB
Markdown
Raw Normal View History

2022-02-24 20:12:23 +03:00
# Web REPL
2022-02-26 03:43:55 +03:00
## Running locally
2022-02-24 20:12:23 +03:00
### 1. Build the Roc website
For a minimal build (when just working on the web REPL)
```bash
cp -r www/public www/build
```
Or, for a full build (with std lib documentation, downloadable source code, etc.)
```bash
www/build.sh
```
### 2. Build the web REPL
2022-02-24 20:12:23 +03:00
2022-02-26 03:43:55 +03:00
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.
```bash
crates/repl_wasm/build-www.sh
2022-02-26 03:43:55 +03:00
```
### 3. Make symlinks to the generated Wasm and JS
```bash
cd www/public
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 slightly different from how we do the production build but it makes development easy.
You can directly edit files like repl.js and just reload your browser to see changes.
### 4. Run a local HTTP server
2022-02-26 03:43:55 +03:00
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.
2022-02-26 03:43:55 +03:00
Any server will do, but this example should work on any system that has Python 3 installed:
```bash
cd www/public
2022-02-26 03:43:55 +03:00
python3 -m http.server
```
### 5. 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.)
2022-02-26 17:32:37 +03:00
**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.
2022-02-26 03:43:55 +03:00
![Screenshot](./screenshot.png)
## How it works
2022-02-24 20:12:23 +03:00
- 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
2022-02-26 03:43:55 +03:00
- 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
2022-02-24 20:12:23 +03:00
- JavaScript
2022-02-26 03:43:55 +03:00
- 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
2022-02-24 20:12:23 +03:00
- Roc compiler WebAssembly module
2022-02-26 03:43:55 +03:00
- 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
2022-02-24 20:12:23 +03:00
- JavaScript
2022-02-26 03:43:55 +03:00
- Displays the input and output text on the web page
![High-level diagram](./architecture.png)
2022-02-24 20:12:23 +03:00
## Related crates
There are several directories/packages involved here:
2022-02-26 03:43:55 +03:00
- `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`