assembler/
directive.rs

1//! Intermetiate representation of the assembly language input.
2//!
3//! This is arranged as a sequence of instruction (not scope) blocks,
4//! each with an optional origin.
5use std::collections::BTreeMap;
6
7use base::prelude::Address;
8
9use super::ast::Equality;
10use super::ast::Origin;
11use super::memorymap::LocatedBlock;
12use super::types::BlockIdentifier;
13
14/// The `Directive` is the abstract syntax representation of the
15/// user's program (i.e. the assembler's input).  A `Directive` is
16/// generated (from a [`super::manuscript::SourceFile`] instance) by
17/// the assembler once it has deduced the absolute address at which
18/// each block will be located.
19///
20/// Symbolic information is included in the equalities table, but also
21/// within the blocks of the program itself.
22#[derive(Debug, Clone, PartialEq, Eq)]
23pub(crate) struct Directive {
24    // items must be in manuscript order, because RC block addresses
25    // are assigned in the order they appear in the code, and
26    // similarly for undefined origins (e.g. "FOO| JMP ..." where FOO
27    // has no definition).
28    pub(crate) blocks: BTreeMap<BlockIdentifier, LocatedBlock>,
29
30    /// Equalities (we use the term from the [TX-2 Users
31    /// Handbook](https://archive.org/details/tx-2-users-handbook-nov-63/page/n157/mode/1up)).
32    /// In more modern terminology, these would be assignments.  An
33    /// equality can be re-assigned, and the last value assigned takes
34    /// effect everywhere in the program.
35    ///
36    ///
37    /// When evaluated, however, the value of an equality can vary in
38    /// different places, because it can refer to local tags (which
39    /// may be dfefined differently inside macro bodies) or (directly
40    /// or indirectly) to `#` which is the address of the word
41    /// currently being assembled.
42    pub(crate) equalities: Vec<Equality>,
43
44    /// The address at which execution should begin, as specified by
45    /// the `☛☛PUNCH` meta-command, if one was given.  See [Users
46    /// Handbook, section
47    /// 6-3.4](https://archive.org/details/tx-2-users-handbook-nov-63/page/n175/mode/1up)
48    /// and [`super::manuscript::ManuscriptMetaCommand::Punch`].
49    pub(crate) entry_point: Option<Address>,
50}
51
52impl Directive {
53    pub(crate) fn new(
54        blocks: BTreeMap<BlockIdentifier, LocatedBlock>,
55        equalities: Vec<Equality>,
56        entry_point: Option<Address>,
57    ) -> Self {
58        Self {
59            blocks,
60            equalities,
61            entry_point,
62        }
63    }
64
65    /// Determine the address of the RC-block.
66    ///
67    /// The real TX-2 assembler ("M4") allowed the program optionally
68    /// to select a location using the[`☛☛RC` meta
69    /// command](https://archive.org/details/tx-2-users-handbook-nov-63/page/n176/mode/1up),
70    /// but this is not yet supported.
71    pub(super) fn position_rc_block(&mut self) -> Address {
72        self.blocks
73            .values()
74            .map(LocatedBlock::following_addr)
75            .max()
76            .unwrap_or_else(Origin::default_address)
77    }
78
79    pub(crate) fn entry_point(&self) -> Option<Address> {
80        self.entry_point
81    }
82}