spade_hir_lowering/
statement_list.rs

1use itertools::Itertools;
2use spade_mir::Statement;
3use spade_mir::ValueName;
4
5use crate::name_map::NameSource;
6use crate::name_map::NameSourceMap;
7
8pub struct StatementList {
9    pub(crate) stmts: Vec<Statement>,
10    name_map: NameSourceMap,
11}
12
13impl Default for StatementList {
14    fn default() -> Self {
15        Self::new()
16    }
17}
18
19impl StatementList {
20    pub fn new() -> StatementList {
21        Self {
22            stmts: vec![],
23            name_map: NameSourceMap::new(),
24        }
25    }
26
27    /// Pushes a statement which has no associated name or id. Currently used for asserts,
28    /// wal_tracing, and pipeline enable signals
29    pub fn push_anonymous(&mut self, stmt: Statement) {
30        self.stmts.push(stmt)
31    }
32
33    /// Pushes a statement which is the primary statement associated with the specified expression
34    pub fn push_primary(&mut self, stmt: Statement, source: impl Into<NameSource>) {
35        let name = match &stmt {
36            Statement::Binding(b) => Some(b.name.clone()),
37            Statement::Register(r) => Some(r.name.clone()),
38            Statement::Constant(id, _, _) => Some(ValueName::Expr(*id)),
39            Statement::Assert(_) => None,
40            Statement::Set { .. } => None,
41            Statement::WalTrace { .. } => None,
42        };
43        self.stmts.push(stmt);
44        if let Some(name) = name {
45            self.name_map.insert_primary(&name, source.into())
46        }
47    }
48
49    /// Pushes a statement which is used as a supporting statement for the generation
50    /// of the specified source. The description should give a short description of what
51    /// this value does. For example, being part of a condition, or being a pipeline register
52    pub fn push_secondary(
53        &mut self,
54        stmt: Statement,
55        source: impl Into<NameSource>,
56        description: &str,
57    ) {
58        let name = match &stmt {
59            Statement::Binding(b) => Some(b.name.clone()),
60            Statement::Register(r) => Some(r.name.clone()),
61            Statement::Constant(id, _, _) => Some(ValueName::Expr(*id)),
62            Statement::Assert(_) => None,
63            Statement::Set { .. } => None,
64            Statement::WalTrace { .. } => None,
65        };
66        self.stmts.push(stmt);
67        if let Some(name) = name {
68            self.name_map
69                .insert_secondary(&name, source.into(), description.to_string())
70        }
71    }
72
73    pub fn append_secondary(
74        &mut self,
75        other: Vec<Statement>,
76        source: impl Into<NameSource> + Clone,
77        description: &str,
78    ) {
79        for statement in other {
80            self.push_secondary(statement, source.clone(), description)
81        }
82    }
83
84    pub fn append(&mut self, mut other: StatementList) {
85        self.stmts.append(&mut other.stmts);
86        self.name_map.merge(other.name_map)
87    }
88
89    pub fn to_vec(self, name_map: &mut NameSourceMap) -> Vec<Statement> {
90        name_map.merge(self.name_map);
91        self.stmts
92    }
93    pub fn to_vec_no_source_map(self) -> Vec<Statement> {
94        self.stmts
95    }
96}
97
98impl std::fmt::Display for StatementList {
99    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100        write!(
101            f,
102            "\n{}\n",
103            self.stmts.iter().map(|s| s.to_string()).join("\n")
104        )
105    }
106}