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