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

The dynamic profile: every value is an LSB dyn. Functions with defaults (per call or once), named, variadic, and by-reference parameters; locals in registers, shared variables in cells; closures with explicit, implicit, and recursive captures; if, the loop primitive with its step, labeled break/continue, return; match by a sequential decision procedure; direct, dynamic, host, and method calls; maps and arrays with PHP value semantics and key coercion (or shared references); every OPS operation with its policy, promote included; throw and try/catch/finally by LSB’s canonical lowering, defer; globals, constants, statics, and the module body. Every instruction maps back to the HIR node it came from (Compiled::origin) and to a line-table row.

Not yet: coroutines, 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§

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.
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, 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.
KeyCoercion
How map keys are normalized before a map is indexed.
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).