litex/execute/by_stmt/
family_by_stmt.rs1use crate::prelude::*;
2
3impl Runtime {
4 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, ¶m_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 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}