Skip to main content

ironwork_rt/lir/
value.rs

1//! Values, expressions and conditions (lir.md §6).
2
3use super::{AbendId, CondId, ConstId, ExprId, FunctionId, Mode, Odo, PlaceId, TempId};
4use crate::codec_enum;
5use crate::vocab::{BinOp, Figurative, RelOp};
6use numeric::precision::Fixed;
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq)]
9pub enum Operand {
10    Load(PlaceId),
11    Const(ConstId),
12    LengthOf(PlaceId),
13    AddressOf(PlaceId),
14    Function(FunctionId),
15}
16
17#[derive(Clone, Debug, PartialEq, Eq)]
18pub enum Const {
19    Bytes(Vec<u8>),
20    National(Vec<u8>),
21    Number(Fixed),
22    Figurative(Figurative),
23    All(Vec<u8>),
24}
25
26/// `Fixed` locates each place of `prepass` before it evaluates `expr`, as the walker's dmax pass
27/// does; static places are left out.
28#[derive(Clone, Debug, PartialEq, Eq)]
29pub enum IntExpr {
30    Const(i64),
31    Item(PlaceId),
32    Fixed { expr: ExprId, dmax: u32, prepass: Vec<PlaceId> },
33    /// Subscript k of the JSON walk in progress (lir.md §9.13): FROM's subscripts, then the
34    /// occurrence of each table the walk has entered. Only a markup payload's places hold it.
35    Walk(u8),
36}
37
38#[derive(Clone, Debug, PartialEq, Eq)]
39pub enum Expr {
40    Operand(Operand),
41    Neg(ExprId),
42    Bin(ExprId, BinOp, ExprId),
43    /// An exponent from 0 to 31, else abend IRONWORK.
44    Pow(ExprId, IntExpr),
45}
46
47#[derive(Clone, Debug, PartialEq, Eq)]
48pub enum Cond {
49    Rel { a: Comparand, op: RelOp, b: Comparand, how: Compare },
50    Class { place: PlaceId, test: ByteClass },
51    Sign { value: Comparand, test: SignTest },
52    /// A level-88 name: equal to any value, or within any THRU pair.
53    Name { subject: PlaceId, values: Vec<(ConstId, Option<ConstId>)>, how: Compare },
54    Not(CondId),
55    And(CondId, CondId),
56    Or(CondId, CondId),
57    Counter(TempId),
58    InTable { index: PlaceId, count: Count },
59    Sql(SqlTest),
60}
61
62/// `Expr` locates each place of `prepass` (the float test's, then for `Mode::Fixed` the dmax pass's,
63/// static ones left out) before it evaluates `expr` in `mode`.
64#[derive(Clone, Debug, PartialEq, Eq)]
65pub enum Comparand {
66    Operand(Operand),
67    Expr { expr: ExprId, dmax: u32, mode: Mode, prepass: Vec<PlaceId> },
68}
69
70#[derive(Clone, Copy, Debug, PartialEq, Eq)]
71pub enum Compare {
72    PackedPfd,
73    Address,
74    Float,
75    Fixed,
76    National,
77    Alphanumeric,
78    Refused(AbendId),
79    /// Two addresses, one side an object reference: equal when both identify the same object, else
80    /// less. Each side is looked up, the first first, and one that was freed or never given abends.
81    References,
82    /// A zoned integer, the first operand when `zoned_first`, against a nonnumeric one: its bytes
83    /// as `rt::store::compared_zoned_bytes` gives them, never its value, compared as alphanumeric.
84    ZonedBytes { zoned_first: bool },
85}
86
87#[derive(Clone, Copy, Debug, PartialEq, Eq)]
88pub enum ByteClass {
89    Packed { signed: bool },
90    Zoned { signed: bool },
91    Digits,
92    Alphabetic,
93    AlphabeticLower,
94    AlphabeticUpper,
95}
96
97#[derive(Clone, Copy, Debug, PartialEq, Eq)]
98pub enum SignTest {
99    Positive,
100    Negative,
101    Zero,
102}
103
104#[derive(Clone, Debug, PartialEq, Eq)]
105pub enum Count {
106    Fixed(u32),
107    Odo(Odo),
108}
109
110/// WHENEVER's classes: SQLCODE < 0, SQLCODE = 100, or a warning.
111#[derive(Clone, Copy, Debug, PartialEq, Eq)]
112pub enum SqlTest {
113    Error,
114    NotFound,
115    Warning,
116}
117
118codec_enum!(Operand { Load(place) = 0, Const(id) = 1, LengthOf(place) = 2, AddressOf(place) = 3, Function(id) = 4 });
119codec_enum!(Const { Bytes(b) = 0, National(n) = 1, Number(f) = 2, Figurative(f) = 3, All(b) = 4 });
120codec_enum!(IntExpr { Const(n) = 0, Item(place) = 1, Fixed { expr, dmax, prepass } = 2, Walk(k) = 3 });
121codec_enum!(Expr { Operand(o) = 0, Neg(e) = 1, Bin(a, op, b) = 2, Pow(base, exponent) = 3 });
122codec_enum!(Cond {
123    Rel { a, op, b, how } = 0,
124    Class { place, test } = 1,
125    Sign { value, test } = 2,
126    Name { subject, values, how } = 3,
127    Not(c) = 4,
128    And(a, b) = 5,
129    Or(a, b) = 6,
130    Counter(t) = 7,
131    InTable { index, count } = 8,
132    Sql(test) = 9,
133});
134codec_enum!(Comparand { Operand(o) = 0, Expr { expr, dmax, mode, prepass } = 1 });
135codec_enum!(Compare {
136    PackedPfd = 0,
137    Address = 1,
138    Float = 2,
139    Fixed = 3,
140    National = 4,
141    Alphanumeric = 5,
142    Refused(abend) = 6,
143    References = 7,
144    ZonedBytes { zoned_first } = 8,
145});
146codec_enum!(ByteClass { Packed { signed } = 0, Zoned { signed } = 1, Digits = 2, Alphabetic = 3, AlphabeticLower = 4, AlphabeticUpper = 5 });
147codec_enum!(SignTest { Positive = 0, Negative = 1, Zero = 2 });
148codec_enum!(Count { Fixed(n) = 0, Odo(odo) = 1 });
149codec_enum!(SqlTest { Error = 0, NotFound = 1, Warning = 2 });