Skip to main content

litex/execute/
exec_have_obj_equal_stmt.rs

1use crate::prelude::*;
2use std::collections::HashMap;
3
4impl Runtime {
5    // TODO: THIS IS A MESS
6    pub fn exec_have_obj_equal_stmt(
7        &mut self,
8        have_obj_equal_stmt: &HaveObjEqualStmt,
9    ) -> Result<StmtResult, RuntimeError> {
10        if have_obj_equal_stmt.param_def.number_of_params()
11            != have_obj_equal_stmt.objs_equal_to.len()
12        {
13            return Err(short_exec_error(
14 have_obj_equal_stmt.clone().into(),
15                    "have_obj_equal_stmt: number of params in param_def does not match number of objs_equal_to".to_string(),
16                    None,
17                    vec![],
18                ));
19        }
20
21        let mut current_index = 0;
22        let mut param_to_obj_map: HashMap<String, Obj> = HashMap::new();
23        for param_def in have_obj_equal_stmt.param_def.groups.iter() {
24            let current_type_holder = self
25                .inst_param_type(
26                    &param_def.param_type,
27                    &param_to_obj_map,
28                    ParamObjType::Identifier,
29                )
30                .map_err(|runtime_error| {
31                    short_exec_error(
32                        have_obj_equal_stmt.clone().into(),
33                        "",
34                        Some(runtime_error),
35                        vec![],
36                    )
37                })?;
38            let current_type = &current_type_holder;
39            for name in param_def.params.iter() {
40                let current_param_equal_to = &have_obj_equal_stmt.objs_equal_to[current_index];
41
42                let verify_result = self
43                    .verify_obj_satisfies_param_type(
44                        current_param_equal_to.clone(),
45                        current_type,
46                        &VerifyState::new(0, false),
47                    )
48                    .map_err(|verify_error| {
49                        short_exec_error(
50                            have_obj_equal_stmt.clone().into(),
51                            "",
52                            Some(verify_error),
53                            vec![],
54                        )
55                    })?;
56                if verify_result.is_unknown() {
57                    let msg = format!(
58                        "have_obj_equal_stmt: {} is not in type {}",
59                        current_param_equal_to, current_type
60                    );
61                    return Err(short_exec_error(
62                        have_obj_equal_stmt.clone().into(),
63                        msg,
64                        None,
65                        vec![],
66                    ));
67                }
68
69                param_to_obj_map.insert(name.clone(), current_param_equal_to.clone());
70                current_index += 1;
71            }
72        }
73
74        let mut infer_result = InferResult::new();
75
76        let param_infer_result = self
77            .define_params_with_type(
78                &have_obj_equal_stmt.param_def,
79                true,
80                ParamObjType::Identifier,
81            )
82            .map_err(|define_params_error| {
83                short_exec_error(
84                    have_obj_equal_stmt.clone().into(),
85                    "",
86                    Some(define_params_error),
87                    vec![],
88                )
89            })?;
90        infer_result.new_infer_result_inside(param_infer_result);
91
92        for (name, obj) in have_obj_equal_stmt
93            .param_def
94            .collect_param_names()
95            .iter()
96            .zip(have_obj_equal_stmt.objs_equal_to.iter())
97        {
98            let equal_to_fact = EqualFact::new(
99                Identifier::new(name.clone()).into(),
100                obj.clone(),
101                have_obj_equal_stmt.line_file.clone(),
102            )
103            .into();
104            let equal_to_fact_infer_result = self
105                .store_atomic_fact_without_well_defined_verified_and_infer(equal_to_fact)
106                .map_err(|store_fact_error| {
107                    short_exec_error(
108                        have_obj_equal_stmt.clone().into(),
109                        "",
110                        Some(store_fact_error),
111                        vec![],
112                    )
113                })?;
114            infer_result.new_infer_result_inside(equal_to_fact_infer_result);
115        }
116
117        let lf = have_obj_equal_stmt.line_file.clone();
118        for ((name, param_type), obj) in have_obj_equal_stmt
119            .param_def
120            .collect_param_names_with_types()
121            .into_iter()
122            .zip(have_obj_equal_stmt.objs_equal_to.iter())
123        {
124            match (param_type, obj) {
125                (ParamType::Obj(Obj::FiniteSeqSet(fs)), Obj::FiniteSeqListObj(list)) => {
126                    self.store_known_finite_seq_list_obj(
127                        &name,
128                        list.clone(),
129                        Some(fs.clone()),
130                        lf.clone(),
131                    );
132                }
133                (ParamType::Obj(Obj::MatrixSet(ms)), Obj::MatrixListObj(m)) => {
134                    self.store_known_matrix_list_obj(
135                        &name,
136                        m.clone(),
137                        Some(ms.clone()),
138                        lf.clone(),
139                    );
140                }
141                _ => {}
142            }
143        }
144
145        Ok(
146            (NonFactualStmtSuccess::new(have_obj_equal_stmt.clone().into(), infer_result, vec![]))
147                .into(),
148        )
149    }
150}