Skip to main content

mist_parser/parser/items/
function.rs

1use crate::{
2    Rule,
3    ast::*,
4    ast_ensure, ast_expr,
5    error::{AstError, AstResult, IntoErr},
6    parser::{consume_rule, listen_rule},
7};
8
9impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FunctionDecl {
10    type Error = AstError<'a, Self>;
11
12    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
13        ast_ensure!(pair, Rule::function_decl => {
14        let mut inner = pair.into_inner();
15            let visibility = Visibility::try_from(&mut inner);
16            let is_override = consume_rule(&mut inner, Rule::override_kw).map(Override::try_from).transpose();
17            let name = Identifier::try_from(inner.next().unwrap());
18
19            let generics = consume_rule(&mut inner, Rule::generics_decl)
20                .map(GenericsDecl::try_from)
21                .transpose()
22                .map(|v| v.unwrap_or_default());
23
24            let self_param = consume_rule(&mut inner, Rule::self_param).map(|param| {
25                let mut param_inner = param.into_inner();
26                let is_ref = listen_rule(&mut param_inner, Rule::deref_px);
27                let lifetime = consume_rule(&mut param_inner, Rule::lifetime);
28                let mutable = listen_rule(&mut param_inner, Rule::mutable);
29                let name = Pattern::Path(mutable && !is_ref, Path(vec![Identifier(String::from("self"))]));
30                let self_ty = TypeExpr::Path(Path(vec![Identifier(String::from("Self"))]), None);
31
32                VarDecl {
33                    name: name.clone(),
34                    type_: Some(if is_ref {
35                        TypeExpr::Ref {
36                            lifetime:
37                                lifetime.map(|v| Identifier::try_from(v.into_inner().next().unwrap()))
38                                    .transpose()
39                                    .expect("Failed to get lifetime identifier"),
40                            mutable,
41                            ty: Box::new(self_ty)
42                        }
43                    } else {
44                        self_ty
45                    }),
46                }
47            });
48
49            let params = consume_rule(&mut inner, Rule::param_list)
50                .map({
51                    let self_param = self_param.clone();
52                    |params_pair| -> AstResult<'a, ParamList> {
53                        let mut params = ParamList::try_from(params_pair)?;
54                        if let Some(x) = self_param {
55                            params.0.insert(0, x);
56                        }
57                        Ok(params)
58                    }
59                })
60                .unwrap_or_else(|| Ok(ParamList(self_param.into_iter().collect())));
61
62            let return_type = consume_rule(&mut inner, Rule::type_expr)
63                .map(TypeExpr::try_from)
64                .transpose();
65
66            let body = inner.next().map(Block::try_from).transpose();
67
68            ast_expr!(Self {
69                visibility: visibility,
70                is_override: is_override,
71                return_type: return_type,
72                name: name,
73                generics: generics,
74                params: params,
75                body: body,
76            })
77        })
78    }
79}
80
81impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Override {
82    type Error = AstError<'a, Self>;
83
84    fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
85        ast_ensure!(pair, Rule::override_kw => {
86            ast_expr!(Override(pair.into_inner().next().map(ExprPath::try_from).transpose()))
87        })
88    }
89}