mist_parser/parser/common/
expr.rs1use crate::{
2 Rule,
3 ast::*,
4 ast_expr,
5 error::{AstError, GetLength, IntoErr, collect_recovered, collect_recovered_map},
6};
7
8impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Expression {
9 type Error = AstError<'a, Self>;
10
11 fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
12 let rule = pair.as_rule();
13 let mut inner = pair.clone().into_inner();
14
15 match rule {
16 Rule::expr => {
17 let prefixes = inner
18 .next()
19 .map(|p| collect_recovered::<Prefix, Prefix>(p.into_inner()))
20 .unwrap_or_else(|| Ok(Vec::new()));
21
22 let exp = Expression::try_from(inner.next().unwrap());
23
24 if inner.len() > 0 || prefixes.len() > 0 {
25 ast_expr!(Expression::Fix {
26 initial: exp.map(Box::new),
27 prefixes: prefixes,
28 postfixes: collect_recovered(inner),
29 })
30 } else {
31 exp
32 }
33 }
34
35 Rule::primary => inner.next().unwrap().try_into(),
36 Rule::static_path => ast_expr!(Expression::Path(pair.try_into())),
37 Rule::literal => ast_expr!(Expression::Literal(pair.try_into())),
38
39 _ => AstError::bug_unimplemented(pair),
40 }
41 }
42}
43
44impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Prefix {
45 type Error = AstError<'a, Self>;
46
47 fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
48 Ok(match pair.as_rule() {
49 Rule::prefix => Self::try_from(pair.into_inner().next().unwrap())?,
50 Rule::deref_px => Self::Deref,
51 Rule::mut_ref_px => Self::RefMut,
52 Rule::ref_px => Self::Ref,
53 Rule::new_px => Self::New,
54 Rule::not_px => Self::Not,
55
56 _ => return AstError::bug_unimplemented(pair),
57 })
58 }
59}
60
61impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Postfix {
62 type Error = AstError<'a, Self>;
63
64 fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
65 let rule = pair.as_rule();
66 let mut inner = pair.clone().into_inner();
67
68 match rule {
69 Rule::postfix => Postfix::try_from(inner.next().unwrap()),
70
71 Rule::field_px => {
72 ast_expr!(Postfix::FieldAccess(inner.next().unwrap().try_into()))
73 }
74
75 Rule::call_px => ast_expr!(Postfix::Call(collect_recovered(inner))),
76
77 Rule::struct_px => ast_expr!(Postfix::StructCall(collect_recovered_map(inner, |p| {
78 let mut pi = p.into_inner();
79 Ok((
80 Identifier::try_from(pi.next().unwrap())?,
81 Expression::try_from(pi.next().unwrap()).get()?,
82 ))
83 }))),
84
85 Rule::index_px => {
86 ast_expr!(Postfix::Index(Expression::try_from(inner.next().unwrap())))
87 }
88
89 Rule::binary_px => {
90 let op_pair = inner.next().unwrap();
91 let op = match op_pair.as_str() {
92 "+" => BinaryOp::Plus,
93 "-" => BinaryOp::Minus,
94 "*" => BinaryOp::Multiply,
95 "/" => BinaryOp::Divide,
96 "%" => BinaryOp::Modulo,
97 "==" => BinaryOp::Equal,
98 "!=" => BinaryOp::NotEqual,
99 "<" => BinaryOp::LessThan,
100 ">" => BinaryOp::GreaterThan,
101 "<=" => BinaryOp::LessThanOrEqual,
102 ">=" => BinaryOp::GreaterThanOrEqual,
103 "&&" => BinaryOp::And,
104 "||" => BinaryOp::Or,
105
106 _ => return AstError::bug_unimplemented(op_pair),
107 };
108
109 Ok(Postfix::Binary(op, inner.next().unwrap().try_into().get()?))
110 }
111
112 Rule::macro_call_px => Ok(Postfix::MacroCall(inner.as_str().to_string())),
113
114 _ => AstError::bug_unimplemented(pair),
115 }
116 }
117}