ironwork-rt 0.1.2

ironwork for COBOL: the runtime a compiled program links, under the runtime exception
Documentation
//! Arithmetic plans (lir.md ยง7): what the walker works out on each execution, fixed at lowering.

use super::{AbendId, ExprId, PlaceId, SymId};
use crate::vocab::SignClause;
use crate::{codec_enum, codec_struct};
use numeric::Arith;
use zarch::hfp::Precision;

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ArithPlan {
    pub dmax: u32,
    pub arith: Arith,
    /// The places the walker's dmax pre-pass locates, in its order, static ones left out.
    pub prepass: Vec<PlaceId>,
    pub steps: Vec<ArithStep>,
    pub remainder: Option<RemainderPlan>,
    /// ON or NOT ON SIZE ERROR is written.
    pub handled: bool,
}

/// `probe` holds the places the walker's float test locates after the receiver, static ones left out.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ArithStep {
    pub target: PlaceId,
    pub expr: ExprId,
    pub mode: Mode,
    pub store: StorePlan,
    pub rounded: bool,
    pub probe: Vec<PlaceId>,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Mode {
    Fixed,
    Float(Precision),
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum StorePlan {
    Zoned { digits: u32, scale: u32, signed: bool, sign: Option<SignClause> },
    Packed { digits: u32, scale: u32, signed: bool },
    /// `name` labels a TRUNC(OPT) report.
    Binary { digits: u32, scale: u32, signed: bool, native: bool, name: SymId },
    NumericEdited { edit: u32, digits: u32, scale: u32, blank_when_zero: bool },
    Float(Precision),
    Index,
    Refused(AbendId),
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct RemainderPlan {
    pub target: PlaceId,
    pub dividend: ExprId,
    pub divisor: ExprId,
    pub quotient_scale: u32,
    pub store: StorePlan,
}

/// PERFORM VARYING's step, SET UP and DOWN BY, and the TALLYING adds: no ROUNDED, no size error.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct StepPlan {
    pub dmax: u32,
    pub store: StorePlan,
}

codec_struct!(ArithPlan { dmax, arith, prepass, steps, remainder, handled });
codec_struct!(ArithStep { target, expr, mode, store, rounded, probe });
codec_enum!(Mode { Fixed = 0, Float(precision) = 1 });
codec_enum!(StorePlan {
    Zoned { digits, scale, signed, sign } = 0,
    Packed { digits, scale, signed } = 1,
    Binary { digits, scale, signed, native, name } = 2,
    NumericEdited { edit, digits, scale, blank_when_zero } = 3,
    Float(precision) = 4,
    Index = 5,
    Refused(abend) = 6,
});
codec_struct!(RemainderPlan { target, dividend, divisor, quotient_scale, store });
codec_struct!(StepPlan { dmax, store });