spade_mir/
type_list.rs

1use std::collections::HashMap;
2
3use crate::{types::Type, Entity, MirInput, Statement, ValueName};
4
5pub struct TypeList {
6    inner: HashMap<ValueName, Type>,
7}
8
9impl TypeList {
10    pub fn empty() -> Self {
11        Self {
12            inner: HashMap::new(),
13        }
14    }
15
16    pub fn from_entity(e: &Entity) -> Self {
17        let mut result = Self::empty();
18
19        for MirInput {
20            val_name,
21            name: _,
22            ty,
23            no_mangle: _,
24        } in &e.inputs
25        {
26            result.inner.insert(val_name.clone(), ty.clone());
27        }
28
29        result.add_statements(&e.statements);
30
31        result
32    }
33
34    fn add_statements(&mut self, stmts: &[Statement]) {
35        for stmt in stmts {
36            match stmt {
37                Statement::Binding(b) => {
38                    self.inner.insert(b.name.clone(), b.ty.clone());
39                }
40                Statement::Register(reg) => {
41                    self.inner.insert(reg.name.clone(), reg.ty.clone());
42                }
43                Statement::Constant(idx, ty, _) => {
44                    self.inner.insert(ValueName::Expr(*idx), ty.clone());
45                }
46                Statement::Assert(_) => {}
47                Statement::Set { .. } => {
48                    // No new types introduced
49                }
50                Statement::WalTrace { .. } => {}
51            }
52        }
53    }
54
55    /// Allows in place construction of a type list
56    #[cfg(test)]
57    pub fn with(mut self, v: ValueName, t: Type) -> Self {
58        self.inner.insert(v, t);
59        self
60    }
61}
62
63impl std::ops::Index<&ValueName> for TypeList {
64    type Output = Type;
65
66    fn index(&self, index: &ValueName) -> &Self::Output {
67        self.inner
68            .get(index)
69            .unwrap_or_else(|| panic!("No type found for {index}"))
70    }
71}