formawasm 0.0.1-beta

Backend that compiles a typed FormaLang IR module into a WebAssembly component.
Documentation
<p align="center">
  <img src="website/logo-180.png" alt="formawasm" width="160">
</p>

<h1 align="center">formawasm</h1>

**formawasm** compiles a [formalang](https://github.com/valentinradu/formalang) Intermediate Representation (IR) module into a [WebAssembly](https://webassembly.org) **component** — a `.wasm` binary that any standards-compliant runtime can execute.

```text
formalang frontend ──► IrModule ──► formawasm ──► .wasm component ──► host runtime
```

formawasm is a *backend*: it doesn't parse `.fv` source files itself, and it doesn't run the resulting wasm. Both jobs belong to other libraries (formalang for parsing, [`wasmtime`](https://wasmtime.dev) / [`wasmi`](https://github.com/wasmi-labs/wasmi) / a browser engine for execution). formawasm only emits bytes.

The boundary between a component and its host is described in **WIT** — the small Interface Definition Language of the [Component Model](https://github.com/WebAssembly/component-model). formawasm generates the WIT file automatically from the public surface of each IR module; the host never hand-writes WIT.

---

## Quickstart

Install the CLI:

```bash
cargo install formawasm
```

Or pin to a specific version:

```bash
cargo install formawasm --version 0.0.1-beta
```

Compile a `.fv` source file:

```bash
echo 'pub fn id(x: I32) -> I32 { x }' > id.fv
formawasm id.fv
# wrote id.wasm (… bytes) from id.fv
```

Inspect the generated WIT interface:

```bash
wasm-tools component wit id.wasm
```

```wit
package formawasm:generated;

world component {
  export id: func(x: s32) -> s32;
}
```

Run it directly with the [wasmtime](https://wasmtime.dev) CLI — no host code required:

```bash
wasmtime run --invoke 'id(42)' id.wasm
# 42
```

Or wire it into your Rust application:

```rust
use wasmtime::{Config, Engine, Store};
use wasmtime::component::{Component, Linker};

let mut config = Config::new();
config.wasm_component_model(true);
let engine = Engine::new(&config)?;

let bytes = std::fs::read("id.wasm")?;
let component = Component::from_binary(&engine, &bytes)?;
let linker = Linker::<()>::new(&engine);
let mut store = Store::new(&engine, ());
let instance = linker.instantiate(&mut store, &component)?;

let id = instance.get_typed_func::<(i32,), (i32,)>(&mut store, "id")?;
let (got,) = id.call(&mut store, (42,))?;
assert_eq!(got, 42);
```

---

## Documentation

The full book lives at [`docs/`](docs/SUMMARY.md) and is built with [mdBook](https://rust-lang.github.io/mdBook/):

```bash
mdbook serve            # local dev server with live reload
```

Highlights:

**For users** (embedding formawasm in a Rust application):

- [Quickstart]docs/user/quickstart.md`.fv``.wasm` in 30 seconds
- [Using the Library]docs/user/library.md`WasmBackend` from your own crate
- [Hosting a Component]docs/user/hosting.md — running components under wasmtime
- [Boundary Policy]docs/user/boundary.md — what can cross the WIT boundary
- [Type Mapping]docs/user/type-mapping.md — formalang ↔ WIT
- [Feature Coverage]docs/user/features.md — what's supported, per IR variant
- [Cargo Features]docs/user/cargo-features.md`wasm-opt`, `dwarf`, validation
- [Troubleshooting]docs/user/troubleshooting.md — common errors

**For contributors** (extending the backend):

- [Architecture]docs/developer/architecture.md — the seven-stage pipeline
- [Crate Layout]docs/developer/crate-layout.md — what's in `src/`
- [Lowering]docs/developer/lowering.md — memory model, runtime helpers, per-IrExpr lowering
- [Extending the Backend]docs/developer/extending.md — adding IR variants, runtime helpers, layouts
- [Testing]docs/developer/testing.md — test conventions and milestone tests
- [Contributing]docs/developer/contributing.md — code style, quality gates, microcommit cadence

---

## Status

Phases 1 through 5 are closed. The backend produces a Component-Model artifact for every milestone — recursive functions (`fib`), structs + enums + methods (`Counter` / `Action`), arrays + ranges + for-loops (sieve of Eratosthenes), strings + optionals + dictionaries (`greet`), virtual dispatch (`Greet` trait across two impls), and host-provided externs (`call_host(21) → 42` via `host_double`).

See [`CHANGELOG.md`](CHANGELOG.md) for the phase-by-phase history; the "Roadmap" section at the top captures what's left.

---

## License

Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or [MIT license](LICENSE-MIT) at your option.