>_RUBYLANG REFERENCE
A compiled Ruby runtime written in Rust. Source is lexed and parsed to an AST, lowered to fusevm bytecode, and executed on the same language-agnostic VM + three-tier Cranelift JIT that hosts zshrs, stryke, awkrs, and elisp. In active development.
What it is
rubylang runs Ruby programs as ordinary compiled bytecode: it lexes and parses the source, lowers it to fusevm instructions, and lets the shared engine execute and JIT-compile them. There is no bespoke VM or tree-walker — arithmetic and comparisons lower to native fusevm ops so the Cranelift JIT can trace hot loops, while Ruby-specific behaviour (method dispatch, blocks, object construction, yield) is served by the runtime host.
It is another language hosted on fusevm, the shared bytecode VM and Cranelift JIT behind zshrs (the shell), stryke (the language), awkrs (AWK), and elisp (Emacs Lisp). rubylang carries no VM or JIT of its own.
Architecture
The pipeline mirrors how zshrs hosts zsh and elisp hosts Emacs Lisp:
Ruby source → lexer → parser (AST) → lower to fusevm bytecode → fusevm VM + Cranelift JIT
│
RubyHost object heap (methods, blocks, String/Array/Hash)
fusevm-hosted
No local vm.rs / jit.rs. Ruby is lowered to fusevm bytecode and executed on the shared three-tier Cranelift JIT; jit-disk-cache persists native code across runs.
Native arithmetic, JIT-able
Arithmetic and comparison operators lower to native fusevm ops; a strict numeric hook supplies Ruby semantics (String/Array +, floored integer division) for non-numeric operands only.
Reference-typed objects
String, Array, and Hash live on the host heap behind Value::Obj handles, so a.push(x) mutates in place — real Ruby reference semantics, not value copies.
Blocks share scope
Because every variable access routes through the thread-local host, a block body run as a nested VM automatically captures and mutates its enclosing locals — Ruby's block semantics, for free.
Example
def fib(n)
n < 2 ? n : fib(n - 1) + fib(n - 2)
end
puts (0..10).map { |i| fib(i) }.join(", ")
# => 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55
sum = 0
[1, 2, 3, 4].each { |x| sum += x }
puts sum # => 10
puts({ a: 1, b: 2 }.merge({ c: 3 }).keys.length) # => 3
Status & roadmap
The table below reflects the current state of the tree.
| Component | State | Notes |
|---|---|---|
| Lexer / parser → AST | Implemented | Space-aware command-call disambiguation; #{} interpolation. |
| AST → fusevm bytecode lowering | Implemented | No local VM; native arithmetic + host dispatch (src/compiler.rs). |
| Object heap & method dispatch | Implemented | Integer/Float/String/Array/Hash/Symbol/Range/Proc (src/host.rs). |
| Core method & Kernel surface | Implemented | Enumerable, String, Hash, Range methods; puts/p/format. Growing. |
Blocks, yield, closures | Implemented | Scope-sharing blocks; break/next/return control flow. |
Standalone ruby binary + REPL | Implemented | Run .rb files, -e one-liners, interactive REPL (src/main.rs). |
| rkyv bytecode script cache | Implemented | Versioned, migration-safe on-disk cache (src/cache.rs). |
Classes, inheritance, super, attr_* | Implemented | initialize, instance vars, single inheritance, ancestor-chain dispatch, method chaining (src/host.rs). |
Modules/include, class methods | Implemented | Mixin methods searched before the superclass; def self.m class methods. |
Exceptions (begin/rescue/ensure) | Implemented | Typed classes, method-body + modifier rescue, custom exception classes. |
Splat params, &:sym, parallel assignment, default args | Implemented | def f(a, *rest), map(&:upcase), a, b = 1, 2, defaulted parameters. |
Parity harness vs reference ruby | Implemented | 35-snippet differential corpus, frozen + replayed in CI (tests/parity.rs). |
LSP server (--lsp) | Implemented | Diagnostics, hover, completion (src/lsp.rs). |
DAP adapter (--dap) | Partial | Handshake + run-to-completion with stdout capture; stepping is a later wave (src/dap.rs). |
extend/prepend, keyword params, regex | Planned | **kwargs, &block params, Regexp, bignum pending. |
Why rubylang
Compiled, not tree-walked
MRI walks a node tree in C; rubylang lowers Ruby to bytecode and JITs hot paths through Cranelift — the same architecture that makes zshrs and stryke fast.
One shared engine
Bug fixes and JIT improvements in fusevm benefit zshrs, stryke, awkrs, elisp, and rubylang at once.
AOP intercepts
A glob-matched before/after/around method-intercept registry (src/intercepts.rs) — aspect weaving over Ruby method calls, the same design as zshrs's function intercepts.
Editor-ready
Ships an LSP server and a DAP adapter over stdio from day one, plus an irb-style REPL on a persistent host.
Building from source
rubylang builds as a standalone Rust crate (it is not a workspace member of the meta repo):
# clone git clone https://github.com/MenkeTechnologies/rubylang cd rubylang # build (debug) cargo build # run a script, a one-liner, or the REPL ./target/debug/ruby script.rb ./target/debug/ruby -e 'puts (1..100).sum' ./target/debug/ruby --repl # run tests cargo test
fusevm is pulled from crates.io with the jit, jit-disk-cache, and aot features.
License
rubylang is MIT licensed — free and open source. See LICENSE.
Repository & links
- Engineering report — report.html (architecture, fusevm hosting, roadmap, dependency posture)
- Builtin reference — reference.html (Kernel and core methods)
- Source — github.com/MenkeTechnologies/rubylang
- Issues — github.com/MenkeTechnologies/rubylang/issues
- The shared VM — fusevm (also behind
zshrs,stryke,awkrs,elisp)