Inside the Multilingual Playground: How the Browser, WASM Runtime, and Language Packs Fit Together
Source: Dev.to
Overview
In a recent article I explored how a human‑language‑first programming language can move from multilingual syntax to multilingual runtimes using WebAssembly. This post goes a level deeper and opens the hood on the browser playground that makes this possible.
Resources
- Project repository
- Online playground
- Language core
Components
Browser UI
A simple HTML/CSS/JavaScript interface that provides:
- A code editor
- A language selector (English, French, Spanish, …)
- A “Run” button
- Panels for program output and intermediate representations
WASM Runtime
The multilingual interpreter, compiled to WebAssembly, plus a few helper pieces that make it easy to call from JavaScript. The interpreter handles lexing, parsing, building the AST, and evaluating the program.
Language Packs
Data that describes how each human language maps to the shared semantic core: keywords, operators, punctuation, and eventually error messages. Each pack is configuration, not a fork of the runtime, which keeps the system maintainable.
Conceptual flow: HTML ↔ JS ↔ WASM ↔ Your code — language packs only change the “accent”, not the meaning.
Execution Flow
-
Collect source and language choice
The UI grabs the text from the editor and the selected language identifier (e.g.,froren). -
Call into the WASM module
JavaScript passes{ source, language_id }into an exported WASM function viaWebAssembly.instantiatebindings. Inside the WASM module the data is just raw bytes and an identifier. -
Lexing and parsing with language packs
The lexer and parser look up the appropriate keyword mapping for the chosen pack. Tokens such assi,wenn, andifall map to the same conditional AST node. -
Build the unified AST
The parser produces a single, language‑agnostic AST. From this point onward the runtime is indifferent to the surface language. -
Evaluate and send results back
The interpreter evaluates the AST, captures outputs and errors, and returns structured results across the JS/WASM boundary. The browser renders them in the output panel.
All of this occurs inside a sandboxed environment in the browser, so learners only need a URL to experiment.
Language Packs
A language pack typically contains:
- Keyword mappings – e.g.,
if,else,whilein the target language mapped to internal tokens. - Logical operator names –
and,or,not. - Literal conventions – such as decimal separators.
- Metadata – language name and code.
How the runtime uses packs
// Pseudocode illustrating the process
function compile(source, language_id) {
const pack = registry[language_id];
const lexer = buildLexer(pack);
const parser = buildParser(pack);
const ast = parser.parse(lexer.tokenize(source));
return ast; // language‑agnostic
}
Adding a new language is simply a matter of adding configuration lines and registering the pack, not forking the interpreter. This design enables realistic experimentation with 10+ human languages without drowning in maintenance.
A nice side effect: the playground can display the same program rendered in different surface syntaxes while keeping the underlying semantics identical.
Error Handling
The multilingual runtime separates concerns:
- Core interpreter – produces language‑agnostic error codes and structures.
- Browser UI – displays those errors in a user‑friendly way, localized to the selected language.
Possible extensions
- Localized error‑message catalogs keyed by error code.
- Ability to show errors in the same human language as the source.
- Toggling the language of diagnostics without rerunning the program.
For example, a parse error can be rendered in French or English simply by swapping the message catalog, while the underlying error object remains unchanged.
Deployment
The playground consists of static assets:
- HTML and CSS for the UI
- JavaScript glue code
- The compiled WASM binary
- JSON (or similar) files for language packs
These can be hosted on GitHub Pages or any static‑site host. Once the interpreter is compiled to WASM, the same core can be reused in other contexts such as online textbooks, documentation, or IDE extensions via a WASI environment.
Future Directions
- More language packs, including scripts and writing systems that challenge assumptions about keywords and layout.
- Richer visualizations of the pipeline (e.g., showing WAT or the internal AST alongside the code).
- Embeddable widgets for tutorials and interactive learning material.
Contributing
If you try the playground and experiment with new languages or diagnostics, I would love feedback and contributions in the repository.
Resources
- Project repository
- Online playground
- Language core