circomspect_program_structure/intermediate_representation/
declarations.rs

1use std::collections::HashMap;
2
3use crate::file_definition::{FileID, FileLocation};
4use crate::ir::*;
5
6/// A structure used to track declared variables.
7#[derive(Default, Clone)]
8pub struct Declarations(HashMap<VariableName, Declaration>);
9
10impl Declarations {
11    #[must_use]
12    pub fn new() -> Declarations {
13        Declarations::default()
14    }
15
16    pub fn add_declaration(&mut self, declaration: &Declaration) {
17        assert!(
18            self.0.insert(declaration.variable_name().clone(), declaration.clone()).is_none(),
19            "variable `{}` already tracked by declaration map",
20            declaration.variable_name()
21        );
22    }
23
24    #[must_use]
25    pub fn get_declaration(&self, name: &VariableName) -> Option<&Declaration> {
26        self.0.get(&name.without_version())
27    }
28
29    #[must_use]
30    pub fn get_type(&self, name: &VariableName) -> Option<&VariableType> {
31        self.get_declaration(name).map(|decl| decl.variable_type())
32    }
33
34    pub fn iter(&self) -> impl Iterator<Item = (&VariableName, &Declaration)> {
35        self.0.iter()
36    }
37
38    #[must_use]
39    pub fn len(&self) -> usize {
40        self.0.len()
41    }
42
43    #[must_use]
44    pub fn is_empty(&self) -> bool {
45        self.0.is_empty()
46    }
47}
48
49/// To avoid having to add a new declaration for each new version of a variable
50/// we track all declarations as part of the CFG header.
51#[derive(Clone, PartialEq, Eq, Hash)]
52pub struct Declaration {
53    name: VariableName,
54    var_type: VariableType,
55    dimensions: Vec<Expression>,
56    file_id: Option<FileID>,
57    file_location: FileLocation,
58}
59
60impl Declaration {
61    pub fn new(
62        name: &VariableName,
63        var_type: &VariableType,
64        dimensions: &[Expression],
65        file_id: &Option<FileID>,
66        file_location: &FileLocation,
67    ) -> Declaration {
68        Declaration {
69            name: name.clone(),
70            var_type: var_type.clone(),
71            dimensions: dimensions.to_vec(),
72            file_id: *file_id,
73            file_location: file_location.clone(),
74        }
75    }
76
77    #[must_use]
78    pub fn file_id(&self) -> Option<FileID> {
79        self.file_id
80    }
81
82    #[must_use]
83    pub fn file_location(&self) -> FileLocation {
84        self.file_location.clone()
85    }
86
87    #[must_use]
88    pub fn variable_name(&self) -> &VariableName {
89        &self.name
90    }
91
92    #[must_use]
93    pub fn variable_type(&self) -> &VariableType {
94        &self.var_type
95    }
96
97    #[must_use]
98    pub fn dimensions(&self) -> &Vec<Expression> {
99        &self.dimensions
100    }
101}