use super::{
AbendId, ArithId, BlockId, CallId, CicsId, CondId, DisplayId, ExprId, FileOpId, InitId, InspectId, IntExpr,
InvokeId, MarkupId, MovePlan, Odo, Operand, ParaId, PlaceId, RangeId, ReleaseId, ReportOp, ReturnId, SearchAllId, SenderCheck, SortId, SqlId,
StepPlan, StringId, SymId, TempId, UnstringId, UpDown,
};
use crate::abend::Ending;
use crate::vocab::AcceptFrom;
use crate::{codec_enum, codec_struct};
use std::collections::BTreeMap;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Op {
Move { from: Operand, to: PlaceId, plan: MovePlan, check: SenderCheck },
Set { from: Operand, to: PlaceId, plan: MovePlan },
Initialize { target: PlaceId, plan: InitId },
Arith(ArithId),
SetAddress { records: Vec<u16>, address: Operand },
SetUpDown { by: IntExpr, down: bool, targets: Vec<(PlaceId, UpDown)> },
SetEntry { entry: Operand, targets: Vec<PlaceId> },
Step { var: PlaceId, by: ExprId, plan: StepPlan, prepass: Vec<PlaceId> },
SetInt { target: PlaceId, value: IntExpr },
Inspect(InspectId),
String(StringId),
Unstring(UnstringId),
SearchAll(SearchAllId),
Nest,
Unnest(u8),
SetTemp(TempId, IntExpr),
DecTemp(TempId),
SetCount(TempId, Odo),
Display(DisplayId),
Accept { target: PlaceId, from: AcceptFrom, plan: MovePlan },
File(FileOpId),
Call(CallId),
Cancel(Operand),
Sort(SortId),
Release(ReleaseId),
Return(ReturnId),
Report(ReportOp),
Invoke(InvokeId),
Cics(CicsId),
Sql(SqlId),
Alter { para: ParaId, to: ParaId },
EnterSegment(u8),
DebugLine(u32),
DebugAlter { range: RangeId, name: SymId, contents: SymId },
Markup(MarkupId),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Step {
Next,
Arm(u8),
GoTo(ParaId),
End(Ending),
Return(u64),
Resume(Resume),
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Terminator {
Jump(BlockId),
Branch { cond: CondId, then: BlockId, otherwise: BlockId },
Select(Vec<BlockId>),
ParagraphEnd { next: ParaId },
GoTo(ParaId),
Switch { value: IntExpr, targets: Vec<ParaId>, otherwise: BlockId },
PerformEnter { range: RangeId, ret: BlockId, resume: Option<Resume> },
ExitProgram { next: BlockId },
End(Ending),
Abend(AbendId),
AlteredGoTo { para: ParaId, otherwise: BlockId },
Debug { range: RangeId, name: SymId, next: BlockId },
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Resume {
pub para: ParaId,
pub block: BlockId,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Range {
pub first: ParaId,
pub last: ParaId,
pub kind: RangeKind,
}
impl Range {
pub fn region(&self, paragraphs: u32) -> (ParaId, ParaId) {
let end = paragraphs.saturating_sub(1);
match self.kind {
RangeKind::SortProcedure => (0, end),
_ if self.last < self.first => (self.first, end),
_ => (self.first, self.last),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum RangeKind {
Perform,
SortProcedure,
UseBeforeReporting,
UseProcedure,
Debugging,
Processing,
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct Declaratives {
pub modes: [Option<RangeId>; 4],
pub debug_item: Option<(u32, u32)>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ReturnPoint {
pub frame: u64,
pub resume: Option<Resume>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Frame {
pub id: u64,
pub kind: FrameKind,
pub displaced: Option<ReturnPoint>,
pub segment: u8,
pub depth: u32,
pub temps: Vec<i64>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum FrameKind {
Main,
Perform { range: RangeId, ret: BlockId, resume: Option<Resume> },
Procedure { range: RangeId },
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct Returns {
pub armed: Vec<Option<ReturnPoint>>,
pub saved: BTreeMap<BlockId, Option<ReturnPoint>>,
pub frames: Vec<Frame>,
pub next_frame: u64,
}
codec_enum!(Op {
Move { from, to, plan, check } = 0,
Initialize { target, plan } = 1,
Arith(id) = 2,
SetAddress { records, address } = 3,
SetUpDown { by, down, targets } = 4,
Step { var, by, plan, prepass } = 5,
SetInt { target, value } = 6,
Inspect(id) = 7,
String(id) = 8,
Unstring(id) = 9,
SearchAll(id) = 10,
Nest = 11,
Unnest(n) = 12,
SetTemp(temp, value) = 13,
DecTemp(temp) = 14,
Display(id) = 15,
Accept { target, from, plan } = 16,
File(id) = 17,
Call(id) = 18,
Cancel(name) = 19,
Sort(id) = 20,
Release(id) = 21,
Return(id) = 22,
Report(op) = 23,
Invoke(id) = 24,
Cics(id) = 25,
Sql(id) = 26,
Alter { para, to } = 27,
EnterSegment(priority) = 28,
DebugLine(line) = 30,
DebugAlter { range, name, contents } = 31,
Markup(id) = 32,
Set { from, to, plan } = 33,
SetCount(temp, odo) = 34,
SetEntry { entry, targets } = 35,
});
codec_enum!(Step { Next = 0, Arm(arm) = 1, GoTo(para) = 2, End(ending) = 3, Return(frame) = 4, Resume(resume) = 5 });
codec_enum!(Terminator {
Jump(block) = 0,
Branch { cond, then, otherwise } = 1,
Select(arms) = 2,
ParagraphEnd { next } = 3,
GoTo(para) = 4,
Switch { value, targets, otherwise } = 5,
ExitProgram { next } = 7,
End(ending) = 8,
Abend(abend) = 9,
AlteredGoTo { para, otherwise } = 10,
Debug { range, name, next } = 11,
PerformEnter { range, ret, resume } = 12,
});
codec_struct!(Resume { para, block });
codec_struct!(Range { first, last, kind });
codec_enum!(RangeKind { Perform = 0, SortProcedure = 1, UseBeforeReporting = 2, UseProcedure = 3, Debugging = 4, Processing = 5 });
codec_struct!(Declaratives { modes, debug_item });
codec_struct!(ReturnPoint { frame, resume });
codec_struct!(Frame { id, kind, displaced, segment, depth, temps });
codec_enum!(FrameKind { Main = 0, Perform { range, ret, resume } = 1, Procedure { range } = 2 });
codec_struct!(Returns { armed, saved, frames, next_frame });