Skip to main content

Phase 0. Skeleton

FieldValue
MEPMEP-53 §Phases
StatusLANDED
Started2026-05-28 (GMT+7)
Landed2026-05-29 07:35 (GMT+7)
Tracking issue— (umbrella)
Tracking PR#22499
Commitaecbc2ddd7 (combined with phase 1)

Gate

TestPhase0Skeleton in transpiler3/rust/build/phase00_test.go: subtests cargo_resolve, runtime_crate, and go_build. The first calls resolveCargo() and rejects environments where no cargo is on PATH and ~/.cargo/bin/cargo is absent. The second checks that runtime3/rust/mochi-runtime/Cargo.toml parses and that src/lib.rs exists, the minimum the emitter requires once extern crate mochi_runtime; is rendered. The third runs go build ./transpiler3/rust/... from the repo root and fails on any compile error in the Rust pipeline subtree.

Lowering decisions

Phase 0 ships no lowering yet, only the scaffolding the later phases depend on. The driver under transpiler3/rust/build/ exports Driver.Build(src, out, target), the Target enum (initially TargetNativeExecutable, TargetRustSource, TargetLinuxStaticX64, TargetLinuxStaticArm64, TargetWasm32WASI), and resolveCargo(). Cargo resolution walks (1) $MOCHI_CARGO, (2) ~/.cargo/bin/cargo, then (3) exec.LookPath("cargo").

transpiler3/rust/rtree/ lands the structural Rust AST: SourceFile, UseDecl, ModDecl, StructDecl, EnumDecl, FnDecl, ImplDecl, LetStmt, IfStmt, MatchStmt, Return, BinaryOp, UnaryOp, Ident, StringLit, IntLit, FloatLit, BoolLit, RawDecl, RawStmt, RawExpr. Each node exposes a RustString(indent int) or RustExprString() renderer using 4-space indent. The SourceFile.RustSource() entry point prepends #![allow(unused, non_snake_case, non_camel_case_types)], the extern crate list, and the use list, then concatenates declarations.

transpiler3/rust/lower/Lower(prog, fileBase, moduleName) exists as a stub signature; it returns a *rtree.SourceFile wrapping an empty fn main() so the driver can round-trip parse, lower, and emit without crashing before any Mochi feature is wired. runtime3/rust/mochi-runtime/src/lib.rs ships the skeleton io::print_* and conv modules so the emitted extern crate mochi_runtime; resolves under cargo.

Files changed

FilePurpose
transpiler3/rust/build/build.goDriver, Build, resolveCargo, Target enum
transpiler3/rust/rtree/Structural Rust AST nodes + renderer
transpiler3/rust/lower/lower.goStub Lower returning an empty main
transpiler3/rust/colour/colour.goStub colour pass (no-op until phase 6)
transpiler3/rust/emit/emit.goEmit(sf, workDir) writes Cargo.toml + src/main.rs
runtime3/rust/mochi-runtime/src/lib.rsRuntime crate skeleton
runtime3/rust/mochi-runtime/Cargo.tomlCrate manifest
transpiler3/rust/build/phase00_test.goTestPhase0Skeleton with 3 subtests

Test set

  • TestPhase0Skeleton/cargo_resolve, TestPhase0Skeleton/runtime_crate, TestPhase0Skeleton/go_build.

Closeout notes

Phase 0 landed on stable Rust 1.95 with rustup default install and go build ./transpiler3/rust/... clean. Key implementation insight: scaffolding the rtree renderer in the same commit as the driver avoided a Phase 1 dependency loop where the hello-world test would need both pieces at once. The runtime crate is single-file (src/lib.rs) to keep cargo check --features embedded simple in phase 18.