1use crate::Pos;
2
3mod oo;
4pub use oo::*;
5
6#[derive(Clone, Debug, Default, PartialEq, Eq)]
7pub struct Program {
8 pub id: String,
9 pub options: Vec<String>,
11 pub initial: bool,
13 pub recursive: bool,
14 pub working_storage: Vec<DataEntry>,
15 pub local_storage: Vec<DataEntry>,
17 pub linkage: Vec<DataEntry>,
18 pub using: Vec<Param>,
20 pub returning: Option<String>,
21 pub paragraphs: Vec<Paragraph>,
22 pub files: Vec<FileDecl>,
24 pub sources: Vec<String>,
26 pub exec_declarations: Vec<ExecBlock>,
28 pub report_writer: crate::report::ReportWriter,
30 pub declaratives: Declaratives,
32 pub oo: Option<Box<Oo>>,
34 pub environment: Environment,
35 pub nested: Vec<String>,
37}
38
39#[derive(Clone, Debug, PartialEq, Eq)]
40pub struct Param {
41 pub by_value: bool,
42 pub name: String,
43}
44
45#[derive(Clone, Copy, Debug, PartialEq, Eq)]
46pub enum Organization {
47 Sequential,
48 LineSequential,
49 Indexed,
50 Relative,
51}
52
53#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
54pub enum Access {
55 #[default]
56 Sequential,
57 Random,
58 Dynamic,
59}
60
61#[derive(Clone, Debug, PartialEq, Eq)]
62pub struct FileDecl {
63 pub name: String,
64 pub assign: String,
66 pub organization: Organization,
67 pub access: Access,
68 pub record_key: Option<Ref>,
69 pub alternate_keys: Vec<(Ref, bool)>,
71 pub relative_key: Option<Ref>,
72 pub optional: bool,
73 pub status: Option<Ref>,
74 pub recording: Option<char>,
76 pub record_min: Option<u32>,
77 pub record_max: Option<u32>,
78 pub records: Vec<DataEntry>,
79 pub reports: Vec<String>,
81 pub linage: Option<Linage>,
83 pub sort: bool,
85 pub pos: Pos,
86}
87
88#[derive(Clone, Debug, PartialEq, Eq)]
90pub struct Linage {
91 pub lines: LinageValue,
92 pub footing: Option<LinageValue>,
93 pub top: Option<LinageValue>,
94 pub bottom: Option<LinageValue>,
95}
96
97#[derive(Clone, Debug, PartialEq, Eq)]
98pub enum LinageValue {
99 Integer(String),
101 Data(Ref),
102}
103
104pub use rt::vocab::OpenMode;
105
106#[derive(Clone, Debug, PartialEq, Eq)]
107pub enum Advancing {
108 Lines { before: bool, count: Expr },
109 Page { before: bool },
110 Mnemonic { before: bool, name: String, environment: String },
113}
114
115impl Advancing {
116 pub fn before(&self) -> bool {
117 match self {
118 Self::Lines { before, .. } | Self::Page { before } | Self::Mnemonic { before, .. } => *before,
119 }
120 }
121}
122
123#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
124pub enum Usage {
125 #[default]
126 Display,
127 Binary,
128 NativeBinary,
130 Packed,
131 Float1,
132 Float2,
133 National,
134 Pointer,
135 Index,
136 ObjectReference,
137 ProgramPointer,
139}
140
141pub use rt::vocab::{SignClause, SignPosition};
142
143#[derive(Clone, Debug, PartialEq, Eq)]
144pub struct DataEntry {
145 pub level: u8,
146 pub name: Option<String>,
148 pub picture: Option<String>,
149 pub usage: Option<Usage>,
151 pub value: Option<Literal>,
152 pub redefines: Option<String>,
153 pub occurs: Option<u32>,
155 pub depending_on: Option<Ref>,
157 pub sign: Option<SignClause>,
158 pub justified: bool,
159 pub sync: bool,
160 pub blank_when_zero: bool,
161 pub indexed_by: Vec<String>,
163 pub keys: Vec<(bool, Ref)>,
165 pub condition_values: Vec<(Literal, Option<Literal>)>,
168 pub false_value: Option<Literal>,
170 pub renames: Option<(Ref, Option<Ref>)>,
172 pub object_class: Option<String>,
174 pub pos: Pos,
175}
176
177pub use rt::vocab::Figurative;
178
179#[derive(Clone, Debug, PartialEq, Eq)]
180pub enum Literal {
181 Alnum(String),
182 Hex(Vec<u8>),
183 National(String),
184 Number(String),
186 Figurative(Figurative),
187 All(Box<Literal>),
188}
189
190#[derive(Clone, Debug, PartialEq, Eq)]
192pub struct Paragraph {
193 pub name: String,
194 pub statements: Vec<Stmt>,
195 pub section: Option<String>,
197 pub is_section: bool,
198 pub priority: u8,
200 pub pos: Pos,
201}
202
203#[derive(Clone, Debug, PartialEq, Eq)]
205pub struct ProcName {
206 pub name: String,
207 pub section: Option<String>,
208}
209
210#[derive(Clone, Debug, Default, PartialEq, Eq)]
213pub struct Declaratives {
214 pub errors: Vec<UseAfterError>,
215 pub debugging: Vec<UseForDebugging>,
216}
217
218#[derive(Clone, Debug, PartialEq, Eq)]
220pub struct UseAfterError {
221 pub section: usize,
223 pub global: bool,
224 pub on: ErrorUse,
225 pub pos: Pos,
226}
227
228#[derive(Clone, Debug, PartialEq, Eq)]
230pub enum ErrorUse {
231 Files(Vec<String>),
232 Mode(OpenMode),
233}
234
235#[derive(Clone, Debug, PartialEq, Eq)]
237pub struct UseForDebugging {
238 pub section: usize,
239 pub procedures: Vec<ProcName>,
241 pub pos: Pos,
242}
243
244#[derive(Clone, Copy, Debug, PartialEq, Eq)]
245pub enum ExitKind {
246 Plain,
247 Paragraph,
248 Section,
249 Perform,
250 PerformCycle,
251}
252
253#[derive(Clone, Debug, PartialEq, Eq)]
254pub enum Subject {
255 Bool(bool),
256 Expr(Expr),
257 Cond(Cond),
258}
259
260#[derive(Clone, Debug, PartialEq, Eq)]
261pub enum Object {
262 Any,
263 Bool(bool),
264 Cond(Cond),
265 Value { not: bool, from: Expr, thru: Option<Expr> },
266}
267
268#[derive(Clone, Debug, PartialEq, Eq)]
270pub struct When {
271 pub alternatives: Vec<Vec<Object>>,
272 pub body: Vec<Stmt>,
273}
274
275#[derive(Clone, Debug, PartialEq, Eq)]
276pub struct Ref {
277 pub name: String,
278 pub qualifiers: Vec<String>,
279 pub subscripts: Vec<Expr>,
280 pub refmod: Option<RefMod>,
281 pub pos: Pos,
282}
283
284#[derive(Clone, Debug, PartialEq, Eq)]
285pub struct RefMod {
286 pub start: Box<Expr>,
287 pub length: Option<Box<Expr>>,
288}
289
290#[derive(Clone, Debug, PartialEq, Eq)]
291pub struct FunctionCall {
292 pub name: String,
293 pub args: Vec<Expr>,
294 pub modifier: Option<String>,
296 pub refmod: Option<RefMod>,
297 pub pos: Pos,
298}
299
300#[derive(Clone, Debug, PartialEq, Eq)]
301pub enum Operand {
302 Ref(Ref),
303 Literal(Literal),
304 Function(FunctionCall),
305 LengthOf(Ref),
306 AddressOf(Ref),
307}
308
309pub use rt::vocab::{AcceptFrom, BinOp, RelOp};
310
311#[derive(Clone, Debug, PartialEq, Eq)]
312pub enum Expr {
313 Operand(Operand),
314 Neg(Box<Expr>),
315 Bin(Box<Expr>, BinOp, Box<Expr>),
316}
317
318#[derive(Clone, Copy, Debug, PartialEq, Eq)]
319pub enum Class {
320 Numeric,
321 Alphabetic,
322 Positive,
323 Negative,
324 Zero,
325}
326
327#[derive(Clone, Debug, PartialEq, Eq)]
328pub enum Cond {
329 Rel(Expr, RelOp, Expr),
330 Class(Expr, Class),
331 Name(Ref),
332 NameOrRel { subject: Expr, op: RelOp, name: Ref },
335 Not(Box<Cond>),
336 And(Box<Cond>, Box<Cond>),
337 Or(Box<Cond>, Box<Cond>),
338}
339
340#[derive(Clone, Debug, PartialEq, Eq)]
341pub struct Target {
342 pub r: Ref,
343 pub rounded: bool,
344}
345
346#[derive(Clone, Debug, PartialEq, Eq)]
347pub struct Varying {
348 pub var: Ref,
349 pub from: Expr,
350 pub by: Expr,
351 pub until: Cond,
352}
353
354#[derive(Clone, Debug, PartialEq, Eq)]
355pub enum Loop {
356 Once,
357 Times(Expr),
358 Until { cond: Cond, test_after: bool },
359 Varying { varying: Box<Varying>, after: Vec<Varying>, test_after: bool },
361}
362
363#[derive(Clone, Debug, PartialEq, Eq)]
364pub enum Stmt {
365 Move { from: Operand, to: Vec<Ref>, pos: Pos },
366 Compute { targets: Vec<Target>, expr: Expr, size_error: Option<SizeError>, pos: Pos },
367 Arith(Box<Arith>),
369 If { cond: Cond, then: Vec<Stmt>, otherwise: Vec<Stmt>, pos: Pos },
370 PerformInline { body: Vec<Stmt>, repeat: Loop, pos: Pos },
371 PerformProc { from: ProcName, thru: Option<ProcName>, repeat: Loop, pos: Pos },
372 Evaluate { subjects: Vec<Subject>, whens: Vec<When>, other: Vec<Stmt>, pos: Pos },
373 Display { items: Vec<Operand>, no_advancing: bool, pos: Pos },
374 Open { files: Vec<(OpenMode, String)>, pos: Pos },
375 Close { files: Vec<String>, pos: Pos },
376 Read(Box<ReadStmt>),
377 Write { record: Ref, from: Option<Operand>, advancing: Option<Advancing>, invalid: Handlers, end_of_page: Handlers, pos: Pos },
378 Rewrite { record: Ref, from: Option<Operand>, invalid: Handlers, pos: Pos },
379 Delete { file: String, invalid: Handlers, pos: Pos },
380 Start { file: String, key: Option<(RelOp, Ref)>, invalid: Handlers, pos: Pos },
381 Initialize { targets: Vec<Ref>, pos: Pos },
382 GoTo { target: Option<ProcName>, pos: Pos },
384 GoToDepending { targets: Vec<ProcName>, on: Ref, pos: Pos },
386 Alter { pairs: Vec<(ProcName, ProcName)>, pos: Pos },
388 Entry { name: String, using: Vec<Param>, pos: Pos },
390 Goback { pos: Pos },
391 ExitProgram { pos: Pos },
393 Call(Box<Call>),
394 Cancel { targets: Vec<Operand>, pos: Pos },
395 Set { set: SetStmt, pos: Pos },
396 Accept { target: Ref, from: AcceptFrom, pos: Pos },
397 String(Box<StringStmt>),
398 Unstring(Box<Unstring>),
399 Inspect(Box<Inspect>),
400 Search(Box<Search>),
401 NextSentence,
403 SentenceEnd,
405 Exec(Box<ExecBlock>),
406 Report(Box<crate::report::ReportStmt>),
407 Invoke(Box<Invoke>),
408 ExitMethod { pos: Pos },
409 Sorting(Box<Sorting>),
410 StopRun { pos: Pos },
411 Continue,
412 Exit { kind: ExitKind, pos: Pos },
413}
414
415#[derive(Clone, Debug, PartialEq, Eq)]
416pub struct SizeError {
417 pub on: Vec<Stmt>,
418 pub not_on: Vec<Stmt>,
419}
420
421#[derive(Clone, Copy, Debug, PartialEq, Eq)]
422pub enum ArithVerb {
423 Add,
424 Subtract,
425 Multiply,
426 Divide,
427}
428
429#[derive(Clone, Debug, PartialEq, Eq)]
433pub struct Arith {
434 pub verb: ArithVerb,
435 pub computations: Vec<(Target, Expr)>,
436 pub remainder: Option<(Target, Expr, Expr)>,
437 pub size_error: Option<SizeError>,
438 pub pos: Pos,
439}
440
441#[derive(Clone, Copy, Debug, PartialEq, Eq)]
442pub enum ArgMode {
443 Reference,
444 Content,
445 Value,
446}
447
448#[derive(Clone, Debug, PartialEq, Eq)]
450pub struct Arg {
451 pub mode: ArgMode,
452 pub value: Option<Operand>,
453}
454
455#[derive(Clone, Debug, PartialEq, Eq)]
456pub struct Call {
457 pub target: Operand,
458 pub using: Vec<Arg>,
459 pub returning: Option<Ref>,
460 pub on_exception: Option<Vec<Stmt>>,
461 pub not_on_exception: Option<Vec<Stmt>>,
462 pub pos: Pos,
463}
464
465#[derive(Clone, Debug, PartialEq, Eq)]
466pub enum SetStmt {
467 ConditionTrue(Vec<Ref>),
468 ConditionFalse(Vec<Ref>),
470 To { targets: Vec<Ref>, value: Operand },
472 AddressOf { targets: Vec<Ref>, value: Operand },
474 UpDown { targets: Vec<Ref>, down: bool, by: Expr },
475}
476
477#[derive(Clone, Debug, PartialEq, Eq)]
478pub enum Delimiter {
479 Size,
480 By(Operand),
481}
482
483#[derive(Clone, Debug, PartialEq, Eq)]
484pub struct StringStmt {
485 pub sources: Vec<(Operand, Delimiter)>,
486 pub into: Ref,
487 pub pointer: Option<Ref>,
488 pub on_overflow: Option<Vec<Stmt>>,
489 pub not_on_overflow: Option<Vec<Stmt>>,
490 pub pos: Pos,
491}
492
493#[derive(Clone, Debug, PartialEq, Eq)]
494pub struct UnstringInto {
495 pub target: Ref,
496 pub delimiter_in: Option<Ref>,
497 pub count_in: Option<Ref>,
498}
499
500#[derive(Clone, Debug, PartialEq, Eq)]
501pub struct Unstring {
502 pub source: Ref,
503 pub delimiters: Vec<(bool, Operand)>,
505 pub into: Vec<UnstringInto>,
506 pub pointer: Option<Ref>,
507 pub tallying: Option<Ref>,
508 pub on_overflow: Option<Vec<Stmt>>,
509 pub not_on_overflow: Option<Vec<Stmt>>,
510 pub pos: Pos,
511}
512
513#[derive(Clone, Debug, PartialEq, Eq)]
515pub struct Bound {
516 pub after: bool,
517 pub value: Operand,
518}
519
520pub use rt::vocab::InspectMode;
521
522#[derive(Clone, Debug, PartialEq, Eq)]
524pub struct InspectPhrase {
525 pub mode: InspectMode,
526 pub pattern: Option<Operand>,
527 pub by: Option<Operand>,
528 pub counter: Option<Ref>,
529 pub bounds: Vec<Bound>,
530}
531
532#[derive(Clone, Debug, PartialEq, Eq)]
533pub struct Inspect {
534 pub target: Ref,
535 pub tallying: Vec<InspectPhrase>,
536 pub replacing: Vec<InspectPhrase>,
537 pub converting: Option<(Operand, Operand, Vec<Bound>)>,
538 pub pos: Pos,
539}
540
541#[derive(Clone, Debug, PartialEq, Eq)]
542pub struct Search {
543 pub table: Ref,
544 pub all: bool,
545 pub varying: Option<Ref>,
546 pub at_end: Option<Vec<Stmt>>,
547 pub whens: Vec<(Cond, Vec<Stmt>)>,
548 pub pos: Pos,
549}
550
551#[derive(Clone, Copy, Debug, PartialEq, Eq)]
552pub enum ExecKind {
553 Sql,
554 Cics,
555 Dli,
556 Other,
557}
558
559#[derive(Clone, Debug, PartialEq, Eq)]
560pub enum ExecArg {
561 Operand(Operand),
562 Text(String),
564}
565
566#[derive(Clone, Debug, PartialEq, Eq)]
568pub struct ExecBlock {
569 pub kind: ExecKind,
570 pub command: String,
572 pub options: Vec<(String, Option<ExecArg>)>,
574 pub host_variables: Vec<Ref>,
576 pub sql: Option<crate::sql::Sql>,
578 pub text: String,
579 pub pos: Pos,
580}
581
582impl ExecBlock {
583 pub fn declarative(&self) -> bool {
585 self.kind == ExecKind::Sql
586 && matches!(self.command.as_str(), "INCLUDE" | "BEGIN DECLARE SECTION" | "END DECLARE SECTION" | "WHENEVER" | "DECLARE CURSOR" | "DECLARE TABLE" | "DECLARE STATEMENT")
587 }
588}
589
590#[derive(Clone, Debug, Default, PartialEq, Eq)]
592pub struct Handlers {
593 pub on: Option<Vec<Stmt>>,
594 pub not_on: Option<Vec<Stmt>>,
595}
596
597#[derive(Clone, Debug, PartialEq, Eq)]
598pub struct ReadStmt {
599 pub file: String,
600 pub next: bool,
602 pub previous: bool,
603 pub into: Option<Ref>,
604 pub key: Option<Ref>,
606 pub at_end: Handlers,
607 pub invalid: Handlers,
608 pub pos: Pos,
609}
610
611#[derive(Clone, Debug, PartialEq, Eq)]
613pub enum Alphabet {
614 Ebcdic,
615 Native,
616 Standard1,
617 Standard2,
618 Literal(Vec<AlphabetEntry>),
620}
621
622impl Alphabet {
623 pub fn name(&self) -> &'static str {
624 match self {
625 Self::Ebcdic => "EBCDIC",
626 Self::Native => "NATIVE",
627 Self::Standard1 => "STANDARD-1",
628 Self::Standard2 => "STANDARD-2",
629 Self::Literal(_) => "literal",
630 }
631 }
632}
633
634#[derive(Clone, Debug, PartialEq, Eq)]
637pub enum AlphabetEntry {
638 Literal(Literal),
639 Through(Literal, Literal),
640 Also(Vec<Literal>),
641}
642
643#[derive(Clone, Debug, Default, PartialEq, Eq)]
645pub struct Environment {
646 pub alphabets: Vec<(String, Alphabet)>,
648 pub collating_sequence: Option<String>,
650 pub same_record_areas: Vec<Vec<String>>,
652 pub same_areas: Vec<Vec<String>>,
653 pub mnemonics: Vec<(String, String)>,
656 pub debugging_mode: bool,
659 pub decimal_point_comma: bool,
662}
663
664#[derive(Clone, Debug, PartialEq, Eq)]
665pub enum Sorting {
666 Sort(SortStmt),
667 Release { record: Ref, from: Option<Operand>, pos: Pos },
668 Return { file: String, into: Option<Ref>, at_end: Handlers, pos: Pos },
669}
670
671#[derive(Clone, Debug, PartialEq, Eq)]
673pub struct SortStmt {
674 pub merge: bool,
675 pub subject: Ref,
677 pub keys: Vec<(bool, Ref)>,
679 pub duplicates: bool,
680 pub collating: Option<String>,
681 pub input: Option<SortIo>,
682 pub output: Option<SortIo>,
683 pub pos: Pos,
684}
685
686#[derive(Clone, Debug, PartialEq, Eq)]
688pub enum SortIo {
689 Files(Vec<String>),
690 Procedure { from: ProcName, thru: Option<ProcName> },
691}
692