Skip to main content

ironwork_rt/
host.rs

1//! What a statement's semantics ask of the executor running it (semantics-library.md C6): a
2//! handle's `Loc` or value, evaluated where the walker would locate or evaluate it, and the stores.
3//! `P` is the executor's handle to a data item and `O` to any other operand: the LIR's `PlaceId`
4//! and `Operand` in the VM, the walker's own references in the interpreter.
5
6use crate::abend::Abend;
7use crate::storage::{Loc, Val};
8use crate::store::{self, ProgramFacts};
9use crate::vocab::Pos;
10use numeric::precision::{Fixed, Places};
11
12type R<T> = Result<T, Abend>;
13
14pub trait Host<P: Copy> {
15    type Facts: ProgramFacts;
16    fn facts(&self) -> Self::Facts;
17    fn mem(&mut self) -> &mut [u8];
18    /// With `receiving`, a group holding the object of its own OCCURS DEPENDING ON is its maximum length.
19    fn locate(&mut self, place: P, receiving: bool) -> R<Loc>;
20    /// The place's value as a subscript takes it.
21    fn integer(&mut self, place: P, pos: Pos) -> R<i64>;
22    /// MOVE into `dest`; `src` is the sender's storage when it has any.
23    fn assign(&mut self, dest: Loc, val: Val, src: Option<Loc>, pos: Pos) -> R<()>;
24    /// A numeric store, not ROUNDED, with no size error.
25    fn store_fixed(&mut self, dest: Loc, value: &Fixed, pos: Pos) -> R<()>;
26}
27
28pub trait Values<P: Copy, O>: Host<P> {
29    fn value(&mut self, operand: &O, pos: Pos) -> R<Val>;
30}
31
32pub fn read<P: Copy>(x: &mut impl Host<P>, loc: Loc, pos: Pos) -> R<Val> {
33    store::read(&x.facts(), x.mem(), loc, pos)
34}
35
36/// Locates `place` again and stores a whole number in it.
37pub fn set_integer<P: Copy>(x: &mut impl Host<P>, place: P, value: i64, pos: Pos) -> R<()> {
38    let dest = x.locate(place, false)?;
39    x.store_fixed(dest, &Fixed::new(value as i128, Places::new(19, 0)), pos)
40}