Skip to main content

litex/execute/by_stmt/
family_by_stmt.rs

1use crate::prelude::*;
2
3impl Runtime {
4    // `by family as set: \p(R)` stores the instantiated `\p(R) =` body.
5    pub fn exec_by_family_stmt(
6        &mut self,
7        stmt: &ByFamilyAsSetStmt,
8    ) -> Result<StmtResult, RuntimeError> {
9        let stmt_exec: Stmt = stmt.clone().into();
10        let family_ty = match &stmt.family_obj {
11            Obj::FamilyObj(f) => f,
12            _ => {
13                return Err(short_exec_error(
14                    stmt_exec,
15                    "by family as set: expected `\\name(...)` family object".to_string(),
16                    None,
17                    vec![],
18                ));
19            }
20        };
21
22        let family_name = family_ty.name.to_string();
23        let def = match self.get_cloned_family_definition_by_name(&family_name) {
24            Some(d) => d,
25            None => {
26                return Err(short_exec_error(
27                    stmt_exec.clone(),
28                    format!("by family as set: family `{}` is not defined", family_name),
29                    None,
30                    vec![],
31                ));
32            }
33        };
34
35        let expected_count = def.params_def_with_type.number_of_params();
36        if family_ty.params.len() != expected_count {
37            return Err(short_exec_error(
38                stmt_exec,
39                format!(
40                    "by family as set: family `{}` expects {} type argument(s), got {}",
41                    family_name,
42                    expected_count,
43                    family_ty.params.len()
44                ),
45                None,
46                vec![],
47            ));
48        }
49
50        let param_to_arg_map = def
51            .params_def_with_type
52            .param_defs_and_args_to_param_to_arg_map(family_ty.params.as_slice());
53
54        let right = self
55            .inst_obj(&def.equal_to, &param_to_arg_map, ParamObjType::DefHeader)
56            .map_err(|e| {
57                short_exec_error(
58                    stmt_exec.clone(),
59                    "by family as set: failed to instantiate family body `equal_to`".to_string(),
60                    Some(e),
61                    vec![],
62                )
63            })?;
64
65        let verify_state = VerifyState::new(0, false);
66        self.verify_obj_well_defined_and_store_cache(&stmt.family_obj, &verify_state)
67            .map_err(|e| {
68                short_exec_error(
69                    stmt_exec.clone(),
70                    format!(
71                        "by family as set: left-hand side `{}` is not well-defined",
72                        stmt.family_obj
73                    ),
74                    Some(e),
75                    vec![],
76                )
77            })?;
78        self.verify_obj_well_defined_and_store_cache(&right, &verify_state)
79            .map_err(|e| {
80                short_exec_error(
81                    stmt_exec.clone(),
82                    format!(
83                        "by family as set: instantiated body `{}` is not well-defined",
84                        right
85                    ),
86                    Some(e),
87                    vec![],
88                )
89            })?;
90
91        let equal_fact =
92            EqualFact::new(stmt.family_obj.clone(), right, stmt.line_file.clone()).into();
93
94        // Keep the directly generated fact before appending store+infer results.
95        let mut infer_result = InferResult::new();
96        infer_result.push_atomic_fact(&equal_fact);
97        infer_result.new_infer_result_inside(
98            self.store_atomic_fact_without_well_defined_verified_and_infer(equal_fact)?,
99        );
100
101        Ok((NonFactualStmtSuccess::new(stmt_exec, infer_result, vec![])).into())
102    }
103}