Skip to main content

litex/parse/
parse_param_def.rs

1use crate::prelude::*;
2
3impl Runtime {
4    /// Each parameter name is pushed to [`Runtime::parsing_free_param_collection`] with `free_param_kind`
5    /// before its shared type is parsed, so later parameter types in the same group (or later groups)
6    /// can resolve earlier parameters. Use [`ParamObjType::DefHeader`] for `prop { ... }` and `family`
7    /// headers, [`ParamObjType::Forall`] for `forall`, [`ParamObjType::Exist`] for `exist`, [`ParamObjType::Identifier`] for `let` / `have`, etc.
8    pub fn parse_param_def_with_param_type_and_skip_comma(
9        &mut self,
10        tb: &mut TokenBlock,
11        free_param_kind: ParamObjType,
12    ) -> Result<ParamGroupWithParamType, RuntimeError> {
13        let param = tb.advance()?;
14        let owned = param.clone();
15        self.parsing_free_param_collection.begin_scope(
16            free_param_kind,
17            std::slice::from_ref(&owned),
18            tb.line_file.clone(),
19        )?;
20        let param_def_with_param_type = if tb.current()? != COMMA {
21            ParamGroupWithParamType::new(vec![param], self.parse_param_type(tb)?)
22        } else {
23            let mut vec_of_params = vec![param];
24
25            while tb.current_token_is_equal_to(COMMA) {
26                tb.skip()?;
27                let p = tb.advance()?;
28                let owned = p.clone();
29                self.parsing_free_param_collection.begin_scope(
30                    free_param_kind,
31                    std::slice::from_ref(&owned),
32                    tb.line_file.clone(),
33                )?;
34                vec_of_params.push(p);
35            }
36            let param_type = self.parse_param_type(tb)?;
37
38            ParamGroupWithParamType::new(vec_of_params, param_type)
39        };
40        if tb.current_token_is_equal_to(COMMA) {
41            tb.skip_token(COMMA)?;
42        }
43        Ok(param_def_with_param_type)
44    }
45
46    pub fn parse_param_type(&mut self, tb: &mut TokenBlock) -> Result<ParamType, RuntimeError> {
47        match tb.current()? {
48            NONEMPTY_SET => self.parse_param_type_nonempty_set(tb),
49            FINITE_SET => self.parse_param_type_finite_set(tb),
50            SET => self.parse_param_type_set(tb),
51            RESTRICTIVE => self.parse_param_type_restrictive(tb),
52            s if s == FAMILY_OBJ_PREFIX => self
53                .parse_family_obj(tb)
54                .map(|f| ParamType::Obj(Obj::FamilyObj(f))),
55            _ => self.parse_param_type_obj(tb),
56        }
57    }
58
59    pub fn parse_param_type_restrictive(
60        &mut self,
61        tb: &mut TokenBlock,
62    ) -> Result<ParamType, RuntimeError> {
63        tb.skip_token(RESTRICTIVE)?;
64        tb.skip_token(LEFT_BRACE)?;
65        // Same shape as the second argument of `$restrict_fn_in`: `fn` + fn-set.
66        tb.skip_token(FN_LOWER_CASE)?;
67        let fn_set = self.parse_fn_set(tb)?;
68        tb.skip_token(RIGHT_BRACE)?;
69        Ok(ParamType::Restrictive(fn_set))
70    }
71
72    pub fn parse_param_type_nonempty_set(
73        &self,
74        tb: &mut TokenBlock,
75    ) -> Result<ParamType, RuntimeError> {
76        tb.skip_token(NONEMPTY_SET)?;
77        Ok(ParamType::NonemptySet(NonemptySet::new()))
78    }
79
80    pub fn parse_param_type_finite_set(
81        &self,
82        tb: &mut TokenBlock,
83    ) -> Result<ParamType, RuntimeError> {
84        tb.skip_token(FINITE_SET)?;
85        Ok(ParamType::FiniteSet(FiniteSet::new()))
86    }
87
88    pub fn parse_param_type_set(&self, tb: &mut TokenBlock) -> Result<ParamType, RuntimeError> {
89        tb.skip_token(SET)?;
90        Ok(ParamType::Set(Set::new()))
91    }
92
93    pub fn parse_param_type_obj(&mut self, tb: &mut TokenBlock) -> Result<ParamType, RuntimeError> {
94        let obj = self.parse_obj(tb)?;
95        Ok(ParamType::Obj(obj))
96    }
97}