1use super::{IntExpr, MovePlan, Operand, PlaceId, RangeId, StorePlan, SymId};
6use crate::files::Format;
7use crate::vocab::{Closing, OpenMode};
8use crate::{codec_enum, codec_struct};
9
10#[derive(Clone, Debug, PartialEq, Eq)]
13pub struct FileDesc {
14 pub name: SymId,
15 pub assign: SymId,
17 pub organization: Organization,
18 pub access: Access,
19 pub optional: bool,
20 pub format: Format,
21 pub read_lengths: (u32, u32),
25 pub fixed: bool,
27 pub record_min: Option<u32>,
29 pub status: Option<(PlaceId, MovePlan)>,
30 pub keys: Option<IndexKeys>,
32 pub relative: Option<RelativeKey>,
33 pub linage: Option<Linage>,
34 pub carriage: Option<Carriage>,
36 pub sort: bool,
38 pub error: Option<RangeId>,
40}
41
42#[derive(Clone, Copy, Debug, PartialEq, Eq)]
43pub enum Organization {
44 Sequential,
45 LineSequential,
46 Indexed,
47 Relative,
48}
49
50#[derive(Clone, Copy, Debug, PartialEq, Eq)]
51pub enum Access {
52 Sequential,
53 Random,
54 Dynamic,
55}
56
57#[derive(Clone, Copy, Debug, PartialEq, Eq)]
59pub struct RecordSpan {
60 pub offset: u32,
61 pub len: u32,
62}
63
64#[derive(Clone, Debug, PartialEq, Eq)]
67pub struct IndexKeys {
68 pub prime: RecordSpan,
69 pub alternates: Vec<(RecordSpan, bool)>,
70}
71
72#[derive(Clone, Debug, PartialEq, Eq)]
75pub struct RelativeKey {
76 pub place: PlaceId,
77 pub value: IntExpr,
78 pub store: StorePlan,
79 pub digits: Option<u32>,
80}
81
82#[derive(Clone, Debug, PartialEq, Eq)]
85pub struct Linage {
86 pub lines: IntExpr,
87 pub footing: Option<IntExpr>,
88 pub top: Option<IntExpr>,
89 pub bottom: Option<IntExpr>,
90 pub counter: Option<(PlaceId, StorePlan)>,
91}
92
93#[derive(Clone, Copy, Debug, PartialEq, Eq)]
96pub struct Carriage {
97 pub machine: bool,
98 pub reserved: bool,
99}
100
101#[derive(Clone, Debug, PartialEq, Eq)]
107pub struct FileOp {
108 pub file: u16,
109 pub verb: FileVerb,
110 pub phrase: Option<Phrase>,
111 pub end_of_page: Option<Phrase>,
112}
113
114impl FileOp {
115 pub fn arms(&self) -> usize {
117 match (self.phrase, self.end_of_page) {
118 (None, None) => 0,
119 (_, None) => 3,
120 (_, Some(_)) => 5,
121 }
122 }
123}
124
125#[derive(Clone, Copy, Debug, PartialEq, Eq)]
126pub struct Phrase {
127 pub on: bool,
128 pub not_on: bool,
129}
130
131#[derive(Clone, Debug, PartialEq, Eq)]
132pub enum FileVerb {
133 Open(OpenMode),
134 Close,
135 CloseWith(Closing),
136 Read { sequential: bool, previous: bool, into: Option<(PlaceId, MovePlan)>, key: u8 },
139 Write { record: PlaceId, from: Option<FromMove>, advancing: Option<Advance> },
141 Rewrite { record: PlaceId, from: Option<FromMove> },
142 Delete,
143 Start { rel: StartRel, key: StartKey },
144}
145
146#[derive(Clone, Copy, Debug, PartialEq, Eq)]
148pub struct FromMove {
149 pub from: Operand,
150 pub to: PlaceId,
151 pub plan: MovePlan,
152}
153
154#[derive(Clone, Debug, PartialEq, Eq)]
157pub enum Advance {
158 Lines { before: bool, count: IntExpr },
159 Page { before: bool },
160 Mnemonic { before: bool, space: Spacing },
162}
163
164#[derive(Clone, Copy, Debug, PartialEq, Eq)]
165pub enum Spacing {
166 Lines(u64),
168 Channel(u8),
169 PageMode,
171}
172
173#[derive(Clone, Copy, Debug, PartialEq, Eq)]
175pub enum StartRel {
176 Equal,
177 Greater,
178 NotLess,
179}
180
181#[derive(Clone, Debug, PartialEq, Eq)]
182pub enum StartKey {
183 Prime,
185 Named { key: u8, span: RecordSpan },
187 Relative(IntExpr),
189 RelativeKey,
191}
192
193codec_struct!(FileDesc {
194 name, assign, organization, access, optional, format, read_lengths, fixed, record_min, status, keys, relative, linage, carriage, sort, error,
195} check file_valid);
196codec_enum!(Organization { Sequential = 0, LineSequential = 1, Indexed = 2, Relative = 3 });
197codec_enum!(Access { Sequential = 0, Random = 1, Dynamic = 2 });
198codec_struct!(RecordSpan { offset, len });
199codec_struct!(IndexKeys { prime, alternates });
200codec_struct!(RelativeKey { place, value, store, digits });
201codec_struct!(Linage { lines, footing, top, bottom, counter });
202codec_struct!(Carriage { machine, reserved });
203codec_struct!(FileOp { file, verb, phrase, end_of_page });
204codec_struct!(Phrase { on, not_on });
205codec_enum!(FileVerb {
206 Open(mode) = 0,
207 Close = 1,
208 Read { sequential, previous, into, key } = 2,
209 Write { record, from, advancing } = 3,
210 Rewrite { record, from } = 4,
211 Delete = 5,
212 Start { rel, key } = 6,
213 CloseWith(closing) = 7,
214});
215codec_struct!(FromMove { from, to, plan });
216codec_enum!(Advance { Lines { before, count } = 0, Page { before } = 1, Mnemonic { before, space } = 2 });
217codec_enum!(Spacing { Lines(n) = 0, Channel(c) = 1, PageMode = 2 });
218codec_enum!(StartRel { Equal = 0, Greater = 1, NotLess = 2 });
219codec_enum!(StartKey { Prime = 0, Named { key, span } = 1, Relative(value) = 2, RelativeKey = 3 });
220
221fn file_valid(file: &FileDesc) -> Result<(), String> {
223 if file.keys.is_some() == (file.organization == Organization::Indexed) {
224 Ok(())
225 } else {
226 Err("keys on a file that is not indexed, or an indexed file without them".into())
227 }
228}