spade_mir/codegen/
util.rs

1use num::BigUint;
2use spade_common::location_info::Loc;
3
4use crate::ValueName;
5
6impl ValueName {
7    pub fn unescaped_var_name(&self) -> String {
8        match self {
9            ValueName::Named(_, _, _) => {
10                format!("{self}")
11            }
12            ValueName::Expr(id) => format!("_e_{}", id.0),
13        }
14    }
15
16    // Returns true if this name needs to be escaped using `\ `
17    pub fn needs_escaping(&self) -> bool {
18        match self {
19            ValueName::Named(id, _, _) => *id == 0,
20            ValueName::Expr(_) => false,
21        }
22    }
23
24    pub fn var_name(&self) -> String {
25        if self.needs_escaping() {
26            format!("\\{} ", self.unescaped_var_name())
27        } else {
28            self.unescaped_var_name()
29        }
30    }
31
32    pub fn backward_var_name(&self) -> String {
33        match self {
34            ValueName::Named(id, name, _) => {
35                if *id == 0 {
36                    format!("\\{}_mut ", name)
37                } else {
38                    format!("{}_n{}_mut", name, id)
39                }
40            }
41            ValueName::Expr(id) => {
42                format!("_e_{}_mut", id.0)
43            }
44        }
45    }
46}
47
48pub fn escape_path(path: &str) -> String {
49    path.replace("::", "_")
50}
51
52pub fn mangle_entity(module: &str) -> String {
53    if module.starts_with('\\') {
54        module.to_string()
55    } else {
56        format!("e_{}", escape_path(module))
57    }
58}
59
60pub fn mangle_input(no_mangle: &Option<Loc<()>>, input: &str) -> String {
61    if no_mangle.is_some() {
62        input.to_string()
63    } else {
64        format!("{}_i", input)
65    }
66}
67
68pub fn mangle_output(no_mangle: &Option<Loc<()>>, input: &str) -> String {
69    if no_mangle.is_some() {
70        input.to_string()
71    } else {
72        format!("{}_o", input)
73    }
74}
75
76#[derive(PartialEq, Debug)]
77pub enum TupleIndex {
78    /// The indexee is a 1 bit scalar, so no indexing should be performed.
79    /// Codegens as empty string
80    None,
81    /// The indexee is zero width, this is most likely caused by a a mir lowering bug
82    /// where a 0 sized type is indexed
83    ZeroWidth,
84    /// The index is a single bit, i.e. codegens as `[val]`
85    Single(BigUint),
86    /// The index is a range of bits, codegens as [left:right]
87    Range { left: BigUint, right: BigUint },
88}
89
90impl TupleIndex {
91    pub fn verilog_code(&self) -> String {
92        match self {
93            TupleIndex::None => String::new(),
94            TupleIndex::ZeroWidth => panic!("Computed a 0 width tuple index"),
95            TupleIndex::Single(i) => format!("[{i}]"),
96            TupleIndex::Range { left, right } => format!("[{left}:{right}]"),
97        }
98    }
99}