1use crate::{parse::*, parser::*, rc::*, syntax::*};
5
6impl Parse for RangeFirst {
7 fn parse(pair: Pair) -> ParseResult<Self> {
8 Ok(Self(Box::new(
9 pair.find(Rule::expression)
10 .or(pair
11 .find(Rule::integer_literal)
12 .map(|i| Expression::Literal(Literal::Integer(i))))
13 .expect("Expression"),
14 )))
15 }
16}
17
18impl Parse for RangeLast {
19 fn parse(pair: Pair) -> ParseResult<Self> {
20 Ok(Self(Box::new(
21 pair.find(Rule::expression)
22 .or(pair
23 .find(Rule::integer_literal)
24 .map(|i| Expression::Literal(Literal::Integer(i))))
25 .expect("Expression"),
26 )))
27 }
28}
29
30impl Parse for RangeExpression {
31 fn parse(pair: Pair) -> ParseResult<Self> {
32 Ok(Self {
33 first: pair.find(Rule::range_start).expect("Range start"),
34 last: pair.find(Rule::range_end).expect("Range end"),
35 src_ref: pair.src_ref(),
36 })
37 }
38}
39
40impl Parse for ListExpression {
41 fn parse(pair: Pair) -> ParseResult<Self> {
42 pair.inner()
43 .filter_map(|pair| match pair.as_rule() {
44 Rule::expression => Some(Expression::parse(pair)),
45 _ => None,
46 })
47 .collect::<Result<Vec<_>, _>>()
48 }
49}
50
51impl Parse for ArrayExpression {
52 fn parse(pair: Pair) -> ParseResult<Self> {
53 Ok(Self {
54 inner: pair
55 .find(Rule::range_expression)
56 .map(ArrayExpressionInner::Range)
57 .or(pair
58 .find(Rule::list_expression)
59 .map(ArrayExpressionInner::List))
60 .unwrap_or_default(),
61 unit: pair.find(Rule::unit).unwrap_or_default(),
62 src_ref: pair.clone().into(),
63 })
64 }
65}
66
67impl Parse for Marker {
68 fn parse(pair: Pair) -> ParseResult<Self> {
69 Parser::ensure_rule(&pair, Rule::marker);
70 Ok(Self {
71 id: Identifier::parse(pair.inner().next().expect(INTERNAL_PARSE_ERROR))?,
72 src_ref: pair.src_ref(),
73 })
74 }
75}
76
77lazy_static::lazy_static! {
78 static ref PRATT_PARSER: pest::pratt_parser::PrattParser<Rule> = {
80 use pest::pratt_parser::{Assoc, Op,PrattParser};
81 use Assoc::*;
82 use Rule::*;
83
84 PrattParser::new()
86 .op(Op::infix(or, Left) | Op::infix(and, Left))
88 .op(Op::infix(equal, Left) | Op::infix(not_equal, Left))
89 .op(Op::infix(greater_than, Left) | Op::infix(less_than, Left))
90 .op(Op::infix(less_equal, Left) | Op::infix(greater_equal, Left))
91 .op(Op::infix(add, Left) | Op::infix(subtract, Left))
92 .op(Op::infix(multiply, Left) | Op::infix(divide, Left))
93 .op(Op::infix(r#union, Left) | Op::infix(intersect, Left))
94 .op(Op::infix(power_xor, Left))
95 .op(Op::infix(near, Left))
96 .op(Op::prefix(unary_minus))
97 .op(Op::prefix(unary_plus))
98 .op(Op::prefix(unary_not))
99 .op(Op::postfix(method_call))
100 .op(Op::postfix(array_element_access))
101 .op(Op::postfix(tuple_element_access))
102 .op(Op::postfix(attribute_access))
103 };
104}
105
106impl Expression {
107 pub fn literal_from_str(s: &str) -> ParseResult<Self> {
109 use std::str::FromStr;
110 if s.len() > 1 && s.starts_with('"') && s.ends_with('"') {
111 Ok(Self::FormatString(FormatString::from_str(s)?))
112 } else {
113 Ok(Self::Literal(Literal::from_str(s)?))
114 }
115 }
116}
117
118impl Parse for Expression {
119 fn parse(pair: Pair) -> ParseResult<Self> {
120 Parser::ensure_rule(&pair, Rule::expression);
121
122 PRATT_PARSER
123 .map_primary(|primary| {
124 match (
125 Pair::new(primary.clone(), pair.source_hash()),
126 primary.as_rule(),
127 ) {
128 (primary, Rule::literal) => Ok(Self::Literal(Literal::parse(primary)?)),
129 (primary, Rule::expression) => Ok(Self::parse(primary)?),
130 (primary, Rule::array_expression) => {
131 Ok(Self::ArrayExpression(ArrayExpression::parse(primary)?))
132 }
133 (primary, Rule::tuple_expression) => {
134 Ok(Self::TupleExpression(TupleExpression::parse(primary)?))
135 }
136 (primary, Rule::format_string) => {
137 Ok(Self::FormatString(FormatString::parse(primary)?))
138 }
139 (primary, Rule::body) => Ok(Self::Body(Body::parse(primary)?)),
140 (primary, Rule::if_statement) => {
141 let statement = IfStatement::parse(primary)?;
142 if !statement.is_complete() {
143 Err(ParseError::IncompleteIfExpression(statement.src_ref()))
144 } else {
145 Ok(Self::If(Box::new(statement)))
146 }
147 },
148 (primary, Rule::call) => Ok(Self::Call(Call::parse(primary)?)),
149 (primary, Rule::qualified_name) => {
150 Ok(Self::QualifiedName(QualifiedName::parse(primary)?))
151 }
152 (primary, Rule::marker) => Ok(Self::Marker(Marker::parse(primary)?)),
153 rule => unreachable!(
154 "Expression::parse expected atom, found {:?} {:?}",
155 rule,
156 pair.as_span().as_str()
157 ),
158 }
159 })
160 .map_infix(|lhs, op, rhs| {
161 let op = match op.as_rule() {
162 Rule::add => "+",
163 Rule::subtract => "-",
164 Rule::multiply => "*",
165 Rule::divide => "/",
166 Rule::r#union => "|",
167 Rule::intersect => "&",
168 Rule::power_xor => "^",
169 Rule::greater_than => ">",
170 Rule::less_than => "<",
171 Rule::less_equal => "≤",
172 Rule::greater_equal => "≥",
173 Rule::equal => "==",
174 Rule::near => "~",
175 Rule::not_equal => "!=",
176 Rule::and => "&",
177 Rule::or => "|",
178
179 rule => unreachable!(
180 "Expression::parse expected infix operation, found {:?}",
181 rule
182 ),
183 };
184 Ok(Self::BinaryOp {
185 lhs: Box::new(lhs?),
186 op: op.into(),
187 rhs: Box::new(rhs?),
188 src_ref: pair.clone().into(),
189 })
190 })
191 .map_prefix(|op, rhs| {
192 let op = match op.as_rule() {
193 Rule::unary_minus => '-',
194 Rule::unary_plus => '+',
195 Rule::unary_not => '!',
196 _ => unreachable!(),
197 };
198
199 Ok(Self::UnaryOp {
200 op: op.into(),
201 rhs: Box::new(rhs?),
202 src_ref: pair.clone().into(),
203 })
204 })
205 .map_postfix(|lhs, op| {
206 match (Pair::new(op.clone(), pair.source_hash()), op.as_rule()) {
207 (op, Rule::array_element_access) => Ok(Self::ArrayElementAccess(
208 Box::new(lhs?),
209 Box::new(Self::parse(op)?),
210 pair.clone().into(),
211 )),
212 (op, Rule::attribute_access) => {
213 let op = op.inner().next().expect(INTERNAL_PARSE_ERROR);
214 Ok(Self::AttributeAccess(
215 Box::new(lhs?),
216 Identifier::parse(op)?,
217 pair.clone().into(),
218 ))
219 }
220 (op, Rule::tuple_element_access) => {
221 let op = op.inner().next().expect(INTERNAL_PARSE_ERROR);
222 match op.as_rule() {
223 Rule::identifier => Ok(Self::PropertyAccess(
224 Box::new(lhs?),
225 Identifier::parse(op)?,
226 pair.clone().into(),
227 )),
228 rule => unreachable!("Expected identifier or int, found {:?}", rule),
229 }
230 }
231 (op, Rule::method_call) => Ok(Self::MethodCall(
232 Box::new(lhs?),
233 MethodCall::parse(op)?,
234 pair.clone().into(),
235 )),
236 rule => {
237 unreachable!("Expr::parse expected postfix operation, found {:?}", rule)
238 }
239 }
240 })
241 .parse(
242 pair.pest_pair()
243 .clone()
244 .into_inner()
245 .filter(|pair| pair.as_rule() != Rule::COMMENT), )
247 }
248}
249
250impl Parse for Rc<Expression> {
251 fn parse(pair: Pair) -> ParseResult<Self> {
252 Ok(Rc::new(Expression::parse(pair)?))
253 }
254}
255
256impl Parse for TupleExpression {
257 fn parse(pair: Pair) -> ParseResult<Self> {
258 Ok(TupleExpression {
259 args: crate::find_rule!(pair, argument_list)?,
260 src_ref: pair.clone().into(),
261 })
262 }
263}
264
265#[macro_export]
267macro_rules! tuple_expression {
268 ($code:literal) => {{
269 $crate::parse!(
270 TupleExpression,
271 $crate::parser::Rule::tuple_expression,
272 $code
273 )
274 }};
275}