Skip to main content

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 });