Skip to content
bprPublic

About

An implementation of a Mojo-like language in Rust

Resources

Stars

5 stars

Watchers

0 watching

Forks

Repository files navigation

mojito

mojito is a small Rust implementation of an evolving subset of Mojo. It is not Mojo and does not pretend to the reach of Mojo's production compiler, but resembling that compiler's own shape is a goal it works toward: it is a compact implementation for studying, and step by step reproducing, the structure of a modern systems programming language compiler. Mojo was chosen as a target because it is a rich language, with value semantics, ownership/borrowing, ASAP destruction, generics, overloading, and compile-time execution — interesting features associated with C++, Rust, and Zig. Those semantics are enforced as explicit compiler analyses over a small MIR, with a register VM as the executable semantic oracle, and the goal is honest subset semantics: features are usually parsed before they are fully supported, and unsupported semantics fail cleanly instead of producing a wrong answer.

Project Goals

  • Parse all of current Mojo and report syntax errors
  • Approach semantic parity with a single-threaded, CPU-first subset of current Mojo. All mojito programs should be runnable by Mojo, though platform-specific Mojo programs stay outside the current target. The most primitive concurrency is expected eventually, and GPU is a stretch goal; parallelism, distributed execution, and Python interoperability are not intended
  • Close the architectural distance to Mojo's own implementation, in stages (docs/architecture.md)
  • Keep the register VM as the executable semantic oracle while adding a stable textual MIR/VM assembly format and, later, native backends — Pliron and Cranelift first, with a possible C or C++ backend

Status

The feature matrix is the authoritative record of what is executable, checked-only, parse-only, or unsupported. The project overview narrates the current status, the deliberate gaps relative to Mojo, and the development direction. Mojito currently tracks the pinned Mojo nightly recorded in docs/mojo-nightly.md.

Pipeline

source
  -> lex
  -> parse
  -> module link
  -> comptime elaboration
  -> check
  -> HIR region tree
  -> MIR
  -> ownership / borrow / liveness analysis
  -> drop elaboration
  -> elaboration to concrete MIR (native::mono)
  -> register VM / native backend

The Compiler driver owns this ordering for whole-program use; individual stage APIs remain available for syntax tools and compiler development. See the architecture guide for phase design and the symbol map for code navigation.

Build

cargo build
cargo test
cargo clippy --all-targets

If your environment sets RUSTC_WRAPPER to a tool that cannot write its cache, prefix commands with env RUSTC_WRAPPER=.

Quick Start

Run a compiler stage over a file, -, or standard input:

cargo run -- <command> [FILE]
Command What it does
lex print the token stream, one token per line
parse print the parsed AST
check parse and type-check
own parse, type-check, and run ownership analysis
run compile and execute on the register VM
emit-mir compile and print canonical executable MIR
exec execute a verified textual MIR artifact
opt run named MIR passes (--pass NAME) over a textual artifact and print it

For example:

echo 'def main(): print("Hello from mojito")' | cargo run -- run
cargo run -- run assets/ok/list_and_struct.mojo
cargo run -- emit-mir assets/ok/defines_main.mojo | cargo run -- exec -

Native Binaries with Pliron and LLVM

The supported Pliron backend lowers Mojito's verified MIR through Pliron's LLVM dialect. It currently requires Linux and LLVM 23.1. The recommended way to get a native executable is a single --emit exe call, which drives the pinned LLVM optimization and linking tools and links the Mojito runtime behind the scenes:

cargo build --release -p mojito-runtime
cargo run --release --features backend-pliron -- compile program.mojo \
  --backend pliron --emit exe --native-opt release -o program
./program

--print-toolchain reports the resolved opt and clang tools and the runtime archive.

To inspect the intermediate LLVM IR instead, emit an .ll file:

cargo run --features backend-pliron -- compile program.mojo \
  --backend pliron --emit ll -o program.ll

The emitted IR includes the synthesized C main wrapper, so you can also run the same LLVM 23.1 optimization and linking machinery by hand — the final link must include Mojito's native runtime:

opt-23 -passes='default<O1>' program.ll -o program.bc
clang-23 --target=x86_64-unknown-linux-gnu --no-default-config \
  program.bc target/release/libmojito_runtime.a \
  -lm -Wl,--build-id=none -o program
./program

Use the LLVM 23 executable names provided by your installation if they differ from opt-23 and clang-23.

Use --emit bc or --emit obj when an intermediate LLVM bitcode or object artifact is more useful. Pliron supports only the native subset recorded in the feature matrix; unsupported programs fail with a diagnostic instead of falling back to the VM. The native ABI and toolchain contract are documented in the native ABI guide.

See usage for module-root options, how to write and run programs, the fixture workflow, differential conformance against Mojo, and the Rust library API.

Documentation

Links

About

An implementation of a Mojo-like language in Rust

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages