mist_parser/parser/common/
statement.rs1use crate::{
2 Rule,
3 ast::*,
4 ast_ensure, ast_expr,
5 error::{AstError, AstResult, IntoErr, collect_recovered},
6 parser::listen_rule,
7};
8
9impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Block {
10 type Error = AstError<'a, Self>;
11
12 fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
13 let mut inner = pair.clone().into_inner();
14
15 ast_ensure!(pair, Rule::block => {
16 ast_expr!(Block(collect_recovered(inner.next().unwrap().into_inner()), inner.next().map(Spanned::try_from).transpose()))
17 })
18 }
19}
20
21impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for StatementBody {
22 type Error = AstError<'a, Self>;
23
24 fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
25 let mut inner = pair.clone().into_inner();
26
27 ast_ensure!(pair, Rule::statement_body => {
28 let i = inner.next().unwrap();
29
30 match i.as_rule() {
31 Rule::expr => ast_expr!(StatementBody::Expression(i.try_into())),
32 Rule::statement_wrapper => ast_expr!(StatementBody::Statement(i.try_into())),
33 _ => AstError::bug_unimplemented(i),
34 }
35 })
36 }
37}
38
39impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for StatementBranch {
40 type Error = AstError<'a, Self>;
41
42 fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
43 let mut inner = pair.clone().into_inner();
44
45 ast_ensure!(pair, Rule::statement_branch => {
46 ast_expr!(StatementBranch {
47 condition: inner.next().unwrap().try_into(),
48 body: inner.next().unwrap().try_into().map(Box::new),
49 })
50 })
51 }
52}
53
54impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Statement {
55 type Error = AstError<'a, Self>;
56
57 fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
58 let rule = pair.as_rule();
59 let mut inner = pair.clone().into_inner();
60
61 match rule {
62 Rule::statement | Rule::basic_stmt | Rule::control_flow => {
63 Statement::try_from(inner.next().unwrap())
64 }
65
66 Rule::block => ast_expr!(Statement::Block(pair.try_into())),
67
68 Rule::var_decl_statement => ast_expr!(Statement::VarDecl(pair.try_into())),
69
70 Rule::return_stmt => {
71 ast_expr!(Statement::Return(
72 inner.next().map(Expression::try_from).transpose()
73 ))
74 }
75
76 Rule::break_stmt => Ok(Statement::Break),
77
78 Rule::continue_stmt => Ok(Statement::Continue),
79
80 Rule::if_stmt => {
81 ast_expr!(Statement::If {
82 initial: inner.next().unwrap().try_into(),
83 else_if: collect_recovered(inner.next().unwrap().into_inner()),
84 else_branch: inner.next().map(StatementBody::try_from).transpose(),
85 })
86 }
87
88 Rule::while_stmt => ast_expr!(Statement::While(inner.next().unwrap().try_into())),
89
90 Rule::loop_stmt => ast_expr!(Statement::Loop(inner.next().unwrap().try_into())),
91
92 Rule::c_for_stmt => ast_expr!(Statement::CStyleFor {
93 init: inner.next().unwrap().try_into(),
94 condition: inner.next().unwrap().try_into(),
95 update: inner.next().unwrap().try_into(),
96 body: inner.next().unwrap().try_into(),
97 }),
98
99 Rule::for_stmt => ast_expr!(Statement::For {
100 mutable: Ok(listen_rule(&mut inner, Rule::mutable)) as AstResult<'_, bool>,
101 pattern: inner.next().unwrap().try_into(),
102 iterator: inner.next().unwrap().try_into(),
103 body: inner.next().unwrap().try_into(),
104 }),
105
106 Rule::match_stmt => ast_expr!(Statement::Match(
107 inner.next().unwrap().try_into(),
108 inner
109 .map(|match_itms| {
110 let mut match_inner = match_itms.into_inner();
111 Ok((
112 collect_recovered(match_inner.next().unwrap().into_inner()).get()?,
113 Expression::try_from(match_inner.next().unwrap()).get()?,
114 ))
115 })
116 .collect::<AstResult<'a, Vec<_>>>(),
117 )),
118
119 _ => AstError::bug_unimplemented(pair),
120 }
121 }
122}