// SCALARS — SCALA IN RUST

scalars v0.1.4 · Scala on fusevm · lex/parse → AST → bytecode → Cranelift JIT · no bespoke VM, no JVM · a fusevm language host (with zshrs, stryke, awkrs, elisp, rubylang, pythonrs) · MIT · in active development

Report Reference GitHub
// Color scheme

>_SCALARS REFERENCE

A Scala frontend 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, elisp, rubylang, and pythonrs. There is no bespoke VM and no JVM. In active development — an early single-object slice.

What it is

scalars runs Scala 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. Arithmetic and comparisons lower to native fusevm ops so the Cranelift JIT can trace hot loops, while Scala-specific behaviour — Int-vs-Double division dispatch, String + concatenation, structural ==, and Double.toString formatting — is served by the host's strict numeric hook (src/host.rs).

It is another language hosted on fusevm, the shared bytecode VM and Cranelift JIT behind zshrs (the shell), stryke (the language), awkrs (AWK), elisp (Emacs Lisp), rubylang (Ruby), and pythonrs (Python). scalars carries no VM or JIT of its own, and — unlike the reference Scala — no JVM: it targets fusevm bytecode directly.

Scope today. The language surface today: a single entry object (object Name extends App { … } whose body runs directly, or an object Name { def main(args: Array[String]): Unit = { … } }), val/var bindings, if/while/for (range, collection and yield forms), println/print, the arithmetic/comparison/boolean and bitwise/shift operators, user-defined methods (including block-local ones), classes/objects/case classes/traits with inheritance and pattern matching, try/catch/throw, first-class functions and partial functions, and the collection library — List/Seq/Vector/Set/Map/Array/Range plus the scala.collection.mutable buffers, sets and maps. See BUGS.md for the honest ledger of what is not carried.

Architecture

The pipeline mirrors how zshrs hosts zsh and rubylang hosts Ruby:

Scala source  →  lexer  →  parser (AST)  →  lower to fusevm bytecode  →  fusevm VM + Cranelift JIT
                                                   │
                                       host: numeric hook (String +, Int/Double /, ==) + Predef print

fusevm-hosted

No local vm.rs / jit.rs and no JVM. Scala is lowered to fusevm bytecode and executed on the shared three-tier Cranelift JIT; jit-disk-cache persists native code across runs.

Newline inference

A hand-written lexer applies Scala's statement-separator rule — a line break separates statements only where one can end and the next can begin, and never inside (…)/[…] (src/lexer.rs).

Faithful numerics

7 / 2 == 3 but 7 / 2.0 == 3.5 (runtime Int/Double dispatch); Double.toString reproduces Java's decimal-vs-scientific threshold; "n=" + 41 concatenates via the strict numeric hook.

Editor + debugger tooling

scala --lsp speaks LSP (completion, hover, live diagnostics from the real parser); scala --dap is a source-line debugger with breakpoints, stepping, and variable inspection.

Example

object Demo extends App {
  var sum = 0
  for (i <- 1 to 10) {
    sum += i
  }
  println(sum)              // => 55

  println(7 / 2)            // => 3     (Int division truncates)
  println(7 / 2.0)         // => 3.5   (Double division)
  println("total = " + sum) // => total = 55
  println(1.0e7)            // => 1.0E7 (Java Double.toString)
}

Toolchain

scala <file>

Lex, parse, lower, and run a .scala file on fusevm.

--dump-tokens / --dump-ast

Print the lexer token stream or the parsed AST and exit.

--disasm

Print the lowered fusevm bytecode disassembly and exit.

--lsp

Language Server Protocol over stdio: keyword/Predef/operator completion, hover, and live parse diagnostics.

--dap

Debug Adapter Protocol over stdio: per-statement breakpoints, single-stepping, stack/scopes/variables, forwarded program output.

--version / --help

Print the version banner or the option grammar.

Status & roadmap

The table below reflects the current state of the tree. See BUGS.md for the honest ledger of what is not yet carried.

ComponentStateNotes
Lexer / parser → ASTImplementedNewline-inferring tokenizer; single-object entry grammar (src/lexer.rs, src/parser.rs).
AST → fusevm bytecode loweringImplementedNo local VM, no JVM; native arithmetic + host hook (src/compiler.rs).
val/var, if/while/range forImplementedBindings, assignments, compound assignment, range comprehensions in statement position.
Int/Double numerics, String +, structural ==ImplementedRuntime division dispatch, Java Double.toString, concatenation coercion via the strict numeric hook (src/host.rs).
println/printImplementedScala-formatted output (true/false, 3.0, null).
Introspection (--dump-tokens/--dump-ast/--disasm)ImplementedToken stream, AST, and fusevm bytecode listing (src/main.rs).
LSP server (--lsp)ImplementedCompletion + hover from the keyword/Predef corpus, live diagnostics from the real parser (src/lsp.rs).
DAP adapter (--dap)ImplementedSource-line breakpoints, stepping, stack/scopes/variables, stdout forwarding (src/dap.rs).
Parity fuzzer vs reference scalaImplementedDifferential probes diffed against a real Scala toolchain (src/bin/parity_fuzz.rs).
User methods, classes, traitsImplementedBlock-local defs with lambda lifting, case class pattern matching, trait mixin and virtual dispatch (src/resolve.rs, src/compiler.rs).
Collections (immutable + mutable)ImplementedThe combinator set over List/Vector/Set/Map/Array/Range, Scala’s own CHAMP HashSet/HashMap iteration order, and the scala.collection.mutable buffers/sets/maps in their hash table’s order (src/host.rs).
Lazy views, Iterator, LazyListPlanned.view/.iterator and user Orderings pending.

Building from source

scalars builds as a standalone Rust crate (it is not a workspace member of the meta repo):

# clone
git clone https://github.com/MenkeTechnologies/scalars
cd scalars

# build (produces target/debug/scala)
cargo build

# run a .scala file
./target/debug/scala examples/hello.scala

# introspection
./target/debug/scala --disasm examples/hello.scala

# editor / debugger tooling over stdio
./target/debug/scala --lsp
./target/debug/scala --dap

# run tests
cargo test

fusevm is pulled from crates.io with the jit, jit-disk-cache, and aot features.

License

scalars is MIT licensed — free and open source. See LICENSE.

Repository & links