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}