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