Skip to main content

litex/execute/
exec_have_exist_obj_stmt.rs

1use crate::prelude::*;
2
3impl Runtime {
4    pub fn exec_have_exist_obj_stmt(
5        &mut self,
6        have_exist_obj_stmt: &HaveByExistStmt,
7    ) -> Result<StmtResult, RuntimeError> {
8        let exist_fact_in_have_obj_stmt = &have_exist_obj_stmt.exist_fact_in_have_obj_st;
9        let verify_state = VerifyState::new(0, false);
10
11        let result = self
12            .verify_exist_fact(exist_fact_in_have_obj_stmt, &verify_state)
13            .map_err(|verify_error| {
14                exec_stmt_error_with_stmt_and_cause(
15                    have_exist_obj_stmt.clone().into(),
16                    verify_error,
17                )
18            })?;
19        if result.is_unknown() {
20            return Err(short_exec_error(
21                have_exist_obj_stmt.clone().into(),
22                "have_exist_obj_stmt: exist fact is not verified".to_string(),
23                None,
24                vec![],
25            ));
26        }
27
28        if exist_fact_in_have_obj_stmt
29            .params_def_with_type()
30            .number_of_params()
31            != have_exist_obj_stmt.equal_tos.len()
32        {
33            return Err(short_exec_error(
34 have_exist_obj_stmt.clone().into(),
35                    "have_exist_obj_stmt: number of params in exist does not match number of given objs".to_string(),
36                    None,
37                    vec![],
38                ));
39        }
40
41        for obj in have_exist_obj_stmt.equal_tos.iter() {
42            self.store_free_param_or_identifier_name(obj, ParamObjType::Exist)?;
43        }
44
45        let new_obj_names_as_identifier_objs = have_exist_obj_stmt
46            .equal_tos
47            .iter()
48            .map(|s| Identifier::new(s.clone()).into())
49            .collect();
50
51        let mut infer_result = self
52            .store_args_satisfy_param_type_when_not_defining_new_identifiers(
53                exist_fact_in_have_obj_stmt.params_def_with_type(),
54                &new_obj_names_as_identifier_objs,
55                have_exist_obj_stmt.line_file.clone(),
56                ParamObjType::Exist,
57            )
58            .map_err(|e| {
59                exec_stmt_error_with_stmt_and_cause(have_exist_obj_stmt.clone().into(), e)
60            })?;
61
62        let param_to_obj_map = exist_fact_in_have_obj_stmt
63            .params_def_with_type()
64            .param_defs_and_args_to_param_to_arg_map(new_obj_names_as_identifier_objs.as_slice());
65
66        for fact in exist_fact_in_have_obj_stmt.facts().iter() {
67            let instantiated_fact = self
68                .inst_exist_body_fact(fact, &param_to_obj_map, ParamObjType::Exist, None)
69                .map_err(|runtime_error| {
70                    exec_stmt_error_with_stmt_and_cause(
71                        have_exist_obj_stmt.clone().into(),
72                        runtime_error,
73                    )
74                })?
75                .to_fact();
76            let fact_infer_result = self
77                .verify_well_defined_and_store_and_infer_with_default_verify_state(
78                    instantiated_fact,
79                )
80                .map_err(|store_fact_error| {
81                    exec_stmt_error_with_stmt_and_cause(
82                        have_exist_obj_stmt.clone().into(),
83                        store_fact_error,
84                    )
85                })?;
86            infer_result.new_infer_result_inside(fact_infer_result);
87        }
88
89        Ok((NonFactualStmtSuccess::new(
90            have_exist_obj_stmt.clone().into(),
91            infer_result,
92            vec![result],
93        ))
94        .into())
95    }
96}