Skip to main content

ironwork_rt/lir/
codec.rs

1//! Codecs for the types the LIR borrows from `rt`, `numeric` and `zarch`, with load-module.md's tags.
2
3use crate::abend::{AbendCode, Ending, FileStatus, Signal};
4use crate::files::Format;
5use crate::module::ModuleError;
6use crate::module::codec::{Decode, Encode, Reader, Writer};
7use crate::picture::Sym;
8use crate::sql::HostType;
9use crate::storage::Kind;
10use crate::vocab::{AcceptFrom, BinOp, Closing, Figurative, InspectMode, OpenMode, Pos, RelOp, SignClause, SignPosition};
11use crate::{codec_enum, codec_struct};
12use numeric::precision::{Fixed, Places};
13use numeric::options::{Compile, FastsrtAdvPrint, Invdata, Stop, Warnings};
14use numeric::{Arith, CicsReturnWarning, Currency, DispSign, IntDate, Nsymbol, Numproc, Options, Qualify, Quote, SortKeys, Trunc, TruncCheck, Vlr, VsamOpenFs};
15use zarch::check::ProgramCheck;
16use zarch::ebcdic::CodePage;
17use zarch::hfp::Precision;
18use zarch::wide::U256;
19
20codec_enum!(Kind {
21    Group = 0,
22    Alnum { justified } = 1,
23    National = 2,
24    Zoned { digits, scale, signed, sign } = 3,
25    Packed { digits, scale, signed } = 4,
26    Binary { digits, scale, signed, native } = 5,
27    Float(precision) = 6,
28    NumericEdited { edit, digits, scale, blank_when_zero } = 7,
29    AlnumEdited { edit } = 8,
30    Pointer = 9,
31    Index = 10,
32    ObjectReference = 11,
33    ProgramPointer = 12,
34});
35codec_struct!(SignClause { position, separate });
36codec_struct!(Pos { file, line, col });
37codec_enum!(SignPosition { Leading = 0, Trailing = 1 });
38codec_enum!(Figurative { Zero = 0, Space = 1, HighValue = 2, LowValue = 3, Quote = 4, Null = 5 });
39codec_enum!(BinOp { Add = 0, Sub = 1, Mul = 2, Div = 3, Pow = 4 });
40codec_enum!(RelOp { Eq = 0, Ne = 1, Lt = 2, Le = 3, Gt = 4, Ge = 5 });
41codec_enum!(AcceptFrom {
42    Sysin = 0,
43    Date { four_digit_year } = 1,
44    Day { four_digit_year } = 2,
45    DayOfWeek = 3,
46    Time = 4,
47});
48codec_enum!(InspectMode { Characters = 0, All = 1, Leading = 2, First = 3 });
49codec_enum!(OpenMode { Input = 0, Output = 1, Extend = 2, InputOutput = 3 });
50codec_enum!(Closing { Volume = 0, NoRewind = 1, Lock = 2 });
51codec_enum!(Format { Fixed = 0, Variable = 1, Text = 2 });
52codec_enum!(HostType {
53    SmallInt { signed } = 0,
54    Integer { signed } = 1,
55    BigInt { signed } = 2,
56    Decimal { digits, scale, signed } = 3,
57    Zoned { digits, scale, signed, sign } = 4,
58    Real = 5,
59    Double = 6,
60    Char(len) = 7,
61    VarChar(max) = 8,
62    Structure(members) = 9,
63});
64codec_enum!(Sym {
65    Nine = 0,
66    Z = 1,
67    Star = 2,
68    FloatLead(c) = 3,
69    Float(c) = 4,
70    Sign(c) = 5,
71    Currency = 6,
72    Cr = 7,
73    Db = 8,
74    Point = 9,
75    Implied = 10,
76    Insert(c) = 11,
77    Char = 12,
78});
79codec_enum!(Precision { Short = 0, Long = 1, Extended = 2 });
80codec_enum!(ProgramCheck {
81    Specification = 0,
82    Data = 1,
83    FixedPointOverflow = 2,
84    FixedPointDivide = 3,
85    DecimalOverflow = 4,
86    DecimalDivide = 5,
87    HfpExponentOverflow = 6,
88    HfpExponentUnderflow = 7,
89    HfpSignificance = 8,
90    HfpDivide = 9,
91});
92
93codec_enum!(Ending { Goback = 0, StopRun = 1, EndOfProgram = 2 });
94codec_enum!(AbendCode {
95    Check(check) = 0,
96    Protection = 1,
97    ModuleNotFound = 2,
98    Io(status) = 3,
99    Cics(code) = 4,
100    User(code) = 5,
101    Ironwork = 6,
102    Exec = 7,
103    Sql = 8,
104    SqlReplay = 9,
105    Java = 10,
106    Signal(signal) = 11,
107});
108codec_enum!(Signal { StopRun = 0, GoBack = 1, SortStopped = 2, ClosedOutput = 3, DeclarativeExit = 4 });
109codec_enum!(FileStatus {
110    Success = 0,
111    SuccessDuplicate = 1,
112    SuccessWrongLength = 2,
113    SuccessOptional = 3,
114    AtEnd = 4,
115    RelativeKeyOverflow = 5,
116    SequenceError = 6,
117    DuplicateKey = 7,
118    NotFound = 8,
119    BoundaryViolation = 9,
120    PermanentError = 10,
121    FileNotFound = 11,
122    OpenModeUnsupported = 12,
123    AlreadyOpen = 13,
124    NotOpen = 14,
125    NoPriorRead = 15,
126    RecordLengthChanged = 16,
127    NoNextRecord = 17,
128    NotOpenInput = 18,
129    NotOpenOutput = 19,
130    NotOpenInputOutput = 20,
131    SuccessNonReel = 21,
132    ClosedWithLock = 22,
133});
134
135codec_struct!(Options {
136    arith, trunc, numproc, codepage, trunc_check, fastsrt, fastsrt_adv_print, sort_keys, adv, thread, dll, rent, dbcs,
137    warnings, compile, dynam, debug, cics_return_warning, invdata, zwb, quote, currency, nsymbol, dispsign, intdate, qualify, initial,
138    vlr, vsamopenfs,
139} check options_valid);
140codec_struct!(Invdata { forcenumcmp, cleansign });
141codec_enum!(Arith { Compat = 0, Extend = 1 });
142codec_enum!(Trunc { Std = 0, Opt = 1, Bin = 2 });
143codec_enum!(Numproc { Nopfd = 0, Pfd = 1 });
144codec_enum!(TruncCheck { Report = 0, Silent = 1 });
145codec_enum!(SortKeys { Dfsort = 0, Strict = 1 });
146codec_enum!(FastsrtAdvPrint { Exclude = 0, Include = 1 });
147codec_enum!(Warnings { Proceed = 0, Block = 1 });
148codec_enum!(Compile { Full = 0, Until(stop) = 1, SyntaxOnly = 2 });
149codec_enum!(Stop { W = 0, E = 1, S = 2 });
150codec_enum!(CicsReturnWarning { Once = 0, Always = 1, Never = 2 });
151codec_enum!(Quote { Quote = 0, Apost = 1 });
152codec_enum!(Currency { Char(c) = 0, Hex(b) = 1 });
153codec_enum!(Nsymbol { National = 0, Dbcs = 1 });
154codec_enum!(DispSign { Compat = 0, Sep = 1 });
155codec_enum!(IntDate { Ansi = 0, Lilian = 1 });
156codec_enum!(Qualify { Compat = 0, Extend = 1 });
157codec_enum!(Vlr { Standard = 0, Compat = 1 });
158codec_enum!(VsamOpenFs { Compat = 0, Succ = 1 });
159
160/// `Options::code_page` panics on a CCSID the tables do not carry.
161fn options_valid(options: &Options) -> Result<(), String> {
162    match CodePage::by_ccsid(options.codepage) {
163        Some(_) => Ok(()),
164        None => Err(format!("CODEPAGE({}) is not a page the tables carry", options.codepage)),
165    }
166}
167
168codec_struct!(Fixed { negative, magnitude, places });
169codec_struct!(Places { int, dec });
170
171/// Four 64-bit limbs, low first.
172impl Encode for U256 {
173    fn encode(&self, w: &mut Writer) {
174        [self.lo as u64, (self.lo >> 64) as u64, self.hi as u64, (self.hi >> 64) as u64].encode(w);
175    }
176}
177
178impl Decode for U256 {
179    fn decode(r: &mut Reader<'_>) -> Result<Self, ModuleError> {
180        let [a, b, c, d] = <[u64; 4]>::decode(r)?;
181        let limbs = |low: u64, high: u64| u128::from(low) | u128::from(high) << 64;
182        Ok(U256 { hi: limbs(c, d), lo: limbs(a, b) })
183    }
184}