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