Skip to main content

vihaco_cpu/
lib.rs

1// SPDX-FileCopyrightText: 2026 The vihaco Authors
2// SPDX-License-Identifier: MIT
3
4//! Checked word-stack CPU component.
5//!
6//! Enable `vihaco-cpu/typed-declarations` to use the `cpu` runtime dialect and
7//! per-instruction `Execute` implementations. This forwards to the lower runtime
8//! crates; facade applications can instead enable `vihaco/typed-declarations`.
9//! Feature-off use retains the legacy instruction enums and `CPUMessage`.
10//!
11//! The nondefault `program-image-execution` feature implies `typed-declarations`
12//! and switches CPU handlers to typed operands and stack result effects.
13//! `vihaco_stdlib::ExecutionState` owns locals, operands, frames, and the program
14//! counter. Heap storage remains on CPU and uses the same typed transfers.
15//!
16//! With this feature, program instructions and their lowering helpers live in
17//! `vihaco_stdlib::program`; CPU exposes only computation and heap instructions.
18//! The following syntax description and example describe the typed-only route.
19//!
20//! Typed instruction syntax retains readable literals until explicit lowering
21//! encodes them into runtime `Word` payloads. Branch and call targets accept
22//! numeric addresses or `@name` symbols; function references accept numeric
23//! indices or function symbols. String constants accept indices or quoted text.
24//! Loaders supply `lower::LabelLookup`, `lower::FunctionLookup`, and
25//! `lower::StringIntern` to resolve them. `vihaco_stdlib::ProgramImage` implements
26//! string interning using its section string table. Heap references remain numeric.
27//! For explicit metadata, [`vihaco_module::loader::MetadataLoweringContext`] implements
28//! all three lookup capabilities and rejects strings absent from the supplied
29//! table. It works with `ParsedModule::lower_with_metadata` in `vihaco-syntax`.
30//! `label @name` is retained in the parsed function's label metadata without an
31//! executable slot. Labels, `function_start`, and `function_end` have no runtime
32//! instruction leaves.
33//! Composite source uses `device::dialect::mnemonic`, for example
34//! `host::cpu::const_i64 -42`. Generated aggregate bytecode codecs are separate work.
35//!
36//! ```
37//! # #[cfg(all(feature = "typed-declarations", not(feature = "program-image-execution")))]
38//! # {
39//! use vihaco_runtime::{Execute, NoMessage, Lower, Parse, Syntax, chumsky::Parser as _};
40//! use vihaco_module::host::StackMemory;
41//! use vihaco_cpu::{CPU, cpu, encode_i64, StepOutcome};
42//! let instruction = cpu::ConstI64::<Syntax>::parser().parse("const_i64 -42")
43//!     .into_result().unwrap();
44//! let instruction = instruction.lower(&mut ()).unwrap();
45//! assert_eq!(instruction, cpu::ConstI64(encode_i64(-42)));
46//! let mut cpu = CPU::default();
47//! assert_eq!(cpu.execute(&instruction, NoMessage::new()).unwrap(), StepOutcome::Continue);
48//! assert_eq!(cpu.stack(), &[encode_i64(-42)]);
49//! # }
50//! ```
51
52#[cfg(not(feature = "program-image-execution"))]
53mod data;
54
55#[cfg(feature = "program-image-execution")]
56#[path = "program_cpu.rs"]
57mod data;
58
59#[cfg(feature = "typed-declarations")]
60#[cfg_attr(not(feature = "program-image-execution"), path = "cpu.rs")]
61#[cfg_attr(feature = "program-image-execution", path = "computation.rs")]
62mod dialect;
63
64#[cfg(not(feature = "typed-declarations"))]
65mod display;
66
67#[cfg(not(feature = "typed-declarations"))]
68mod instruction;
69
70#[cfg(feature = "typed-declarations")]
71pub use dialect::cpu;
72
73#[cfg(feature = "typed-declarations")]
74mod execute;
75
76#[cfg(all(
77    feature = "typed-declarations",
78    not(feature = "program-image-execution")
79))]
80mod literal;
81
82#[cfg(all(
83    feature = "typed-declarations",
84    not(feature = "program-image-execution")
85))]
86pub mod lower;
87
88#[cfg(all(
89    feature = "typed-declarations",
90    not(feature = "program-image-execution")
91))]
92pub mod message;
93
94#[cfg(all(
95    feature = "typed-declarations",
96    not(feature = "program-image-execution")
97))]
98pub mod operand;
99
100#[cfg(feature = "typed-declarations")]
101#[doc(hidden)]
102pub use data::{__vihaco_fields_CPU, __vihaco_inventory_CPU};
103
104#[cfg(not(feature = "program-image-execution"))]
105mod outcome;
106pub mod word;
107
108pub use data::CPU;
109
110#[cfg(not(feature = "typed-declarations"))]
111pub use data::CPUMessage;
112
113#[cfg(not(feature = "typed-declarations"))]
114pub use data::{RuntimeInstruction, SurfaceInstruction};
115
116#[cfg(not(feature = "typed-declarations"))]
117pub use instruction::{SurfaceType, SurfaceValue};
118
119#[cfg(not(feature = "program-image-execution"))]
120pub use outcome::StepOutcome;
121pub use word::{
122    Word, decode_bool, decode_f32, decode_f64, decode_function_ref, decode_heap_ref, decode_i32,
123    decode_i64, decode_string_id, decode_u32, decode_u64, encode_bool, encode_f32, encode_f64,
124    encode_function_ref, encode_heap_ref, encode_i32, encode_i64, encode_string_id, encode_u32,
125    encode_u64,
126};
127
128#[cfg(all(test, not(feature = "typed-declarations")))]
129mod tests {
130    use super::*;
131
132    #[test]
133    fn surface_instruction_implements_surface_marker() {
134        fn require_surface_instruction<T: vihaco_parser::SurfaceInstruction>() {}
135
136        require_surface_instruction::<SurfaceInstruction>();
137    }
138}