Architecture¶
The crate is a library (src/lib.rs) plus a thin command-line front end (src/main.rs). This
page is an overview; the doc comments in each module go into detail.
Compiler passes¶
Lower the checked AST to IR: blocks of instructions over virtual registers, one per local.
For each function, compute live intervals and assign registers by linear scan, spilling the least-used values to the stack.
Emit x86-64 assembly from the allocated IR, then assemble and link it with gcc.
Pipelines¶
src/driver.rs wires the stages together, and src/main.rs picks a pipeline from the command line.
stone run:lexer->parser->checker->interpreterstone build:lexer->parser->checker->codegen::ir(lower to IR) ->codegen::regalloc(linear scan) ->codegen::x64(emit, then gcc)stone check:lexer->parser->checker, printing every diagnostic without running
Source map¶
module |
role |
|---|---|
|
source positions ( |
|
errors and warnings with a span, and their terminal rendering |
|
|
|
source text to tokens, including Python-style |
|
syntax tree nodes, modeled on |
|
recursive-descent PEG parser; |
|
type inference and name resolution, producing diagnostics, expression types, and symbols with their references |
|
tree-walking evaluator |
|
the |
|
the IR the backend compiles through: lowering from the AST ( |
|
target-independent linear-scan register allocation and parallel-move ordering |
|
the x86-64 backend: instruction selection from allocated IR ( |
|
names of the builtins shared by both backends ( |
|
the run/build/check pipelines, and |
Language server¶
lsp/ is the stone-lsp crate, a language server built on lsp-server and lsp-types, kept out of the main crate so stone itself still depends only on clap. It reanalyzes a document on every change with driver::analyze and answers requests from the resulting checker::Analysis: its diagnostics, the type of every expression, and every symbol with all of its references.
request |
answered from |
|---|---|
diagnostics |
|
hover |
the symbol’s signature, a builtin’s documentation, or the innermost expression’s type |
definition, references, rename |
|
document symbols |
globals and functions, with each function’s parameters and locals |
completion |
|
editors/vscode/ is a VS Code extension that provides highlighting and indentation rules and starts stone-lsp for .st files.
Fuzzing¶
The fuzz/ crate uses cargo-fuzz (libFuzzer, nightly Rust). It is a separate crate, so the main crate still depends only on clap.
target |
input |
checks |
|---|---|---|
|
arbitrary text |
the front end returns tokens, a module, or an error, and never panics, overflows the stack, or takes exponential time |
|
arbitrary text |
the interpreter finishes under |
|
arbitrary text that parses |
|
|
programs from |
the same stages on deep, valid programs |
|
programs from |
|
stone_fuzz::generate writes source text rule by rule from the grammar, tracking scope so every name and call is defined and every program passes the checker. It covers int arithmetic, comparisons, functions with up to eight parameters, if/while/for with break and cont, multi-argument print with strings and booleans, and top-level lists. Every loop is bounded, and functions never read globals, which may not be assigned yet when they run. differential skips a program if the interpreter rejects it (out of fuel, division by zero, an unassigned variable).
Seeds for the text targets are the .st programs in fuzz/corpus/<target>/. fuzz/stone.dict lists stone’s tokens.
Benchmarks¶
The bench/ crate compares compiled stone with C (gcc -O2 and gcc -O0) and Python. It is a separate crate, like fuzz/, and depends on stone only for its tests. Each benchmark in bench/programs/ is written three times, as .st, .c, and .py, and the runner refuses to time a program unless all four builds print the same .out file. See bench/README.md for the programs and a baseline.