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 pos: Pos,
11 pub options: Vec<String>,
13 pub initial: bool,
16 pub recursive: bool,
17 pub common: bool,
19 pub working_storage: Vec<DataEntry>,
20 pub local_storage: Vec<DataEntry>,
22 pub linkage: Vec<DataEntry>,
23 pub screens: Vec<ScreenEntry>,
25 pub using: Vec<Param>,
27 pub returning: Option<String>,
28 pub paragraphs: Vec<Paragraph>,
29 pub files: Vec<FileDecl>,
31 pub sources: Vec<String>,
33 pub exec_declarations: Vec<ExecBlock>,
35 pub report_writer: crate::report::ReportWriter,
37 pub declaratives: Declaratives,
39 pub oo: Option<Box<Oo>>,
41 pub environment: Environment,
42 pub nested: Vec<String>,
44 pub registers: Vec<String>,
47 pub callable: Vec<String>,
51 pub hidden: Vec<String>,
54 pub duplicates: Vec<(String, Pos)>,
57 pub linked: Vec<String>,
60 pub containers: Vec<Container>,
62 pub messages: Vec<crate::Error>,
64 pub function: Option<Function>,
66 pub prototypes: Vec<Prototype>,
69 pub repository_functions: Vec<String>,
72}
73
74impl Program {
75 pub fn intrinsic(&self, name: &str) -> bool {
77 is_intrinsic_name(name) && !self.repository_functions.iter().any(|f| f == name)
78 }
79}
80
81pub fn is_intrinsic_name(name: &str) -> bool {
83 rt::intrinsic::FIRST.contains(&name) || rt::intrinsic::FUNCTIONS.contains(&name)
84}
85
86impl Program {
87 pub fn load_name(&self) -> &str {
89 self.function.as_ref().map_or(&self.id, |f| &f.external)
90 }
91
92 pub fn is_prototype(&self) -> bool {
93 self.function.as_ref().is_some_and(|f| f.prototype)
94 }
95}
96
97#[derive(Clone, Debug, PartialEq, Eq)]
98pub struct Function {
99 pub external: String,
101 pub prototype: bool,
103 pub pos: Pos,
104}
105
106#[derive(Clone, Debug, PartialEq, Eq)]
108pub struct Prototype {
109 pub name: String,
110 pub external: String,
111 pub using: Vec<Param>,
112 pub returning: Option<String>,
113 pub linkage: Vec<DataEntry>,
114 pub environment: Environment,
116 pub pos: Pos,
117}
118
119#[derive(Clone, Debug, PartialEq, Eq)]
120pub struct Param {
121 pub by_value: bool,
122 pub name: String,
123}
124
125#[derive(Clone, Copy, Debug, PartialEq, Eq)]
126pub enum Organization {
127 Sequential,
128 LineSequential,
129 Indexed,
130 Relative,
131}
132
133#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
134pub enum Access {
135 #[default]
136 Sequential,
137 Random,
138 Dynamic,
139}
140
141#[derive(Clone, Debug, PartialEq, Eq)]
142pub struct FileDecl {
143 pub name: String,
144 pub assign: String,
146 pub assign_item: Option<AssignItem>,
149 pub organization: Organization,
150 pub access: Access,
151 pub record_key: Option<Ref>,
152 pub alternate_keys: Vec<(Ref, bool)>,
154 pub split_keys: Vec<(String, Vec<Ref>)>,
157 pub relative_key: Option<Ref>,
158 pub optional: bool,
159 pub status: Option<Ref>,
160 pub vsam_status: Option<Ref>,
162 pub passwords: Vec<Ref>,
164 pub recording: Option<char>,
166 pub record_min: Option<u32>,
167 pub record_max: Option<u32>,
168 pub record_varying: bool,
171 pub record_depending: Option<Ref>,
173 pub label_records: Vec<Ref>,
176 pub records: Vec<DataEntry>,
177 pub reports: Vec<String>,
179 pub linage: Option<Linage>,
181 pub sort: bool,
183 pub external: bool,
184 pub global: bool,
185 pub declared_in: Option<String>,
187 pub pos: Pos,
188}
189
190impl FileDecl {
191 pub fn split_key(&self, name: &str) -> Option<&[Ref]> {
193 self.split_keys.iter().find(|(key, _)| key == name).map(|(_, pieces)| pieces.as_slice())
194 }
195}
196
197#[derive(Clone, Debug, PartialEq, Eq)]
202pub struct AssignItem {
203 pub reference: Ref,
204 pub explicit: bool,
206 pub declared_if_missing: bool,
209}
210
211#[derive(Clone, Debug, Default, PartialEq, Eq)]
214pub struct Container {
215 pub id: String,
216 pub working_storage: Vec<DataEntry>,
217 pub local_storage: Vec<DataEntry>,
218 pub linkage: Vec<DataEntry>,
219 pub files: Vec<FileDecl>,
220}
221
222#[derive(Clone, Debug, PartialEq, Eq)]
224pub struct Linage {
225 pub lines: LinageValue,
226 pub footing: Option<LinageValue>,
227 pub top: Option<LinageValue>,
228 pub bottom: Option<LinageValue>,
229}
230
231#[derive(Clone, Debug, PartialEq, Eq)]
232pub enum LinageValue {
233 Integer(String),
235 Data(Ref),
236}
237
238pub use rt::vocab::{Closing, OpenMode};
239
240#[derive(Clone, Debug, PartialEq, Eq)]
241pub enum Advancing {
242 Lines { before: bool, count: Expr },
243 Page { before: bool },
244 Mnemonic { before: bool, name: String, environment: String },
247}
248
249impl Advancing {
250 pub fn before(&self) -> bool {
251 match self {
252 Self::Lines { before, .. } | Self::Page { before } | Self::Mnemonic { before, .. } => *before,
253 }
254 }
255}
256
257#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
258pub enum Usage {
259 #[default]
260 Display,
261 Binary,
262 NativeBinary,
264 BinaryChar { signed: bool },
266 CompX,
269 Packed,
270 Float1,
271 Float2,
272 National,
273 Dbcs,
275 Pointer,
276 Index,
277 ObjectReference,
278 ProgramPointer,
280}
281
282pub use rt::vocab::{SignClause, SignPosition};
283
284#[derive(Clone, Debug, PartialEq, Eq)]
285pub struct DataEntry {
286 pub level: u8,
287 pub name: Option<String>,
289 pub spelled: Option<String>,
292 pub picture: Option<String>,
293 pub usage: Option<Usage>,
295 pub value: Option<Literal>,
296 pub redefines: Option<String>,
297 pub occurs: Option<u32>,
299 pub occurs_min: Option<u32>,
302 pub depending_on: Option<Ref>,
304 pub sign: Option<SignClause>,
305 pub justified: bool,
306 pub sync: bool,
307 pub blank_when_zero: bool,
308 pub indexed_by: Vec<String>,
310 pub keys: Vec<(bool, Ref)>,
312 pub condition_values: Vec<(Literal, Option<Literal>)>,
315 pub false_value: Option<Literal>,
317 pub renames: Option<(Ref, Option<Ref>)>,
319 pub object_class: Option<String>,
321 pub external: bool,
323 pub global: bool,
325 pub any_length: bool,
328 pub based: bool,
331 pub pos: Pos,
332}
333
334pub use rt::vocab::Figurative;
335
336#[derive(Clone, Debug, PartialEq, Eq)]
337pub enum Literal {
338 Alnum(String),
339 Hex(Vec<u8>),
340 National(String),
341 Dbcs(String),
343 Number(String),
345 Figurative(Figurative),
346 All(Box<Literal>),
347}
348
349#[derive(Clone, Debug, PartialEq, Eq)]
351pub struct Paragraph {
352 pub name: String,
353 pub statements: Vec<Stmt>,
354 pub section: Option<String>,
356 pub is_section: bool,
357 pub priority: u8,
359 pub pos: Pos,
360}
361
362#[derive(Clone, Debug, PartialEq, Eq)]
364pub struct ProcName {
365 pub name: String,
366 pub section: Option<String>,
367}
368
369#[derive(Clone, Debug, Default, PartialEq, Eq)]
372pub struct Declaratives {
373 pub errors: Vec<UseAfterError>,
374 pub debugging: Vec<UseForDebugging>,
375}
376
377#[derive(Clone, Debug, PartialEq, Eq)]
379pub struct UseAfterError {
380 pub section: usize,
382 pub global: bool,
383 pub on: ErrorUse,
384 pub pos: Pos,
385}
386
387#[derive(Clone, Debug, PartialEq, Eq)]
389pub enum ErrorUse {
390 Files(Vec<String>),
391 Mode(OpenMode),
392}
393
394#[derive(Clone, Debug, PartialEq, Eq)]
396pub struct UseForDebugging {
397 pub section: usize,
398 pub procedures: Vec<ProcName>,
400 pub pos: Pos,
401}
402
403#[derive(Clone, Copy, Debug, PartialEq, Eq)]
404pub enum ExitKind {
405 Plain,
406 Paragraph,
407 Section,
408 Perform,
409 PerformCycle,
410}
411
412#[derive(Clone, Debug, PartialEq, Eq)]
413pub enum Subject {
414 Bool(bool),
415 Expr(Expr),
416 Cond(Cond),
417}
418
419#[derive(Clone, Debug, PartialEq, Eq)]
420pub enum Object {
421 Any,
422 Bool(bool),
423 Cond(Cond),
424 Value { not: bool, from: Expr, thru: Option<Expr> },
425}
426
427#[derive(Clone, Debug, PartialEq, Eq)]
429pub struct When {
430 pub alternatives: Vec<Vec<Object>>,
431 pub body: Vec<Stmt>,
432}
433
434#[derive(Clone, Debug, PartialEq, Eq)]
435pub struct Ref {
436 pub name: String,
437 pub qualifiers: Vec<String>,
438 pub subscripts: Vec<Expr>,
439 pub refmod: Option<RefMod>,
440 pub pos: Pos,
441}
442
443#[derive(Clone, Debug, PartialEq, Eq)]
444pub struct RefMod {
445 pub start: Box<Expr>,
446 pub length: Option<Box<Expr>>,
447}
448
449#[derive(Clone, Debug, PartialEq, Eq)]
450pub struct FunctionCall {
451 pub name: String,
452 pub args: Vec<Expr>,
453 pub modifier: Option<String>,
455 pub refmod: Option<RefMod>,
456 pub all_subscripts: Vec<(usize, Vec<usize>)>,
459 pub pos: Pos,
460}
461
462#[derive(Clone, Debug, PartialEq, Eq)]
463pub enum Operand {
464 Ref(Ref),
465 Literal(Literal),
466 Function(FunctionCall),
467 LengthOf(Ref),
468 AddressOf(Ref),
469}
470
471pub use rt::vocab::{AcceptFrom, BinOp, RelOp};
472
473#[derive(Clone, Debug, PartialEq, Eq)]
474pub enum Expr {
475 Operand(Operand),
476 Neg(Box<Expr>),
477 Bin(Box<Expr>, BinOp, Box<Expr>),
478}
479
480#[derive(Clone, Debug, PartialEq, Eq)]
481pub enum Class {
482 Numeric,
483 Alphabetic,
484 AlphabeticLower,
485 AlphabeticUpper,
486 Dbcs,
488 Kanji,
490 Positive,
491 Negative,
492 Zero,
493 Named(String),
495}
496
497#[derive(Clone, Debug, PartialEq, Eq)]
498pub enum Cond {
499 Rel(Expr, RelOp, Expr),
500 Class(Expr, Class),
501 Name(Ref),
502 NameOrRel { subject: Expr, op: RelOp, negated: bool, name: Ref },
506 Not(Box<Cond>),
507 And(Box<Cond>, Box<Cond>),
508 Or(Box<Cond>, Box<Cond>),
509}
510
511#[derive(Clone, Debug, PartialEq, Eq)]
512pub struct Target {
513 pub r: Ref,
514 pub rounded: bool,
515}
516
517#[derive(Clone, Debug, PartialEq, Eq)]
518pub struct Varying {
519 pub var: Ref,
520 pub from: Expr,
521 pub by: Expr,
522 pub until: Cond,
523}
524
525#[derive(Clone, Debug, PartialEq, Eq)]
526pub enum Loop {
527 Once,
528 Times(Expr),
529 Until { cond: Cond, test_after: bool },
530 Forever,
533 Varying { varying: Box<Varying>, after: Vec<Varying>, test_after: bool },
535}
536
537#[derive(Clone, Debug, PartialEq, Eq)]
538pub enum Stmt {
539 Move { from: Operand, to: Vec<Ref>, pos: Pos },
540 Compute { targets: Vec<Target>, expr: Expr, size_error: Option<SizeError>, pos: Pos },
541 Arith(Box<Arith>),
543 Corresponding(Box<Corresponding>),
546 If { cond: Cond, then: Vec<Stmt>, otherwise: Vec<Stmt>, pos: Pos },
547 PerformInline { body: Vec<Stmt>, repeat: Loop, pos: Pos },
548 PerformProc { from: ProcName, thru: Option<ProcName>, repeat: Loop, pos: Pos },
549 Evaluate { subjects: Vec<Subject>, whens: Vec<When>, other: Vec<Stmt>, pos: Pos },
550 Display { items: Vec<Operand>, upon: Option<Upon>, no_advancing: bool, screen: Option<Box<ScreenPhrases>>, pos: Pos },
553 Open { files: Vec<(OpenMode, String)>, pos: Pos },
554 Close { files: Vec<(String, Option<Closing>)>, pos: Pos },
555 Read(Box<ReadStmt>),
556 Write { record: Ref, from: Option<Operand>, advancing: Option<Advancing>, invalid: Handlers, end_of_page: Handlers, pos: Pos },
557 Rewrite { record: Ref, from: Option<Operand>, invalid: Handlers, pos: Pos },
558 Delete { file: String, invalid: Handlers, pos: Pos },
559 DeleteFile { files: Vec<String>, pos: Pos },
562 Start { file: String, key: Option<(RelOp, Ref)>, invalid: Handlers, pos: Pos },
563 Initialize { targets: Vec<Ref>, with: Option<Box<InitializeWith>>, pos: Pos },
565 GoTo { target: Option<ProcName>, pos: Pos },
567 GoToDepending { targets: Vec<ProcName>, on: Ref, pos: Pos },
569 Alter { pairs: Vec<(ProcName, ProcName)>, pos: Pos },
571 Entry { name: String, using: Vec<Param>, pos: Pos },
573 Goback { pos: Pos },
574 ExitProgram { pos: Pos },
576 Call(Box<Call>),
577 Cancel { targets: Vec<Operand>, pos: Pos },
578 Set { set: SetStmt, pos: Pos },
579 Accept { target: Ref, from: AcceptFrom, exception: Handlers, screen: Option<Box<ScreenPhrases>>, pos: Pos },
583 String(Box<StringStmt>),
584 Unstring(Box<Unstring>),
585 Inspect(Box<Inspect>),
586 Search(Box<Search>),
587 NextSentence,
589 SentenceEnd,
591 Exec(Box<ExecBlock>),
592 Report(Box<crate::report::ReportStmt>),
593 Invoke(Box<Invoke>),
594 JsonGenerate(Box<JsonGenerate>),
595 JsonParse(Box<JsonParse>),
596 XmlParse(Box<XmlParse>),
597 XmlGenerate(Box<XmlGenerate>),
598 ExitMethod { pos: Pos },
599 Sorting(Box<Sorting>),
600 StopRun { pos: Pos },
601 Continue { pos: Pos },
602 Exit { kind: ExitKind, pos: Pos },
603}
604
605#[derive(Clone, Debug, PartialEq, Eq)]
606pub struct SizeError {
607 pub on: Vec<Stmt>,
608 pub not_on: Vec<Stmt>,
609}
610
611#[derive(Clone, Copy, Debug, PartialEq, Eq)]
612pub enum ArithVerb {
613 Add,
614 Subtract,
615 Multiply,
616 Divide,
617}
618
619#[derive(Clone, Debug, PartialEq, Eq)]
623pub struct Arith {
624 pub verb: ArithVerb,
625 pub computations: Vec<(Target, Expr)>,
626 pub remainder: Option<(Target, Expr, Expr)>,
627 pub size_error: Option<SizeError>,
628 pub pos: Pos,
629}
630
631#[derive(Clone, Copy, Debug, PartialEq, Eq)]
632pub enum CorrespondingVerb {
633 Move,
634 Add,
635 Subtract,
636}
637
638#[derive(Clone, Debug, PartialEq, Eq)]
641pub struct Corresponding {
642 pub verb: CorrespondingVerb,
643 pub from: Ref,
644 pub to: Ref,
645 pub rounded: bool,
646 pub size_error: Option<SizeError>,
647 pub pos: Pos,
648}
649
650#[derive(Clone, Copy, Debug, PartialEq, Eq)]
651pub enum ArgMode {
652 Reference,
653 Content,
654 Value,
655}
656
657#[derive(Clone, Debug, PartialEq, Eq)]
659pub struct Arg {
660 pub mode: ArgMode,
661 pub value: Option<Operand>,
662}
663
664#[derive(Clone, Debug, PartialEq, Eq)]
665pub struct Call {
666 pub target: Operand,
667 pub using: Vec<Arg>,
668 pub returning: Option<Ref>,
669 pub on_exception: Option<Vec<Stmt>>,
670 pub not_on_exception: Option<Vec<Stmt>>,
671 pub pos: Pos,
672}
673
674#[derive(Clone, Debug, PartialEq, Eq)]
675pub enum SetStmt {
676 ConditionTrue(Vec<Ref>),
677 ConditionFalse(Vec<Ref>),
679 To { targets: Vec<Ref>, value: Operand },
681 Entry { targets: Vec<Ref>, entry: Operand },
683 AddressOf { targets: Vec<Ref>, value: Operand },
685 UpDown { targets: Vec<Ref>, down: bool, by: Expr },
686 Switches(Vec<(Vec<Ref>, bool)>),
688}
689
690#[derive(Clone, Debug, PartialEq, Eq)]
691pub enum Delimiter {
692 Size,
693 By(Operand),
694}
695
696#[derive(Clone, Debug, PartialEq, Eq)]
697pub struct StringStmt {
698 pub sources: Vec<(Operand, Delimiter)>,
699 pub into: Ref,
700 pub pointer: Option<Ref>,
701 pub on_overflow: Option<Vec<Stmt>>,
702 pub not_on_overflow: Option<Vec<Stmt>>,
703 pub pos: Pos,
704}
705
706#[derive(Clone, Debug, PartialEq, Eq)]
707pub struct UnstringInto {
708 pub target: Ref,
709 pub delimiter_in: Option<Ref>,
710 pub count_in: Option<Ref>,
711}
712
713#[derive(Clone, Debug, PartialEq, Eq)]
714pub struct Unstring {
715 pub source: Ref,
716 pub delimiters: Vec<(bool, Operand)>,
718 pub into: Vec<UnstringInto>,
719 pub pointer: Option<Ref>,
720 pub tallying: Option<Ref>,
721 pub on_overflow: Option<Vec<Stmt>>,
722 pub not_on_overflow: Option<Vec<Stmt>>,
723 pub pos: Pos,
724}
725
726#[derive(Clone, Debug, PartialEq, Eq)]
728pub struct Bound {
729 pub after: bool,
730 pub value: Operand,
731}
732
733pub use rt::vocab::InspectMode;
734
735#[derive(Clone, Debug, PartialEq, Eq)]
737pub struct InspectPhrase {
738 pub mode: InspectMode,
739 pub pattern: Option<Operand>,
740 pub by: Option<Operand>,
741 pub counter: Option<Ref>,
742 pub bounds: Vec<Bound>,
743}
744
745#[derive(Clone, Copy, Debug, PartialEq, Eq)]
748pub enum DataCategory {
749 Alphabetic,
750 Alphanumeric,
751 AlphanumericEdited,
752 Dbcs,
753 National,
754 NationalEdited,
755 Numeric,
756 NumericEdited,
757 Utf8,
758}
759
760impl DataCategory {
761 pub const ALL: [Self; 9] = [
762 Self::Alphabetic,
763 Self::Alphanumeric,
764 Self::AlphanumericEdited,
765 Self::Dbcs,
766 Self::National,
767 Self::NationalEdited,
768 Self::Numeric,
769 Self::NumericEdited,
770 Self::Utf8,
771 ];
772
773 pub fn from_word(word: &str) -> Option<Self> {
774 Some(match word {
775 "ALPHABETIC" => Self::Alphabetic,
776 "ALPHANUMERIC" => Self::Alphanumeric,
777 "ALPHANUMERIC-EDITED" => Self::AlphanumericEdited,
778 "DBCS" | "EGCS" => Self::Dbcs,
779 "NATIONAL" => Self::National,
780 "NATIONAL-EDITED" => Self::NationalEdited,
781 "NUMERIC" => Self::Numeric,
782 "NUMERIC-EDITED" => Self::NumericEdited,
783 "UTF-8" => Self::Utf8,
784 _ => return None,
785 })
786 }
787
788 pub fn word(self) -> &'static str {
789 match self {
790 Self::Alphabetic => "ALPHABETIC",
791 Self::Alphanumeric => "ALPHANUMERIC",
792 Self::AlphanumericEdited => "ALPHANUMERIC-EDITED",
793 Self::Dbcs => "DBCS",
794 Self::National => "NATIONAL",
795 Self::NationalEdited => "NATIONAL-EDITED",
796 Self::Numeric => "NUMERIC",
797 Self::NumericEdited => "NUMERIC-EDITED",
798 Self::Utf8 => "UTF-8",
799 }
800 }
801}
802
803#[derive(Clone, Debug, Default, PartialEq, Eq)]
805pub struct InitializeWith {
806 pub filler: bool,
807 pub value: Vec<DataCategory>,
808 pub replacing: Vec<(DataCategory, Operand)>,
809 pub default: bool,
810}
811
812#[derive(Clone, Copy, Debug, PartialEq, Eq)]
814pub enum InitialValue<'a> {
815 Value,
817 Replacing(&'a Operand),
818 Default,
820}
821
822impl InitializeWith {
823 pub fn initial_value(&self, category: Option<DataCategory>, has_value: bool) -> Option<InitialValue<'_>> {
827 let named = |c: DataCategory| category == Some(c);
828 if has_value && self.value.iter().any(|&c| named(c)) {
829 return Some(InitialValue::Value);
830 }
831 if let Some((_, by)) = self.replacing.iter().find(|(c, _)| named(*c)) {
832 return Some(InitialValue::Replacing(by));
833 }
834 (self.default || self.value.is_empty() && self.replacing.is_empty()).then_some(InitialValue::Default)
835 }
836}
837
838#[derive(Clone, Debug, PartialEq, Eq)]
840pub struct Inspect {
841 pub target: Operand,
842 pub tallying: Vec<InspectPhrase>,
843 pub replacing: Vec<InspectPhrase>,
844 pub converting: Option<(Operand, Operand, Vec<Bound>)>,
845 pub pos: Pos,
846}
847
848#[derive(Clone, Debug, PartialEq, Eq)]
849pub struct Search {
850 pub table: Ref,
851 pub all: bool,
852 pub varying: Option<Ref>,
853 pub at_end: Option<Vec<Stmt>>,
854 pub whens: Vec<(Cond, Vec<Stmt>)>,
855 pub pos: Pos,
856}
857
858#[derive(Clone, Copy, Debug, PartialEq, Eq)]
859pub enum ExecKind {
860 Sql,
861 Cics,
862 Dli,
863 Other,
864}
865
866#[derive(Clone, Debug, PartialEq, Eq)]
867pub enum ExecArg {
868 Operand(Operand),
869 Text(String),
871}
872
873#[derive(Clone, Debug, PartialEq, Eq)]
875pub struct ExecBlock {
876 pub kind: ExecKind,
877 pub command: String,
879 pub options: Vec<(String, Option<ExecArg>)>,
881 pub host_variables: Vec<Ref>,
883 pub sql: Option<crate::sql::Sql>,
885 pub text: String,
886 pub pos: Pos,
887}
888
889impl ExecBlock {
890 pub fn declarative(&self) -> bool {
892 self.kind == ExecKind::Sql
893 && matches!(self.command.as_str(), "INCLUDE" | "BEGIN DECLARE SECTION" | "END DECLARE SECTION" | "WHENEVER" | "DECLARE CURSOR" | "DECLARE TABLE" | "DECLARE STATEMENT")
894 }
895}
896
897#[derive(Clone, Debug, Default, PartialEq, Eq)]
899pub struct Handlers {
900 pub on: Option<Vec<Stmt>>,
901 pub not_on: Option<Vec<Stmt>>,
902}
903
904#[derive(Clone, Debug, PartialEq, Eq)]
905pub struct ReadStmt {
906 pub file: String,
907 pub next: bool,
909 pub previous: bool,
910 pub into: Option<Ref>,
911 pub key: Option<Ref>,
913 pub at_end: Handlers,
914 pub invalid: Handlers,
915 pub pos: Pos,
916}
917
918#[derive(Clone, Debug, PartialEq, Eq)]
920pub enum Alphabet {
921 Ebcdic,
922 Native,
923 Standard1,
924 Standard2,
925 Literal(Vec<AlphabetEntry>),
927}
928
929impl Alphabet {
930 pub fn name(&self) -> &'static str {
931 match self {
932 Self::Ebcdic => "EBCDIC",
933 Self::Native => "NATIVE",
934 Self::Standard1 => "STANDARD-1",
935 Self::Standard2 => "STANDARD-2",
936 Self::Literal(_) => "literal",
937 }
938 }
939}
940
941#[derive(Clone, Debug, PartialEq, Eq)]
944pub enum AlphabetEntry {
945 Literal(Literal),
946 Through(Literal, Literal),
947 Also(Vec<Literal>),
948}
949
950#[derive(Clone, Debug, Default, PartialEq, Eq)]
952pub struct Environment {
953 pub alphabets: Vec<(String, Alphabet)>,
955 pub collating_sequence: Option<String>,
957 pub same_record_areas: Vec<Vec<String>>,
959 pub same_areas: Vec<Vec<String>>,
960 pub mnemonics: Vec<(String, String)>,
963 pub debugging_mode: bool,
966 pub decimal_point_comma: bool,
969 pub currency: Vec<CurrencySign>,
971 pub switches: Vec<Switch>,
973 pub classes: Vec<ClassClause>,
975}
976
977#[derive(Clone, Debug, PartialEq, Eq)]
979pub struct ClassClause {
980 pub name: String,
981 pub members: Vec<(Literal, Option<Literal>)>,
982 pub pos: Pos,
983}
984
985#[derive(Clone, Debug, PartialEq, Eq)]
988pub struct Switch {
989 pub number: u8,
990 pub mnemonic: Option<String>,
991 pub on: Option<String>,
992 pub off: Option<String>,
993 pub pos: Pos,
994}
995
996#[derive(Clone, Debug, Default, PartialEq, Eq)]
1000pub struct ScreenPhrases {
1001 pub at: Option<ScreenAt>,
1002 pub blank_screen: bool,
1003 pub blank_line: bool,
1004 pub erase_eol: bool,
1005 pub erase_eos: bool,
1006 pub update: bool,
1007 pub secure: bool,
1008 pub attributes: Vec<String>,
1009 pub screen: Option<String>,
1012 pub inputs: Vec<ScreenInput>,
1013 pub pos: Pos,
1014}
1015
1016#[derive(Clone, Debug, PartialEq, Eq)]
1019pub struct ScreenInput {
1020 pub field: Ref,
1021 pub target: Ref,
1022 pub line: u32,
1023 pub column: u32,
1024 pub update: bool,
1025 pub secure: bool,
1026}
1027
1028#[derive(Clone, Debug, Default, PartialEq, Eq)]
1030pub struct ScreenEntry {
1031 pub level: u8,
1032 pub name: Option<String>,
1033 pub line: Option<ScreenPlace>,
1034 pub column: Option<ScreenPlace>,
1035 pub value: Option<Literal>,
1036 pub picture: Option<String>,
1037 pub from: Option<Operand>,
1038 pub to: Option<Ref>,
1039 pub using: Option<Ref>,
1040 pub blank_screen: bool,
1041 pub blank_line: bool,
1042 pub erase_eol: bool,
1043 pub erase_eos: bool,
1044 pub secure: bool,
1045 pub attributes: Vec<String>,
1046 pub pos: Pos,
1047}
1048
1049#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1052pub enum ScreenPlace {
1053 At(u32),
1054 Plus(u32),
1055 Minus(u32),
1056}
1057
1058#[derive(Clone, Debug, PartialEq, Eq)]
1059pub enum ScreenAt {
1060 Combined(Operand),
1062 LineColumn { line: Option<Operand>, column: Option<Operand> },
1063}
1064
1065#[derive(Clone, Debug, PartialEq, Eq)]
1068pub struct Upon {
1069 pub name: String,
1070 pub device: String,
1071}
1072
1073#[derive(Clone, Debug, PartialEq, Eq)]
1075pub struct CurrencySign {
1076 pub value: String,
1077 pub symbol: char,
1078 pub hex: Option<Vec<u8>>,
1081}
1082
1083pub const HEX_SYMBOL: char = '\0';
1085
1086#[derive(Clone, Debug, PartialEq, Eq)]
1087pub enum Sorting {
1088 Sort(SortStmt),
1089 Release { record: Ref, from: Option<Operand>, pos: Pos },
1090 Return { file: String, into: Option<Ref>, at_end: Handlers, pos: Pos },
1091}
1092
1093#[derive(Clone, Debug, PartialEq, Eq)]
1095pub struct SortStmt {
1096 pub merge: bool,
1097 pub subject: Ref,
1099 pub keys: Vec<(bool, Ref)>,
1101 pub duplicates: bool,
1102 pub collating: Option<String>,
1103 pub input: Option<SortIo>,
1104 pub output: Option<SortIo>,
1105 pub pos: Pos,
1106}
1107
1108#[derive(Clone, Debug, PartialEq, Eq)]
1110pub enum SortIo {
1111 Files(Vec<String>),
1112 Procedure { from: ProcName, thru: Option<ProcName> },
1113}
1114
1115
1116#[derive(Clone, Debug, PartialEq, Eq)]
1118pub struct JsonGenerate {
1119 pub receiver: Ref,
1120 pub from: Ref,
1121 pub count: Option<Ref>,
1122 pub names: Vec<(Ref, Option<Literal>)>,
1124 pub suppress: Vec<Suppression>,
1125 pub converting: Vec<(Ref, JsonConversion)>,
1126 pub indicating: Vec<NullIndicator>,
1127 pub encoding: Option<Encoding>,
1128 pub on_exception: Option<Vec<Stmt>>,
1129 pub not_on_exception: Option<Vec<Stmt>>,
1130 pub pos: Pos,
1131}
1132
1133#[derive(Clone, Debug, PartialEq, Eq)]
1137pub enum Suppression {
1138 Item { item: Ref, when: Vec<Figurative> },
1139 Every { numeric: Option<bool>, form: Option<XmlForm>, when: Vec<Figurative> },
1140}
1141
1142#[derive(Clone, Debug, PartialEq, Eq)]
1145pub enum Marker {
1146 Condition(Ref),
1147 Literal(Literal),
1148}
1149
1150#[derive(Clone, Debug, PartialEq, Eq)]
1151pub enum JsonConversion {
1152 Boolean(Marker),
1153 Null(Figurative),
1154}
1155
1156#[derive(Clone, Debug, PartialEq, Eq)]
1158pub struct NullIndicator {
1159 pub item: Ref,
1160 pub marker: Marker,
1161 pub indicator: Option<Ref>,
1162}
1163
1164#[derive(Clone, Debug, PartialEq, Eq)]
1165pub enum Encoding {
1166 Ccsid(Operand),
1167 FromCodepage,
1168}
1169
1170#[derive(Clone, Debug, PartialEq, Eq)]
1172pub struct JsonParse {
1173 pub source: Ref,
1174 pub into: Ref,
1175 pub detail: bool,
1176 pub ignoring: Vec<Option<Ref>>,
1178 pub indicating: Vec<(Ref, Flag, Option<Ref>)>,
1180 pub encoding: Option<Encoding>,
1181 pub names: Vec<(Ref, Option<Literal>)>,
1183 pub suppress: Vec<Ref>,
1184 pub converting: Vec<(Ref, ParseConversion)>,
1185 pub on_exception: Option<Vec<Stmt>>,
1186 pub not_on_exception: Option<Vec<Stmt>>,
1187 pub pos: Pos,
1188}
1189
1190#[derive(Clone, Debug, PartialEq, Eq)]
1194pub enum Flag {
1195 Condition(Ref),
1196 Conditions(Ref, Ref),
1197 Literals(Literal, Literal),
1198}
1199
1200#[derive(Clone, Debug, PartialEq, Eq)]
1201pub enum ParseConversion {
1202 Boolean(Box<Flag>),
1203 Null(Figurative),
1204}
1205
1206#[derive(Clone, Debug, PartialEq, Eq)]
1208pub struct XmlGenerate {
1209 pub receiver: Ref,
1210 pub from: Ref,
1211 pub count: Option<Ref>,
1212 pub encoding: Option<Operand>,
1214 pub declaration: bool,
1215 pub attributes: bool,
1216 pub namespace: Option<Operand>,
1217 pub prefix: Option<Operand>,
1218 pub names: Vec<(Ref, Literal)>,
1219 pub types: Vec<(Ref, XmlForm)>,
1220 pub suppress: Vec<Suppression>,
1221 pub on_exception: Option<Vec<Stmt>>,
1222 pub not_on_exception: Option<Vec<Stmt>>,
1223 pub pos: Pos,
1224}
1225
1226#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1228pub enum XmlForm {
1229 Attribute,
1230 Element,
1231 Content,
1232}
1233
1234#[derive(Clone, Debug, PartialEq, Eq)]
1236pub struct XmlParse {
1237 pub document: Ref,
1238 pub encoding: Option<Operand>,
1240 pub returning_national: bool,
1241 pub procedure: ProcName,
1242 pub thru: Option<ProcName>,
1243 pub on_exception: Option<Vec<Stmt>>,
1244 pub not_on_exception: Option<Vec<Stmt>>,
1245 pub pos: Pos,
1246}