Skip to main content

Crate bcgen_lang

Crate bcgen_lang 

Source
Expand description

§bcgen_lang

Compiles HIR (the representation every LexerSketch language lowers into) to LSB, the bytecode bvm-lang executes.

§The lazy path

Build or lower a resolved unit, compile it, and hand the module to a VM:

use hir_lang::{Builder, Name, OpKind};
use intern_lang::Interner;

// fn add(a, b) { a + b }
let mut names = Interner::new();
let mut b = Builder::new();
let (pa, a) = b.local_param(Name::new(names.intern("a")));
let (pb, bb) = b.local_param(Name::new(names.intern("b")));
let (ua, ub) = (b.use_binder(a), b.use_binder(bb));
let sum = b.op(OpKind::Add, &[ua, ub]);
let body = b.block(&[], Some(sum));
let add = b.func(Name::new(names.intern("add")), &[pa, pb], body);
let root = b.module(None, &[add]);
let hir = b.finish(root)?;

let out = bcgen_lang::compile(&hir, &names)?;
let module = out.module();
assert!(module.function(out.function(add).unwrap()).is_some());
assert!(!bytecode_lang::encode(module).is_empty());

Running it (with bvm-lang): Program::load(out.into_module(), &host), then vm.run(func, &[Value::Int(2), Value::Int(3)]) returns Int(5).

§What it compiles

HIR spec v3 (hir-lang 0.4) to LSB format 2 (bytecode-lang 0.3), in the dynamic profile: every value is an LSB dyn. Functions with defaults (per call or once), named, variadic, and by-reference parameters, each carrying its LSB parameter list so dynamic calls bind in the VM; locals in registers, shared variables in LSB references; closures with explicit, implicit, and recursive captures; generators (keyed yield, yield from), await, and spawn; if, the loop primitive with its step, labeled break/continue, return; match by a sequential decision procedure, raising NoMatch when no arm matches; direct, dynamic, host, and method calls; maps and arrays with PHP value semantics, separation that copies only what is shared, and key coercion (or shared references); let_place and PHP references into array elements; every OPS v2 operation with its policy (pow, promote, shift = saturate); union and intersection type tests and casts; throw and try/catch/finally by LSB’s canonical lowering, defer; globals, constants, statics, and the module body; named intrinsics through an Intrinsics table (Intrinsics::mox maps every Mox intrinsic to an inline fast path or a host function). Every instruction maps back to the HIR node it came from (Compiled::origin) and to a line-table row.

Not yet: classes, declared records and sums, and typed fast paths (0.5); each is a precise CompileError::Unsupported.

§Guarantees

  • Loads. Every module it emits passes bvm-lang’s load-time checks: registers, windows, constants, branch targets, and handlers in range.
  • Semantics. Differential tests run random programs through the compiler and the VM, and through a reference interpreter written in the tests, comparing results, error kinds, and error locations.
  • No recursion over the input. Generation is an explicit task stack; any nesting depth compiles in bounded native stack.
  • Budgeted and deterministic. Output is bounded by Options::with_max_instructions; the same unit compiles to the same bytes.

§no_std

The crate needs only alloc. The default std feature is additive.

Structs§

Arity
How many operands an intrinsic takes: from min to max, both inclusive (at most 255, an import’s limit).
Compiled
A compiled unit: the LSB module, its entry points, and the map from every instruction back to the HIR node it was compiled from.
Compiler
A configured compiler: Options and, optionally, a Locate for the line tables.
IntrinsicDef
One entry of an Intrinsics table: the operands it takes and how it compiles.
Intrinsics
The intrinsic table: named intrinsic → arity and lowering. A name that is not in the table is CompileError::UnknownIntrinsic.
LineIndex
A Locate for one source file: 1-based lines and byte columns from the file’s text, for spans that start at base in the session byte space.
Location
A source position for a line-table row: file, line, and column, numbered as the Locate implementation numbers them.
Options
Compilation options: the dynamic profile’s array and key semantics, the body’s role, host linkage, the intrinsic table, and budgets.

Enums§

ArraySemantics
How arrays and maps behave when a value is copied.
BodyMode
What the module body (Module.body) compiles to.
CompileError
Why compile refused a unit.
Fast
A guarded fast path: the operand kinds where an LSB sequence computes exactly the intrinsic’s result, tested at run time; outside that domain the intrinsic’s host function is called with the same operands.
KeyCoercion
How map keys are normalized before a map is indexed.
Lowering
How one named intrinsic compiles.
LsbOp
An LSB instruction sequence with LSB’s own semantics, hooks included (LSB §5.6–§5.10). These are the 0.2 built-in intrinsics.
Unsupported
A HIR form this release does not compile, named precisely.

Traits§

Locate
Maps HIR spans to source positions for LSB line tables.

Functions§

compile
Compiles a resolved unit with the default Options (the PHP profile).