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