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