vihaco / virtual ISA & machine framework

QuEra Computing · Rust · v0.1

vihaco

Rust 2024 License MIT Source github.com/QuEraComputing/vihaco
counter.rs
use eyre::Result;
use vihaco::{component, dispatch, Effects, Message};

// Bytecode-visible operations. Each variant becomes an opcode; tuple fields
// become the payload bytes that follow it.
component! {
    #[derive(Debug, Default)]
    pub component Counter {
        value: i64,
    }

    instruction {
        Add(i64),
        Print,
    }
}

use counter::runtime::Instruction as CounterInst;

/// Resolved execution input — supplied by the runtime, not encoded in
/// the instruction stream.
#[derive(Debug, Clone, Message)]
pub struct Prefix(pub String);

/// A value the component returns for the runtime or observers to consume.
#[derive(Debug, Clone, PartialEq)]
pub struct Line(pub String);

// One `execute` per component: (instruction, message) in, effects out.
#[dispatch(instruction = counter::runtime::Instruction, message = Prefix, effect = Line)]
impl counter::Counter {
    fn execute(&mut self, inst: &CounterInst, msg: Prefix) -> Result<Effects<Line>> {
        match inst {
            CounterInst::Add(v) => {
                self.value += v;
                Ok(Effects::none())
            }
            CounterInst::Print => Ok(Effects::one(Line(format!("{}{}", msg.0, self.value)))),
        }
    }
}

A component is an execution unit: it takes a typed instruction plus a resolved message and returns typed effects. The derives handle opcodes, encoding, and the runtime glue.

i. Instruction sets

Bytecode as Rust enums

#[derive(Instruction)] turns an enum into an opcode set with inferred (or fixed) encoding width. Nest enums to compose several component instruction families under one machine type.

ii. Components & effects

Execute, then observe

Components consume a resolved Message and return typed Effects. Observers react to those effects with #[observe], keeping execution and delivery cleanly separated.

iii. Pattern-derived syntax

From source text to module

#[derive(Parse)] generates a chumsky parser for your instruction syntax from declarative, compile-time-checked patterns. Module parsing produces typed function bodies for your resolver.

§Install

vihaco is a Cargo workspace of focused crates. vihaco is the foundation — add the others as your project needs them. There is no umbrella crate and no published release yet, so depend on the git repo:

[dependencies]
vihaco        = { git = "https://github.com/QuEraComputing/vihaco" }
vihaco-cpu    = { git = "https://github.com/QuEraComputing/vihaco" }  # optional: a ready-made CPU component
vihaco-parser = { git = "https://github.com/QuEraComputing/vihaco" }  # optional: #[derive(Parse)] for source text

Requires Rust edition 2024.

Continue to the Quick Start →

Continue to the Quick Start, work through the Guides, or browse the API Reference.