Attribute Macro dialect
#[dialect]Expand description
Declare instructions with retained syntax operands and capability-based lowering.
Available with typed-declarations. The framework dependency is discovered
automatically, including renamed dependencies. To use a module reexporting
the framework API, apply #[vihaco(crate = path)] to the dialect module.
The path is resolved in the annotated module’s parent scope; self, super,
crate, and absolute paths are supported. Operand types retain their
authored scope. Unannotated bindings use the corresponding field’s parser.
$0:SyntaxType retains another Parse type. If it differs from the field,
the generated instruction has a phase parameter defaulting to Runtime,
and its Syntax form requires an instruction-owned Lower implementation.
Unchanged instructions remain nongeneric and receive identity lowering.
Write authored lowering implementations outside the dialect module, beside
its declaration or in a separate module in the same crate.
use vihaco_runtime::dialect;
mod framework {
pub use vihaco_runtime::*;
}
#[dialect]
#[vihaco(crate = crate::framework)]
pub mod arithmetic {
#[instruction]
pub struct Add(pub i64);
}
fn main() {
use framework::{Parse, chumsky::Parser};
assert_eq!(arithmetic::Add::parser().parse("add 2")
.into_result().unwrap().0, 2);
}Differing operand types are retained until explicit lowering, even when Rust already provides a conversion between them:
use vihaco_runtime::{dialect, Lower, Parse, Syntax, chumsky::Parser};
#[dialect]
mod control {
#[instruction]
#[pattern = "'call $0:u64"]
pub struct Call(pub u32);
}
impl<C: ?Sized> Lower<C> for control::Call<Syntax> {
type Runtime = control::Call;
fn lower(self, _: &mut C) -> vihaco_runtime::eyre::Result<Self::Runtime> {
Ok(control::Call(self.0.try_into()?))
}
}
let source = control::Call::<Syntax>::parser().parse("call 4294967296")
.into_result().unwrap();
assert_eq!(source.0, 4294967296);
assert!(source.lower(&mut ()).is_err());Declare public runtime instructions and their direct parsers.
The framework root is discovered automatically from a dependency on vihaco
or vihaco-runtime, including renamed dependencies. Apply
#[vihaco(crate = path)] to the dialect module to select an explicit root.
The path must name a module exposing the framework API and is resolved in
the annotated module’s parent scope. Relative self and super paths are
supported. Operand types retain their authored scope.