tiger_lib/parse/pdxfile/
memory.rs

1//! Maintain the parser state for `@values` and `@:` directives.
2
3use crate::block::Block;
4use crate::helpers::TigerHashMap;
5use crate::token::Token;
6
7/// Definitions retained by the parser, to handle @values and macros.
8#[derive(Clone, Default, Debug)]
9pub struct PdxfileMemory {
10    /// Pdx calls them variables even though they are constants.
11    variables: TigerHashMap<String, Token>,
12    /// Macros defined with `@:define`.
13    blocks: TigerHashMap<String, Block>,
14}
15
16impl PdxfileMemory {
17    pub fn merge(&mut self, other: PdxfileMemory) {
18        self.variables.extend(other.variables);
19        self.blocks.extend(other.blocks);
20    }
21}
22
23pub struct CombinedMemory<'global> {
24    global: &'global PdxfileMemory,
25    local: PdxfileMemory,
26}
27
28impl<'global> CombinedMemory<'global> {
29    pub fn new(global: &'global PdxfileMemory) -> Self {
30        Self { global, local: PdxfileMemory::default() }
31    }
32
33    pub fn from_local(global: &'global PdxfileMemory, local: PdxfileMemory) -> Self {
34        Self { global, local }
35    }
36
37    /// Get a previously set named value.
38    pub fn get_variable(&self, key: &str) -> Option<&Token> {
39        self.local.variables.get(key).or_else(|| self.global.variables.get(key))
40    }
41
42    /// Check if a variable has been defined previously.
43    pub fn has_variable(&self, key: &str) -> bool {
44        self.local.variables.contains_key(key) || self.global.variables.contains_key(key)
45    }
46
47    /// Insert a local value definition.
48    pub fn set_variable(&mut self, key: String, value: Token) {
49        self.local.variables.insert(key, value);
50    }
51
52    /// Retrieve a previously defined macro.
53    pub fn get_block(&self, key: &str) -> Option<&Block> {
54        self.local.blocks.get(key).or_else(|| self.global.blocks.get(key))
55    }
56
57    /// Check if a macro has been defined under this name.
58    pub fn has_block(&self, key: &str) -> bool {
59        self.local.blocks.contains_key(key) || self.global.blocks.contains_key(key)
60    }
61
62    /// Define a macro.
63    pub fn define_block(&mut self, key: String, block: Block) {
64        self.local.blocks.insert(key, block);
65    }
66
67    /// Return the global part of the memory.
68    pub fn as_global(&self) -> &PdxfileMemory {
69        self.global
70    }
71
72    /// Clone the local part of the memory.
73    pub fn get_local(&self) -> PdxfileMemory {
74        self.local.clone()
75    }
76
77    /// Ignore the global part of the memory.
78    #[cfg(feature = "ck3")]
79    pub fn into_local(self) -> PdxfileMemory {
80        self.local
81    }
82}