1mod arith;
4mod call;
5mod class;
6mod codec;
7mod collating;
8mod debug;
9mod file;
10mod flow;
11mod markup;
12mod payload;
13mod place;
14mod sort;
15mod sql;
16mod text;
17mod value;
18
19pub use arith::{ArithPlan, ArithStep, Mode, RemainderPlan, StepPlan, StorePlan, UpDown};
20pub use call::{CallArg, CallPlan, CallTarget, EntryPoint, LeService};
21pub use class::{Class, ClassPart, Method};
22pub use collating::{Collating, Sequence};
23pub use debug::Debug;
24pub use file::{
25 Access, Advance, Carriage, FileDesc, FileOp, FileVerb, FromMove, IndexKeys, Linage, Organization, Phrase, RecordSpan,
26 RelativeKey, Spacing, StartKey, StartRel,
27};
28pub use markup::{
29 Ccsid, Convert, Flag, Indicator, JsonGenerate, JsonLeaf, JsonNode, JsonParse, JsonValue, Marker, Markup, Named, NumberInto, ParseLeaf, ParseNode, ParseValue,
30 SetTo, XmlForm, XmlGenerate, XmlNode, XmlParse, XmlRegister, XmlValue,
31};
32pub use flow::{Declaratives, Frame, FrameKind, Op, Range, RangeKind, Resume, ReturnPoint, Returns, Step, Terminator};
33pub use crate::cics::CicsCommand;
34pub use crate::report::{ReportOp, Writer as ReportWriter};
35pub use payload::{
36 Argument, DisplayItem, DisplayPlan, FloatFrom, Func, FunctionPlan, Image, InitField, InitPlan,
37 InvokePlan, MethodName, MovePlan, NationalFrom, NumericFrom, Receiver, SearchAllPlan, SearchKey, TrimSide,
38};
39pub use place::{Base, Odo, Place, RefMod, Subscript};
40pub use sort::{FileSort, ReleasePlan, ReturnPlan, SortIo, SortKey, SortKeys, SortPlan, TableSort};
41pub use sql::{HostPlace, SqlEntry, SqlStatement, Sqlca, SqlcaField};
42pub use text::{
43 Bound, Chars, ConvertTable, Converting, DelimiterIn, InspectPhrase, InspectPlan, Replacement, StringPlan,
44 StringSource, UnstringInto, UnstringPlan,
45};
46pub use value::{ByteClass, Compare, Comparand, Cond, Const, Count, Expr, IntExpr, Operand, SignTest, SqlTest};
47
48use crate::abend::AbendCode;
49use crate::{codec_enum, codec_struct};
50use crate::picture::Sym;
51use crate::storage::Kind;
52
53pub type BlockId = u32;
54pub type ParaId = u32;
55pub type RangeId = u32;
56pub type PlaceId = u32;
57pub type ExprId = u32;
58pub type CondId = u32;
59pub type ConstId = u32;
60pub type SymId = u32;
61pub type DebugId = u32;
62pub type AbendId = u32;
63pub type TempId = u16;
65pub type SqlId = u32;
66pub type ArithId = u32;
67pub type InitId = u32;
68pub type DisplayId = u32;
69pub type InspectId = u32;
70pub type StringId = u32;
71pub type UnstringId = u32;
72pub type SearchAllId = u32;
73pub type FunctionId = u32;
74pub type FileOpId = u32;
75pub type CallId = u32;
76pub type SortId = u32;
77pub type ReleaseId = u32;
78pub type ReturnId = u32;
79pub type InvokeId = u32;
80pub type CicsId = u32;
81pub type MarkupId = u32;
82
83#[derive(Clone, Debug, PartialEq, Eq)]
84pub struct Program {
85 pub id: SymId,
86 pub options: ProgramOptions,
87 pub initial: bool,
88 pub recursive: bool,
89 pub storage: Storage,
90 pub items: Vec<Item>,
91 pub paragraphs: Vec<Paragraph>,
92 pub procedure_start: ParaId,
94 pub ranges: Vec<Range>,
95 pub blocks: Vec<Block>,
96 pub places: Vec<Place>,
97 pub exprs: Vec<Expr>,
98 pub conds: Vec<Cond>,
99 pub consts: Vec<Const>,
100 pub plans: Plans,
101 pub services: Services,
102 pub sql: Vec<SqlEntry>,
103 pub abends: Vec<AbendText>,
104 pub edits: Vec<Edit>,
105 pub symbols: Vec<String>,
106 pub debug: Debug,
107}
108
109#[derive(Clone, Debug, PartialEq, Eq)]
110pub struct ProgramOptions {
111 pub options: numeric::Options,
112 pub ssrange: bool,
113 pub cards: Vec<String>,
115 pub collating: Collating,
116 pub decimal_point_comma: bool,
119 pub numval_currency: String,
121 pub when_compiled: Option<CompileTime>,
124}
125
126#[derive(Clone, Debug, PartialEq, Eq)]
129pub struct Edit {
130 pub syms: Vec<Sym>,
131 pub currency: String,
132}
133
134#[derive(Clone, Copy, Debug, PartialEq, Eq)]
137pub struct CompileTime {
138 pub seconds: i64,
139 pub hundredths: u32,
140 pub source: TimeSource,
141}
142
143#[derive(Clone, Copy, Debug, PartialEq, Eq)]
144pub enum TimeSource {
145 SourceDateEpoch,
147 Clock,
148}
149
150impl CompileTime {
151 pub const LATEST: i64 = 253_402_300_799;
153}
154
155#[derive(Clone, Debug, Default, PartialEq, Eq)]
156pub struct Storage {
157 pub size: u32,
158 pub image: Vec<u8>,
160 pub local_image: Vec<u8>,
161 pub init_reports: Vec<SymId>,
163 pub init_abend: Option<AbendId>,
164 pub linkage: Vec<u32>,
166 pub using: Vec<u16>,
167 pub returning: Option<u16>,
168 pub file_areas: Vec<(u32, u32)>,
170}
171
172#[derive(Clone, Debug, PartialEq, Eq)]
174pub struct Item {
175 pub name: Option<SymId>,
176 pub level: u8,
177 pub parent: Option<u32>,
178 pub offset: u32,
179 pub size: u32,
180 pub occurs: u32,
181 pub dims: Vec<(u32, u32)>,
183 pub kind: Kind,
184 pub local: bool,
185 pub linkage: Option<u16>,
186 pub redefines: Option<SymId>,
187 pub depending_on: Option<u32>,
189 pub keys: Vec<(bool, u32)>,
191 pub at: DebugId,
192}
193
194#[derive(Clone, Debug, PartialEq, Eq)]
197pub struct AbendText {
198 pub code: AbendCode,
199 pub message: SymId,
200 pub at: Option<DebugId>,
201}
202
203#[derive(Clone, Copy, Debug, PartialEq, Eq)]
204pub struct Paragraph {
205 pub name: SymId,
206 pub is_section: bool,
207 pub entry: BlockId,
208 pub section_end: ParaId,
210 pub priority: u8,
212 pub at: DebugId,
213 pub abandoned: Option<AbendId>,
216}
217
218#[derive(Clone, Debug, PartialEq, Eq)]
219pub struct Block {
220 pub ops: Vec<Op>,
221 pub end: Terminator,
222}
223
224#[derive(Clone, Debug, Default, PartialEq, Eq)]
226pub struct Plans {
227 pub arith: Vec<ArithPlan>,
228 pub init: Vec<InitPlan>,
229 pub display: Vec<DisplayPlan>,
230 pub inspect: Vec<InspectPlan>,
231 pub string: Vec<StringPlan>,
232 pub unstring: Vec<UnstringPlan>,
233 pub search_all: Vec<SearchAllPlan>,
234 pub function: Vec<FunctionPlan>,
235}
236
237#[derive(Clone, Debug, Default, PartialEq, Eq)]
238pub struct Services {
239 pub file_ops: Vec<FileOp>,
240 pub files: Vec<FileDesc>,
241 pub calls: Vec<CallPlan>,
242 pub sorts: Vec<SortPlan>,
243 pub releases: Vec<ReleasePlan>,
244 pub returns: Vec<ReturnPlan>,
245 pub invokes: Vec<InvokePlan>,
246 pub cics: Vec<CicsCommand>,
247 pub sqlca: Sqlca,
248 pub entries: Vec<EntryPoint>,
250 pub class: Option<Box<Class>>,
252 pub declaratives: Declaratives,
253 pub markup: Vec<Markup>,
255}
256
257codec_struct!(Program {
258 id, options, initial, recursive, storage, items, paragraphs, procedure_start, ranges, blocks, places, exprs,
259 conds, consts, plans, services, sql, abends, edits, symbols, debug,
260} check program_valid);
261codec_struct!(ProgramOptions { options, ssrange, cards, collating, decimal_point_comma, numval_currency, when_compiled });
262codec_struct!(Edit { syms, currency });
263codec_struct!(CompileTime { seconds, hundredths, source } check compile_time_valid);
264codec_enum!(TimeSource { SourceDateEpoch = 0, Clock = 1 });
265codec_struct!(Storage {
266 size, image, local_image, init_reports, init_abend, linkage, using, returning, file_areas,
267} check storage_valid);
268codec_struct!(Item {
269 name, level, parent, offset, size, occurs, dims, kind, local, linkage, redefines, depending_on, keys, at,
270});
271codec_struct!(AbendText { code, message, at });
272codec_struct!(Paragraph { name, is_section, entry, section_end, priority, at, abandoned });
273codec_struct!(Block { ops, end });
274codec_struct!(Plans { arith, init, display, inspect, string, unstring, search_all, function });
275codec_struct!(Services { file_ops, files, calls, sorts, releases, returns, invokes, cics, sqlca, entries, class, declaratives, markup });
276
277pub(crate) fn program_valid(program: &Program) -> Result<(), String> {
278 sql::table_valid(&program.sql, &program.symbols)
279}
280
281fn compile_time_valid(t: &CompileTime) -> Result<(), String> {
282 let whole = t.source == TimeSource::SourceDateEpoch && t.hundredths != 0;
283 if !(0..=CompileTime::LATEST).contains(&t.seconds) || t.hundredths > 99 || whole {
284 return Err(format!("a compile time of {} seconds and {} hundredths from {:?}", t.seconds, t.hundredths, t.source));
285 }
286 Ok(())
287}
288
289fn storage_valid(storage: &Storage) -> Result<(), String> {
290 if u32::try_from(storage.image.len()) == Ok(storage.size) {
291 Ok(())
292 } else {
293 Err(format!("an image of {} bytes for a slab of {}", storage.image.len(), storage.size))
294 }
295}