use crate::Pos;
mod oo;
pub use oo::*;
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct Program {
pub id: String,
pub options: Vec<String>,
pub initial: bool,
pub recursive: bool,
pub working_storage: Vec<DataEntry>,
pub local_storage: Vec<DataEntry>,
pub linkage: Vec<DataEntry>,
pub using: Vec<Param>,
pub returning: Option<String>,
pub paragraphs: Vec<Paragraph>,
pub files: Vec<FileDecl>,
pub sources: Vec<String>,
pub exec_declarations: Vec<ExecBlock>,
pub report_writer: crate::report::ReportWriter,
pub declaratives: Declaratives,
pub oo: Option<Box<Oo>>,
pub environment: Environment,
pub nested: Vec<String>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Param {
pub by_value: bool,
pub name: String,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Organization {
Sequential,
LineSequential,
Indexed,
Relative,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum Access {
#[default]
Sequential,
Random,
Dynamic,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct FileDecl {
pub name: String,
pub assign: String,
pub organization: Organization,
pub access: Access,
pub record_key: Option<Ref>,
pub alternate_keys: Vec<(Ref, bool)>,
pub relative_key: Option<Ref>,
pub optional: bool,
pub status: Option<Ref>,
pub recording: Option<char>,
pub record_min: Option<u32>,
pub record_max: Option<u32>,
pub records: Vec<DataEntry>,
pub reports: Vec<String>,
pub linage: Option<Linage>,
pub sort: bool,
pub pos: Pos,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Linage {
pub lines: LinageValue,
pub footing: Option<LinageValue>,
pub top: Option<LinageValue>,
pub bottom: Option<LinageValue>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum LinageValue {
Integer(String),
Data(Ref),
}
pub use rt::vocab::OpenMode;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Advancing {
Lines { before: bool, count: Expr },
Page { before: bool },
Mnemonic { before: bool, name: String, environment: String },
}
impl Advancing {
pub fn before(&self) -> bool {
match self {
Self::Lines { before, .. } | Self::Page { before } | Self::Mnemonic { before, .. } => *before,
}
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum Usage {
#[default]
Display,
Binary,
NativeBinary,
Packed,
Float1,
Float2,
National,
Pointer,
Index,
ObjectReference,
ProgramPointer,
}
pub use rt::vocab::{SignClause, SignPosition};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct DataEntry {
pub level: u8,
pub name: Option<String>,
pub picture: Option<String>,
pub usage: Option<Usage>,
pub value: Option<Literal>,
pub redefines: Option<String>,
pub occurs: Option<u32>,
pub depending_on: Option<Ref>,
pub sign: Option<SignClause>,
pub justified: bool,
pub sync: bool,
pub blank_when_zero: bool,
pub indexed_by: Vec<String>,
pub keys: Vec<(bool, Ref)>,
pub condition_values: Vec<(Literal, Option<Literal>)>,
pub false_value: Option<Literal>,
pub renames: Option<(Ref, Option<Ref>)>,
pub object_class: Option<String>,
pub pos: Pos,
}
pub use rt::vocab::Figurative;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Literal {
Alnum(String),
Hex(Vec<u8>),
National(String),
Number(String),
Figurative(Figurative),
All(Box<Literal>),
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Paragraph {
pub name: String,
pub statements: Vec<Stmt>,
pub section: Option<String>,
pub is_section: bool,
pub priority: u8,
pub pos: Pos,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ProcName {
pub name: String,
pub section: Option<String>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct Declaratives {
pub errors: Vec<UseAfterError>,
pub debugging: Vec<UseForDebugging>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct UseAfterError {
pub section: usize,
pub global: bool,
pub on: ErrorUse,
pub pos: Pos,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ErrorUse {
Files(Vec<String>),
Mode(OpenMode),
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct UseForDebugging {
pub section: usize,
pub procedures: Vec<ProcName>,
pub pos: Pos,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ExitKind {
Plain,
Paragraph,
Section,
Perform,
PerformCycle,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Subject {
Bool(bool),
Expr(Expr),
Cond(Cond),
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Object {
Any,
Bool(bool),
Cond(Cond),
Value { not: bool, from: Expr, thru: Option<Expr> },
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct When {
pub alternatives: Vec<Vec<Object>>,
pub body: Vec<Stmt>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Ref {
pub name: String,
pub qualifiers: Vec<String>,
pub subscripts: Vec<Expr>,
pub refmod: Option<RefMod>,
pub pos: Pos,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RefMod {
pub start: Box<Expr>,
pub length: Option<Box<Expr>>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct FunctionCall {
pub name: String,
pub args: Vec<Expr>,
pub modifier: Option<String>,
pub refmod: Option<RefMod>,
pub pos: Pos,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Operand {
Ref(Ref),
Literal(Literal),
Function(FunctionCall),
LengthOf(Ref),
AddressOf(Ref),
}
pub use rt::vocab::{AcceptFrom, BinOp, RelOp};
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Expr {
Operand(Operand),
Neg(Box<Expr>),
Bin(Box<Expr>, BinOp, Box<Expr>),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Class {
Numeric,
Alphabetic,
Positive,
Negative,
Zero,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Cond {
Rel(Expr, RelOp, Expr),
Class(Expr, Class),
Name(Ref),
NameOrRel { subject: Expr, op: RelOp, name: Ref },
Not(Box<Cond>),
And(Box<Cond>, Box<Cond>),
Or(Box<Cond>, Box<Cond>),
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Target {
pub r: Ref,
pub rounded: bool,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Varying {
pub var: Ref,
pub from: Expr,
pub by: Expr,
pub until: Cond,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Loop {
Once,
Times(Expr),
Until { cond: Cond, test_after: bool },
Varying { varying: Box<Varying>, after: Vec<Varying>, test_after: bool },
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Stmt {
Move { from: Operand, to: Vec<Ref>, pos: Pos },
Compute { targets: Vec<Target>, expr: Expr, size_error: Option<SizeError>, pos: Pos },
Arith(Box<Arith>),
If { cond: Cond, then: Vec<Stmt>, otherwise: Vec<Stmt>, pos: Pos },
PerformInline { body: Vec<Stmt>, repeat: Loop, pos: Pos },
PerformProc { from: ProcName, thru: Option<ProcName>, repeat: Loop, pos: Pos },
Evaluate { subjects: Vec<Subject>, whens: Vec<When>, other: Vec<Stmt>, pos: Pos },
Display { items: Vec<Operand>, no_advancing: bool, pos: Pos },
Open { files: Vec<(OpenMode, String)>, pos: Pos },
Close { files: Vec<String>, pos: Pos },
Read(Box<ReadStmt>),
Write { record: Ref, from: Option<Operand>, advancing: Option<Advancing>, invalid: Handlers, end_of_page: Handlers, pos: Pos },
Rewrite { record: Ref, from: Option<Operand>, invalid: Handlers, pos: Pos },
Delete { file: String, invalid: Handlers, pos: Pos },
Start { file: String, key: Option<(RelOp, Ref)>, invalid: Handlers, pos: Pos },
Initialize { targets: Vec<Ref>, pos: Pos },
GoTo { target: Option<ProcName>, pos: Pos },
GoToDepending { targets: Vec<ProcName>, on: Ref, pos: Pos },
Alter { pairs: Vec<(ProcName, ProcName)>, pos: Pos },
Entry { name: String, using: Vec<Param>, pos: Pos },
Goback { pos: Pos },
ExitProgram { pos: Pos },
Call(Box<Call>),
Cancel { targets: Vec<Operand>, pos: Pos },
Set { set: SetStmt, pos: Pos },
Accept { target: Ref, from: AcceptFrom, pos: Pos },
String(Box<StringStmt>),
Unstring(Box<Unstring>),
Inspect(Box<Inspect>),
Search(Box<Search>),
NextSentence,
SentenceEnd,
Exec(Box<ExecBlock>),
Report(Box<crate::report::ReportStmt>),
Invoke(Box<Invoke>),
ExitMethod { pos: Pos },
Sorting(Box<Sorting>),
StopRun { pos: Pos },
Continue,
Exit { kind: ExitKind, pos: Pos },
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SizeError {
pub on: Vec<Stmt>,
pub not_on: Vec<Stmt>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ArithVerb {
Add,
Subtract,
Multiply,
Divide,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Arith {
pub verb: ArithVerb,
pub computations: Vec<(Target, Expr)>,
pub remainder: Option<(Target, Expr, Expr)>,
pub size_error: Option<SizeError>,
pub pos: Pos,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ArgMode {
Reference,
Content,
Value,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Arg {
pub mode: ArgMode,
pub value: Option<Operand>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Call {
pub target: Operand,
pub using: Vec<Arg>,
pub returning: Option<Ref>,
pub on_exception: Option<Vec<Stmt>>,
pub not_on_exception: Option<Vec<Stmt>>,
pub pos: Pos,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum SetStmt {
ConditionTrue(Vec<Ref>),
ConditionFalse(Vec<Ref>),
To { targets: Vec<Ref>, value: Operand },
AddressOf { targets: Vec<Ref>, value: Operand },
UpDown { targets: Vec<Ref>, down: bool, by: Expr },
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Delimiter {
Size,
By(Operand),
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct StringStmt {
pub sources: Vec<(Operand, Delimiter)>,
pub into: Ref,
pub pointer: Option<Ref>,
pub on_overflow: Option<Vec<Stmt>>,
pub not_on_overflow: Option<Vec<Stmt>>,
pub pos: Pos,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct UnstringInto {
pub target: Ref,
pub delimiter_in: Option<Ref>,
pub count_in: Option<Ref>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Unstring {
pub source: Ref,
pub delimiters: Vec<(bool, Operand)>,
pub into: Vec<UnstringInto>,
pub pointer: Option<Ref>,
pub tallying: Option<Ref>,
pub on_overflow: Option<Vec<Stmt>>,
pub not_on_overflow: Option<Vec<Stmt>>,
pub pos: Pos,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Bound {
pub after: bool,
pub value: Operand,
}
pub use rt::vocab::InspectMode;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct InspectPhrase {
pub mode: InspectMode,
pub pattern: Option<Operand>,
pub by: Option<Operand>,
pub counter: Option<Ref>,
pub bounds: Vec<Bound>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Inspect {
pub target: Ref,
pub tallying: Vec<InspectPhrase>,
pub replacing: Vec<InspectPhrase>,
pub converting: Option<(Operand, Operand, Vec<Bound>)>,
pub pos: Pos,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Search {
pub table: Ref,
pub all: bool,
pub varying: Option<Ref>,
pub at_end: Option<Vec<Stmt>>,
pub whens: Vec<(Cond, Vec<Stmt>)>,
pub pos: Pos,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ExecKind {
Sql,
Cics,
Dli,
Other,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ExecArg {
Operand(Operand),
Text(String),
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ExecBlock {
pub kind: ExecKind,
pub command: String,
pub options: Vec<(String, Option<ExecArg>)>,
pub host_variables: Vec<Ref>,
pub sql: Option<crate::sql::Sql>,
pub text: String,
pub pos: Pos,
}
impl ExecBlock {
pub fn declarative(&self) -> bool {
self.kind == ExecKind::Sql
&& matches!(self.command.as_str(), "INCLUDE" | "BEGIN DECLARE SECTION" | "END DECLARE SECTION" | "WHENEVER" | "DECLARE CURSOR" | "DECLARE TABLE" | "DECLARE STATEMENT")
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct Handlers {
pub on: Option<Vec<Stmt>>,
pub not_on: Option<Vec<Stmt>>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ReadStmt {
pub file: String,
pub next: bool,
pub previous: bool,
pub into: Option<Ref>,
pub key: Option<Ref>,
pub at_end: Handlers,
pub invalid: Handlers,
pub pos: Pos,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Alphabet {
Ebcdic,
Native,
Standard1,
Standard2,
Literal(Vec<AlphabetEntry>),
}
impl Alphabet {
pub fn name(&self) -> &'static str {
match self {
Self::Ebcdic => "EBCDIC",
Self::Native => "NATIVE",
Self::Standard1 => "STANDARD-1",
Self::Standard2 => "STANDARD-2",
Self::Literal(_) => "literal",
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum AlphabetEntry {
Literal(Literal),
Through(Literal, Literal),
Also(Vec<Literal>),
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct Environment {
pub alphabets: Vec<(String, Alphabet)>,
pub collating_sequence: Option<String>,
pub same_record_areas: Vec<Vec<String>>,
pub same_areas: Vec<Vec<String>>,
pub mnemonics: Vec<(String, String)>,
pub debugging_mode: bool,
pub decimal_point_comma: bool,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Sorting {
Sort(SortStmt),
Release { record: Ref, from: Option<Operand>, pos: Pos },
Return { file: String, into: Option<Ref>, at_end: Handlers, pos: Pos },
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SortStmt {
pub merge: bool,
pub subject: Ref,
pub keys: Vec<(bool, Ref)>,
pub duplicates: bool,
pub collating: Option<String>,
pub input: Option<SortIo>,
pub output: Option<SortIo>,
pub pos: Pos,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum SortIo {
Files(Vec<String>),
Procedure { from: ProcName, thru: Option<ProcName> },
}