ironwork_rt/lir/scope.rs
1//! EXTERNAL and GLOBAL (lir.md ยง9.16): the records and file connectors a program shares with the
2//! run unit and with the programs containing it, bound each time it is activated, and what a
3//! program that contains others gives them (assumptions C69, C180 and C181).
4
5use super::{RangeId, SymId};
6use crate::{codec_enum, codec_struct};
7
8/// A program's EXTERNAL and GLOBAL storage, files and procedures; empty for a program with none.
9#[derive(Clone, Debug, Default, PartialEq, Eq)]
10pub struct Scope {
11 /// The PROGRAM-IDs of the programs containing this one, innermost first.
12 pub containers: Vec<SymId>,
13 /// Each LINKAGE record whose storage the run unit or a containing program holds, by ordinal,
14 /// in ordinal order.
15 pub records: Vec<(u16, Binding)>,
16 /// Each file whose connector is not its own, in file order.
17 pub files: Vec<SharedFile>,
18 /// Each file whose record area is not in the slab, and the LINKAGE record bound to it.
19 pub areas: Vec<(u16, u16)>,
20 /// A program that contains others: its GLOBAL records and files as they find them.
21 pub globals: Vec<Global>,
22 /// A program that contains others: its GLOBAL EXCEPTION/ERROR procedures for files, by file,
23 /// and for the open modes, in `Declaratives.modes`' order.
24 pub global_files: Vec<(u16, RangeId)>,
25 pub global_modes: [Option<RangeId>; 4],
26}
27
28/// Where a record addressed as a LINKAGE record gets its address when the program is activated.
29#[derive(Clone, Debug, PartialEq, Eq)]
30pub enum Binding {
31 /// The run unit's EXTERNAL record of this name and size, allocated by the first program that
32 /// describes it.
33 External { name: SymId, size: u32 },
34 /// The run unit's record area of EXTERNAL file k, by the file's name and its area's size.
35 ExternalFile(u16),
36 /// What containing program `program` gives as its GLOBAL `name` of `section`: a record, or for
37 /// `Section::File` the record area of the file of that name.
38 Global { program: SymId, section: Section, name: SymId },
39}
40
41#[derive(Clone, Copy, Debug, PartialEq, Eq)]
42pub enum Section {
43 WorkingStorage,
44 LocalStorage,
45 Linkage,
46 File,
47}
48
49/// File `file`, whose connector is the run unit's EXTERNAL file of its name when `external`, and
50/// otherwise file `declared_in` declares GLOBAL, that program's own file of its name.
51#[derive(Clone, Copy, Debug, PartialEq, Eq)]
52pub struct SharedFile {
53 pub file: u16,
54 pub external: bool,
55 pub declared_in: Option<SymId>,
56}
57
58/// A GLOBAL record or file of a program that contains others: where the record, or the file's
59/// record area, is in an activation of it.
60#[derive(Clone, Copy, Debug, PartialEq, Eq)]
61pub struct Global {
62 pub section: Section,
63 pub name: SymId,
64 pub at: GlobalAt,
65}
66
67/// An offset in the slab or in LOCAL-STORAGE, or the address LINKAGE record n holds.
68#[derive(Clone, Copy, Debug, PartialEq, Eq)]
69pub enum GlobalAt {
70 Program(u32),
71 Local(u32),
72 Linkage(u16),
73}
74
75codec_struct!(Scope { containers, records, files, areas, globals, global_files, global_modes });
76codec_enum!(Binding { External { name, size } = 0, ExternalFile(file) = 1, Global { program, section, name } = 2 });
77codec_enum!(Section { WorkingStorage = 0, LocalStorage = 1, Linkage = 2, File = 3 });
78codec_struct!(SharedFile { file, external, declared_in });
79codec_struct!(Global { section, name, at });
80codec_enum!(GlobalAt { Program(offset) = 0, Local(offset) = 1, Linkage(record) = 2 });