1use super::{
5 AbendId, ArithId, BlockId, CallId, CicsId, CondId, DisplayId, ExprId, FileOpId, InitId, InspectId, IntExpr,
6 InvokeId, MarkupId, MovePlan, Operand, ParaId, PlaceId, RangeId, ReleaseId, ReportOp, ReturnId, SearchAllId, SortId, SqlId,
7 StepPlan, StringId, SymId, TempId, UnstringId, UpDown,
8};
9use crate::abend::Ending;
10use crate::vocab::AcceptFrom;
11use crate::{codec_enum, codec_struct};
12use std::collections::BTreeMap;
13
14#[derive(Clone, Debug, PartialEq, Eq)]
15pub enum Op {
16 Move { from: Operand, to: PlaceId, plan: MovePlan },
17 Initialize { target: PlaceId, plan: InitId },
18 Arith(ArithId),
19 SetAddress { records: Vec<u16>, address: Operand },
22 SetUpDown { by: IntExpr, down: bool, targets: Vec<(PlaceId, UpDown)> },
24 Step { var: PlaceId, by: ExprId, plan: StepPlan, prepass: Vec<PlaceId> },
27 SetInt { target: PlaceId, value: IntExpr },
29 Inspect(InspectId),
30 String(StringId),
31 Unstring(UnstringId),
32 SearchAll(SearchAllId),
33 Nest,
35 Unnest(u8),
36 SetTemp(TempId, IntExpr),
37 DecTemp(TempId),
38 Display(DisplayId),
39 Accept { target: PlaceId, from: AcceptFrom, plan: MovePlan },
40 File(FileOpId),
41 Call(CallId),
42 Cancel(Operand),
43 Sort(SortId),
44 Release(ReleaseId),
45 Return(ReturnId),
46 Report(ReportOp),
47 Invoke(InvokeId),
48 Cics(CicsId),
49 Sql(SqlId),
50 Alter { para: ParaId, to: ParaId },
53 EnterSegment(u8),
57 DebugLine(u32),
59 DebugAlter { range: RangeId, name: SymId, contents: SymId },
62 Markup(MarkupId),
64}
65
66#[derive(Clone, Copy, Debug, PartialEq, Eq)]
68pub enum Step {
69 Next,
70 Arm(u8),
72 GoTo(ParaId),
75 End(Ending),
76 Return(u64),
78 Resume(Resume),
80}
81
82#[derive(Clone, Debug, PartialEq, Eq)]
83pub enum Terminator {
84 Jump(BlockId),
85 Branch { cond: CondId, then: BlockId, otherwise: BlockId },
86 Select(Vec<BlockId>),
88 ParagraphEnd { next: ParaId },
91 GoTo(ParaId),
92 Switch { value: IntExpr, targets: Vec<ParaId>, otherwise: BlockId },
94 PerformEnter { range: RangeId, ret: BlockId, resume: Option<Resume> },
97 ExitProgram { next: BlockId },
99 End(Ending),
100 Abend(AbendId),
101 AlteredGoTo { para: ParaId, otherwise: BlockId },
104 Debug { range: RangeId, name: SymId, next: BlockId },
107}
108
109#[derive(Clone, Copy, Debug, PartialEq, Eq)]
113pub struct Resume {
114 pub para: ParaId,
115 pub block: BlockId,
116}
117
118#[derive(Clone, Copy, Debug, PartialEq, Eq)]
119pub struct Range {
120 pub first: ParaId,
121 pub last: ParaId,
122 pub kind: RangeKind,
123}
124
125impl Range {
126 pub fn region(&self, paragraphs: u32) -> (ParaId, ParaId) {
130 let end = paragraphs.saturating_sub(1);
131 match self.kind {
132 RangeKind::SortProcedure => (0, end),
133 _ if self.last < self.first => (self.first, end),
134 _ => (self.first, self.last),
135 }
136 }
137}
138
139#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
140pub enum RangeKind {
141 Perform,
142 SortProcedure,
143 UseBeforeReporting,
144 UseProcedure,
146 Debugging,
148 Processing,
150}
151
152#[derive(Clone, Debug, Default, PartialEq, Eq)]
154pub struct Declaratives {
155 pub modes: [Option<RangeId>; 4],
158 pub debug_item: Option<(u32, u32)>,
160}
161
162#[derive(Clone, Copy, Debug, PartialEq, Eq)]
165pub struct ReturnPoint {
166 pub frame: u64,
167 pub resume: Option<Resume>,
168}
169
170#[derive(Clone, Debug, PartialEq, Eq)]
175pub struct Frame {
176 pub id: u64,
177 pub kind: FrameKind,
178 pub displaced: Option<ReturnPoint>,
179 pub segment: u8,
180 pub depth: u32,
181 pub temps: Vec<i64>,
182}
183
184#[derive(Clone, Copy, Debug, PartialEq, Eq)]
185pub enum FrameKind {
186 Main,
188 Perform { range: RangeId, ret: BlockId, resume: Option<Resume> },
189 Procedure { range: RangeId },
192}
193
194#[derive(Clone, Debug, Default, PartialEq, Eq)]
197pub struct Returns {
198 pub armed: Vec<Option<ReturnPoint>>,
199 pub saved: BTreeMap<BlockId, Option<ReturnPoint>>,
200 pub frames: Vec<Frame>,
201 pub next_frame: u64,
202}
203
204codec_enum!(Op {
205 Move { from, to, plan } = 0,
206 Initialize { target, plan } = 1,
207 Arith(id) = 2,
208 SetAddress { records, address } = 3,
209 SetUpDown { by, down, targets } = 4,
210 Step { var, by, plan, prepass } = 5,
211 SetInt { target, value } = 6,
212 Inspect(id) = 7,
213 String(id) = 8,
214 Unstring(id) = 9,
215 SearchAll(id) = 10,
216 Nest = 11,
217 Unnest(n) = 12,
218 SetTemp(temp, value) = 13,
219 DecTemp(temp) = 14,
220 Display(id) = 15,
221 Accept { target, from, plan } = 16,
222 File(id) = 17,
223 Call(id) = 18,
224 Cancel(name) = 19,
225 Sort(id) = 20,
226 Release(id) = 21,
227 Return(id) = 22,
228 Report(op) = 23,
229 Invoke(id) = 24,
230 Cics(id) = 25,
231 Sql(id) = 26,
232 Alter { para, to } = 27,
233 EnterSegment(priority) = 28,
234 DebugLine(line) = 30,
235 DebugAlter { range, name, contents } = 31,
236 Markup(id) = 32,
237});
238codec_enum!(Step { Next = 0, Arm(arm) = 1, GoTo(para) = 2, End(ending) = 3, Return(frame) = 4, Resume(resume) = 5 });
239codec_enum!(Terminator {
240 Jump(block) = 0,
241 Branch { cond, then, otherwise } = 1,
242 Select(arms) = 2,
243 ParagraphEnd { next } = 3,
244 GoTo(para) = 4,
245 Switch { value, targets, otherwise } = 5,
246 ExitProgram { next } = 7,
247 End(ending) = 8,
248 Abend(abend) = 9,
249 AlteredGoTo { para, otherwise } = 10,
250 Debug { range, name, next } = 11,
251 PerformEnter { range, ret, resume } = 12,
252});
253codec_struct!(Resume { para, block });
254codec_struct!(Range { first, last, kind });
255codec_enum!(RangeKind { Perform = 0, SortProcedure = 1, UseBeforeReporting = 2, UseProcedure = 3, Debugging = 4, Processing = 5 });
256codec_struct!(Declaratives { modes, debug_item });
257codec_struct!(ReturnPoint { frame, resume });
258codec_struct!(Frame { id, kind, displaced, segment, depth, temps });
259codec_enum!(FrameKind { Main = 0, Perform { range, ret, resume } = 1, Procedure { range } = 2 });
260codec_struct!(Returns { armed, saved, frames, next_frame });