Skip to main content

ironwork_syntax/
report.rs

1//! The REPORT SECTION as written: report descriptions with their report groups, the INITIATE,
2//! GENERATE, TERMINATE and SUPPRESS statements, and USE BEFORE REPORTING procedures.
3
4use crate::Pos;
5use crate::ast::{Expr, Literal, Ref, SignClause};
6pub use rt::report::{ColumnNumber, Footing, LineNumber, NextGroup};
7
8#[derive(Clone, Debug, Default, PartialEq, Eq)]
9pub struct ReportWriter {
10    pub reports: Vec<Report>,
11    pub uses: Vec<UseBeforeReporting>,
12    /// Paragraphs before this index are the DECLARATIVES, which run only when invoked.
13    pub procedure_start: usize,
14}
15
16/// An RD entry and the report groups that follow it.
17#[derive(Clone, Debug, PartialEq, Eq)]
18pub struct Report {
19    pub name: String,
20    /// CODE literal: prefixed to every record the report writes.
21    pub code: Option<Literal>,
22    /// CONTROL identifiers, major to minor. FINAL is always the highest level, written or not.
23    pub controls: Vec<Ref>,
24    pub page: Option<u32>,
25    pub heading: Option<u32>,
26    pub first_detail: Option<u32>,
27    pub last_detail: Option<u32>,
28    pub footing: Option<Footing>,
29    pub line_limit: Option<u32>,
30    pub groups: Vec<Group>,
31    pub pos: Pos,
32}
33
34#[derive(Clone, Debug, PartialEq, Eq)]
35pub enum ControlName {
36    Final,
37    Item(Ref),
38}
39
40#[derive(Clone, Debug, PartialEq, Eq)]
41pub enum GroupType {
42    ReportHeading,
43    PageHeading,
44    /// CONTROL HEADING, for the control named or the only one there is.
45    ControlHeading(Option<ControlName>),
46    Detail,
47    ControlFooting(Option<ControlName>),
48    PageFooting,
49    ReportFooting,
50}
51
52#[derive(Clone, Debug, PartialEq, Eq)]
53pub struct SumClause {
54    pub operands: Vec<Ref>,
55    /// UPON: the DETAIL groups whose GENERATE adds the operands.
56    pub upon: Vec<Ref>,
57    pub reset: Option<ControlName>,
58}
59
60#[derive(Clone, Debug, PartialEq, Eq)]
61pub enum Content {
62    Source(Expr),
63    Value(Literal),
64    Sum(Vec<SumClause>),
65}
66
67/// A report group: its 01-level entry, then every entry below it, in order.
68#[derive(Clone, Debug, PartialEq, Eq)]
69pub struct Group {
70    pub name: Option<String>,
71    pub kind: GroupType,
72    pub next_group: Option<NextGroup>,
73    pub entries: Vec<Entry>,
74    pub pos: Pos,
75}
76
77#[derive(Clone, Debug, PartialEq, Eq)]
78pub struct Entry {
79    pub level: u8,
80    pub name: Option<String>,
81    pub line: Option<LineNumber>,
82    pub column: Option<ColumnNumber>,
83    pub picture: Option<String>,
84    pub content: Option<Content>,
85    pub rounded: bool,
86    pub group_indicate: bool,
87    pub blank_when_zero: bool,
88    pub justified: bool,
89    pub sign: Option<SignClause>,
90    pub pos: Pos,
91}
92
93#[derive(Clone, Debug, PartialEq, Eq)]
94pub enum ReportStmt {
95    Initiate { reports: Vec<String>, pos: Pos },
96    /// GENERATE a DETAIL group, or a report for summary reporting; `qualifier` is IN report-name.
97    Generate { name: String, qualifier: Option<String>, pos: Pos },
98    Terminate { reports: Vec<String>, pos: Pos },
99    Suppress { pos: Pos },
100}
101
102/// A DECLARATIVES section that runs just before a report group is produced.
103#[derive(Clone, Debug, PartialEq, Eq)]
104pub struct UseBeforeReporting {
105    /// The section's header among the program's paragraphs.
106    pub section: usize,
107    pub group: String,
108    pub qualifier: Option<String>,
109    /// USE GLOBAL: it serves the same group name in contained programs too.
110    pub global: bool,
111    pub pos: Pos,
112}