1mod error;
5mod helpers;
6mod simplify;
7
8use crate::Span;
9use crate::ast::*;
10use crate::parser::helpers::{binop, comment_parser};
11use crate::parser::simplify::simplify_unary_op;
12use crate::tokens::*;
13use chumsky::error::Rich;
14use chumsky::input::{Input, MappedInput};
15use chumsky::prelude::*;
16use chumsky::{Parser, extra, select_ref};
17pub use error::ParseError;
18use helpers::ParserExt;
19use std::str::FromStr;
20
21type Extra<'tokens> = extra::Err<Rich<'tokens, Token<'tokens>, Span>>;
22
23pub fn map_token_input<'a, 'token>(
24 spanned: &'a SpannedToken<Token<'token>>,
25) -> (&'a Token<'token>, &'a Span) {
26 (&spanned.token, &spanned.span)
27}
28
29type InputMap<'input, 'token> =
30 fn(&'input SpannedToken<Token<'token>>) -> (&'input Token<'token>, &'input Span);
31
32type ParserInput<'input, 'token> = MappedInput<
33 'input,
34 Token<'token>,
35 Span,
36 &'input [SpannedToken<Token<'token>>],
37 InputMap<'input, 'token>,
38>;
39
40fn input<'input, 'tokens>(
41 input: &'input [SpannedToken<Token<'tokens>>],
42) -> ParserInput<'input, 'tokens> {
43 let end = input.last().map(|t| t.span.end).unwrap_or_default();
44 Input::map(input, end..end, map_token_input)
45}
46
47pub fn parse<'tokens>(
49 tokens: &'tokens [SpannedToken<Token<'tokens>>],
50) -> Result<SourceFile, Vec<ParseError>> {
51 parser()
52 .parse(input(tokens))
53 .into_result()
54 .map_err(|errors| errors.into_iter().map(ParseError::new).collect())
55}
56
57fn parser<'tokens>()
58-> impl Parser<'tokens, ParserInput<'tokens, 'tokens>, SourceFile, Extra<'tokens>> {
59 let mut statement_list_parser = Recursive::declare();
60 let mut statement_parser = Recursive::declare();
61 let mut expression_parser = Recursive::declare();
62 let mut type_parser = Recursive::declare();
63 let mut attribute_parser = Recursive::declare();
64 let mut if_inner = Recursive::declare();
65
66 let semi_recovery = none_of(Token::SigilSemiColon).repeated().ignored();
67
68 let block_recovery = just(Token::SigilOpenCurlyBracket)
69 .then(
70 none_of(Token::SigilCloseCurlyBracket)
71 .repeated()
72 .then(just(Token::SigilCloseCurlyBracket)),
73 )
74 .map_with(|_, e| StatementList {
75 span: e.span(),
76 statements: vec![Statement::Error(e.span())],
77 tail: None,
78 extras: ItemExtras::default(),
79 });
80
81 let block = statement_list_parser
82 .clone()
83 .delimited_by(
84 just(Token::SigilOpenCurlyBracket),
85 just(Token::SigilCloseCurlyBracket),
86 )
87 .recover_with(via_parser(block_recovery))
88 .boxed();
89
90 let identifier_parser = select_ref! { Token::Identifier(ident) = e => Identifier {
91 span: e.span(),
92 name: ident.as_ref().into(),
93 } }
94 .labelled("identifier")
95 .boxed();
96
97 let qualified_name = identifier_parser
98 .clone()
99 .separated_by(just(Token::SigilDoubleColon))
100 .at_least(1)
101 .collect::<Vec<_>>()
102 .with_extras()
103 .map_with(|(parts, extras), e| QualifiedName {
104 span: e.span(),
105 parts,
106 extras,
107 })
108 .labelled("qualified name")
109 .boxed();
110
111 let single_type = select_ref! {
112 Token::Identifier(ident) = e => SingleType {
113 span: e.span(),
114 name: ident.as_ref().into()
115 },
116 Token::Unit(unit) = e => SingleType {
117 span: e.span(),
118 name: unit.as_ref().into()
119 },
120 Token::SigilQuote = e => SingleType {
121 span: e.span(),
122 name: r#"""#.into()
123 },
124 }
125 .labelled("quantity type")
126 .boxed();
127
128 type_parser.define({
129 let single = single_type.clone().map(Type::Single);
130 let array = type_parser
131 .clone()
132 .delimited_by(
133 just(Token::SigilOpenSquareBracket),
134 just(Token::SigilCloseSquareBracket),
135 )
136 .map_with(|inner, e| {
137 Type::Array(ArrayType {
138 span: e.span(),
139 inner: Box::new(inner),
140 })
141 })
142 .labelled("array type")
143 .boxed();
144
145 let tuple = identifier_parser
146 .clone()
147 .then_ignore(just(Token::SigilColon))
148 .or_not()
149 .then(type_parser.clone())
150 .separated_by(just(Token::SigilComma))
151 .allow_trailing()
152 .collect::<Vec<_>>()
153 .delimited_by(
154 just(Token::SigilOpenBracket),
155 just(Token::SigilCloseBracket),
156 )
157 .map_with(|inner, e| {
158 Type::Tuple(TupleType {
159 span: e.span(),
160 inner,
161 })
162 })
163 .labelled("tuple type")
164 .boxed();
165
166 single.or(array).or(tuple).labelled("type").boxed()
167 });
168
169 let literal_parser = {
170 let single_value = select_ref! {
171 Token::LiteralFloat(x) = e => {
172 match f64::from_str(x) {
173 Ok(value) => LiteralKind::Float(FloatLiteral {
174 value,
175 span: e.span(),
176 }),
177 Err(err) => LiteralKind::Error(LiteralError {
178 span: e.span(),
179 kind: err.into(),
180 })
181 }
182 },
183 Token::LiteralInt(x) = e => {
184 match i64::from_str(x) {
185 Ok(value) => LiteralKind::Integer(IntegerLiteral {
186 value,
187 span: e.span(),
188 }),
189 Err(err) => LiteralKind::Error(LiteralError {
190 span: e.span(),
191 kind: err.into(),
192 })
193 }
194 },
195 Token::LiteralString(content) = e => {
196 LiteralKind::String(StringLiteral {
197 span: e.span(),
198 content: content.as_ref().into(),
199 })
200 },
201 Token::LiteralBool(value) = e => {
202 LiteralKind::Bool(BoolLiteral {
203 span: e.span(),
204 value: *value,
205 })
206 },
207 }
208 .boxed();
209
210 single_value
211 .then(single_type.clone().or_not())
212 .with_extras()
213 .map_with(|((literal, ty), extras), e| {
214 let literal = match (literal, ty) {
215 (LiteralKind::Float(float), Some(ty)) => {
216 LiteralKind::Quantity(QuantityLiteral {
217 span: e.span(),
218 value: float.value,
219 ty,
220 })
221 }
222 (LiteralKind::Integer(int), Some(ty)) => {
223 LiteralKind::Quantity(QuantityLiteral {
224 span: e.span(),
225 value: int.value as f64,
226 ty,
227 })
228 }
229 (_, Some(_)) => LiteralKind::Error(LiteralError {
230 span: e.span(),
231 kind: LiteralErrorKind::Untypable,
232 }),
233 (literal, None) => literal,
234 };
235 Literal {
236 span: e.span(),
237 literal,
238 extras,
239 }
240 })
241 .labelled("literal")
242 .boxed()
243 };
244
245 let unary_operator_parser = select_ref! {
246 Token::OperatorSubtract => UnaryOperator::Minus,
247 Token::OperatorAdd => UnaryOperator::Plus,
248 Token::OperatorNot => UnaryOperator::Not,
249 }
250 .labelled("unary operator")
251 .boxed();
252
253 let doc_comment = select_ref! {
254 Token::DocComment(comment) => comment,
255 }
256 .repeated()
257 .at_least(1)
258 .collect::<Vec<_>>()
259 .map_with(|lines, e| Comment {
260 span: e.span(),
261 lines: lines.into_iter().map(|s| s.as_ref().into()).collect(),
262 })
263 .labelled("doc-comment")
264 .or_not()
265 .boxed();
266
267 let tuple_recovery = just(Token::SigilOpenBracket)
268 .then(
269 none_of(Token::SigilCloseBracket)
270 .repeated()
271 .then(just(Token::SigilCloseBracket)),
272 )
273 .map_with(|_, e| {
274 (
275 vec![TupleItem {
276 span: e.span(),
277 name: None,
278 value: Expression::Error(e.span()),
279 extras: ItemExtras::default(),
280 }],
281 ItemExtras::default(),
282 )
283 });
284
285 let tuple_body = identifier_parser
286 .clone()
287 .then_ignore(just(Token::OperatorAssignment))
288 .or_not()
289 .then(expression_parser.clone())
290 .with_extras()
291 .map_with(|((name, value), extras), e| TupleItem {
292 span: e.span(),
293 extras,
294 name,
295 value,
296 })
297 .separated_by(just(Token::SigilComma))
298 .allow_trailing()
299 .collect::<Vec<_>>()
300 .boxed();
301
302 let call_inner = qualified_name
303 .clone()
304 .then(
305 tuple_body
306 .clone()
307 .with_extras()
308 .map_with(|(arguments, extras), e| ArgumentList {
309 span: e.span(),
310 extras,
311 arguments: arguments
312 .into_iter()
313 .map(|item| match item.name {
314 Some(name) => Argument::Named(NamedArgument {
315 span: item.span,
316 extras: item.extras,
317 name,
318 value: item.value,
319 }),
320 None => Argument::Unnamed(UnnamedArgument {
321 span: item.span,
322 extras: item.extras,
323 value: item.value,
324 }),
325 })
326 .collect::<Vec<_>>(),
327 })
328 .labelled("function arguments")
329 .delimited_by(
330 just(Token::SigilOpenBracket),
331 just(Token::SigilCloseBracket),
332 )
333 .recover_with(via_parser(tuple_recovery.clone().map_with(|_, e| {
334 ArgumentList {
335 span: e.span(),
336 extras: ItemExtras::default(),
337 arguments: Vec::new(),
338 }
339 }))),
340 )
341 .with_extras()
342 .map_with(|((name, arguments), extras), e| Call {
343 span: e.span(),
344 extras,
345 name,
346 arguments,
347 })
348 .boxed();
349
350 statement_parser.define({
351 let visibility = select_ref! {
352 Token::KeywordPub => Visibility::Public,
353 }
354 .labelled("visibility");
355
356 let expression = attribute_parser
357 .clone()
358 .then(expression_parser.clone())
359 .with_extras()
360 .map_with(
361 |((attributes, expression), extras), e| ExpressionStatement {
362 span: e.span(),
363 extras,
364 attributes,
365 expression,
366 },
367 )
368 .map(Statement::Expression)
369 .boxed();
370
371 let assignment_qualifier = select_ref! {
372 Token::KeywordConst => AssignmentQualifier::Const,
373 Token::KeywordProp => AssignmentQualifier::Prop,
374 }
375 .or_not()
376 .boxed();
377
378 let assignment_inner = doc_comment
379 .clone()
380 .then(attribute_parser.clone())
381 .then(visibility.or_not())
382 .then(assignment_qualifier)
383 .then(identifier_parser.clone())
384 .then(
385 just(Token::SigilColon)
386 .ignore_then(type_parser.clone())
387 .or_not(),
388 )
389 .then_ignore(just(Token::OperatorAssignment))
390 .then(
391 expression_parser.clone().recover_with(via_parser(
392 semi_recovery
393 .clone()
394 .map_with(|_, e| Expression::Error(e.span())),
395 )),
396 )
397 .with_extras()
398 .map_with(
399 |(((((((doc, attributes), visibility), qualifier), name), ty), value), extras),
400 e| {
401 Assignment {
402 span: e.span(),
403 extras,
404 doc,
405 attributes,
406 visibility,
407 qualifier,
408 name,
409 value: Box::new(value),
410 ty,
411 }
412 },
413 )
414 .boxed();
415
416 let assignment = assignment_inner
417 .clone()
418 .map(Statement::Assignment)
419 .labelled("assignment");
420
421 attribute_parser.define({
422 let attribute_command = assignment_inner
423 .clone()
424 .map(AttributeCommand::Assignment)
425 .or(call_inner.clone().map(AttributeCommand::Call))
426 .or(identifier_parser.clone().map(AttributeCommand::Ident));
427
428 just(Token::SigilHash)
429 .ignore_then(just(Token::OperatorNot).or_not().map(|opt| opt.is_some()))
430 .then(
431 attribute_command
432 .separated_by(just(Token::SigilComma))
433 .at_least(1)
434 .collect::<Vec<_>>()
435 .delimited_by(
436 just(Token::SigilOpenSquareBracket),
437 just(Token::SigilCloseSquareBracket),
438 ),
439 )
440 .with_extras()
441 .map_with(|((is_inner, commands), extras), e| Attribute {
442 span: e.span(),
443 is_inner,
444 extras,
445 commands,
446 })
447 .labelled("attribute")
448 .repeated()
449 .collect::<Vec<Attribute>>()
450 .boxed()
451 });
452
453 let comment = comment_parser()
454 .map(Statement::Comment)
455 .labelled("comment")
456 .boxed();
457
458 let arguments_inner = identifier_parser
459 .clone()
460 .then(
461 just(Token::SigilColon)
462 .ignore_then(type_parser.clone())
463 .or_not(),
464 )
465 .then(
466 just(Token::OperatorAssignment)
467 .ignore_then(expression_parser.clone())
468 .or_not(),
469 )
470 .with_extras()
471 .map_with(|(((name, ty), default), extras), e| ArgumentDefinition {
472 span: e.span(),
473 extras,
474 name,
475 ty,
476 default,
477 })
478 .separated_by(just(Token::SigilComma))
479 .allow_trailing()
480 .collect::<Vec<_>>()
481 .boxed();
482
483 let arguments = arguments_inner
484 .with_extras()
485 .map_with(|(arguments, extras), e| ArgumentsDefinition {
486 span: e.span(),
487 extras,
488 arguments,
489 })
490 .delimited_by(
491 just(Token::SigilOpenBracket),
492 just(Token::SigilCloseBracket),
493 )
494 .boxed();
495
496 let module = doc_comment
497 .clone()
498 .then(attribute_parser.clone())
499 .then(visibility.or_not())
500 .then_ignore(just(Token::KeywordMod))
501 .then(identifier_parser.clone())
502 .then(
503 block
504 .clone()
505 .map(Some)
506 .or(just(Token::SigilSemiColon).map(|_| None)),
507 )
508 .with_extras()
509 .map_with(
510 |(((((doc, attributes), visibility), name), body), extras), e| {
511 Statement::Module(ModuleDefinition {
512 span: e.span(),
513 extras,
514 doc,
515 attributes,
516 visibility,
517 name,
518 body,
519 })
520 },
521 )
522 .boxed();
523
524 let use_parts = identifier_parser
525 .clone()
526 .map(UseStatementPart::Identifier)
527 .or(just(Token::OperatorMultiply).map_with(|_, e| UseStatementPart::Glob(e.span())))
528 .separated_by(just(Token::SigilDoubleColon))
529 .at_least(1)
530 .collect::<Vec<_>>()
531 .with_extras()
532 .map_with(|(parts, extras), e| UseName {
533 span: e.span(),
534 extras,
535 parts,
536 })
537 .boxed();
538
539 let use_statement = visibility
540 .or_not()
541 .then_ignore(just(Token::KeywordUse))
542 .then(use_parts)
543 .then(
544 just(Token::KeywordAs)
545 .ignore_then(identifier_parser.clone())
546 .or_not(),
547 )
548 .with_extras()
549 .map_with(|(((visibility, name), use_as), extras), e| {
550 Statement::Use(UseStatement {
551 span: e.span(),
552 extras,
553 visibility,
554 name,
555 use_as,
556 })
557 })
558 .boxed();
559
560 let workspace_kind = select_ref! {
561 Token::KeywordSketch => WorkbenchKind::Sketch,
562 Token::KeywordPart => WorkbenchKind::Part,
563 Token::KeywordOp => WorkbenchKind::Op,
564 }
565 .boxed();
566
567
568 let init = doc_comment
569 .clone()
570 .then(just(Token::KeywordInit).map_with(|_, e| e.span()))
571 .then(arguments.clone())
572 .then(block.clone())
573 .with_extras()
574 .map_with(|((((doc, keyword_span), arguments), body), extras), e| {
575 Statement::Init(InitDefinition {
576 span: e.span(),
577 keyword_span,
578 extras,
579 doc,
580 arguments,
581 body,
582 })
583 })
584 .boxed();
585 let workspace = doc_comment
586 .clone()
587 .then(attribute_parser.clone())
588 .then(visibility.or_not())
589 .then(workspace_kind)
590 .then(identifier_parser.clone())
591 .then(arguments.clone())
592 .then(block.clone())
593 .with_extras()
594 .map_with(
595 |(((((((doc, attributes), visibility), kind), name), arguments), body), extras),
596 e| {
597 Statement::Workbench(WorkbenchDefinition {
598 span: e.span(),
599 extras,
600 kind,
601 doc,
602 attributes,
603 visibility,
604 name,
605 arguments,
606 body,
607 })
608 },
609 )
610 .boxed();
611
612 let return_statement = just(Token::KeywordReturn)
613 .ignore_then(expression_parser.clone().or_not())
614 .with_extras()
615 .map_with(|(value, extras), e| {
616 Statement::Return(Return {
617 span: e.span(),
618 extras,
619 value,
620 })
621 })
622 .boxed();
623
624 let function = doc_comment
625 .clone()
626 .then(visibility.or_not())
627 .then_ignore(just(Token::KeywordFn))
628 .then(identifier_parser.clone())
629 .then(arguments.clone())
630 .then(
631 just(Token::SigilSingleArrow)
632 .ignore_then(type_parser.clone())
633 .or_not(),
634 )
635 .then(block.clone())
636 .with_extras()
637 .map_with(
638 |((((((doc, visibility), name), arguments), return_type), body), extras), e| {
639 Statement::Function(FunctionDefinition {
640 span: e.span(),
641 extras,
642 doc,
643 visibility,
644 name,
645 arguments,
646 return_type,
647 body,
648 })
649 },
650 )
651 .boxed();
652
653 let if_expression = attribute_parser
654 .clone()
655 .then(if_inner.clone().map(Expression::If))
656 .with_extras()
657 .map_with(|((attributes, expression), extras), e| {
658 Statement::Expression(ExpressionStatement {
659 span: e.span(),
660 extras,
661 attributes,
662 expression,
663 })
664 })
665 .labelled("if statement")
666 .boxed();
667
668 let doc_statement = select_ref! {
669 Token::DocComment(comment) => comment,
670 }
671 .repeated()
672 .at_least(1)
673 .collect::<Vec<_>>()
674 .map_with(|lines, e| Comment {
675 span: e.span(),
676 lines: lines.into_iter().map(|s| s.as_ref().into()).collect(),
677 })
678 .labelled("doc-comment")
679 .map(Statement::Comment)
680 .boxed();
681
682 let with_semi = assignment
683 .or(return_statement)
684 .or(use_statement)
685 .or(expression)
686 .boxed();
687
688 let without_semi = function
689 .or(doc_statement)
690 .or(init)
691 .or(workspace)
692 .or(module)
693 .or(comment)
694 .or(if_expression)
695 .boxed();
696
697 without_semi
698 .or(with_semi.then_ignore(just(Token::SigilSemiColon).labelled("semicolon")))
699 .labelled("statement")
700 });
701
702 statement_list_parser.define({
703 let trailing_expr = attribute_parser
704 .clone()
705 .then(expression_parser.clone())
706 .with_extras()
707 .map_with(
708 |((attributes, expression), extras), e| ExpressionStatement {
709 span: e.span(),
710 extras,
711 attributes,
712 expression,
713 },
714 )
715 .map(Statement::Expression)
716 .map(Box::new)
717 .or_not();
718 statement_parser
719 .repeated()
720 .collect::<Vec<_>>()
721 .then(trailing_expr)
722 .with_extras()
723 .map_with(|((statements, tail), extras), e| StatementList {
724 span: e.span(),
725 extras,
726 statements,
727 tail,
728 })
729 .boxed()
730 });
731
732 expression_parser.define({
733 let unclosed_string = select_ref! {
734 Token::Error(LexerError::UnclosedString(_)) => (),
735 }
736 .ignore_then(
737 semi_recovery
738 .clone()
739 .try_map_with(|_, e| {
740 let span: Span = e.span();
741 Err::<Expression, _>(Rich::custom(
742 (span.start - 1)..span.end,
743 "unclosed string",
744 ))
745 })
746 .recover_with(via_parser(
747 semi_recovery
748 .clone()
749 .map_with(|_, e| Expression::Error(e.span())),
750 )),
751 )
752 .labelled("unclosed string")
753 .boxed();
754
755 let literal = literal_parser
756 .map(Expression::Literal)
757 .labelled("literal")
758 .boxed()
759 .or(unclosed_string);
760
761 let marker = just(Token::SigilAt)
762 .ignore_then(identifier_parser.clone())
763 .map(Expression::Marker)
764 .labelled("marker")
765 .boxed();
766
767 let string_content_part = select_ref! {
768 Token::StringContent(content) = e => StringPart::Content(StringLiteral {
769 span: e.span(),
770 content: content.as_ref().into(),
771 }),
772 Token::Character(char) = e => StringPart::Char(StringCharacter {
773 span: e.span(),
774 character: *char,
775 }),
776 }
777 .labelled("string content")
778 .boxed();
779
780 let format_precision = select_ref!(
781 Token::StringFormatPrecision(precision) = e => {
782 u32::from_str(&precision[1..]).map_err(|err| (err, e.span()))
783 }
784 );
785 let format_width = select_ref!(
786 Token::StringFormatWidth(width) = e => {
787 u32::from_str(&width[1..]).map_err(|err| (err, e.span()))
788 }
789 );
790 let format_spec = format_width
791 .or_not()
792 .then(format_precision.or_not())
793 .map_with(|(width, precision), e| StringFormatSpecification {
794 span: e.span(),
795 width,
796 precision,
797 })
798 .labelled("string format specification")
799 .boxed();
800
801 let string_format_part = expression_parser
802 .clone()
803 .then(format_spec)
804 .with_extras()
805 .delimited_by(
806 just(Token::StringFormatOpen),
807 just(Token::StringFormatClose),
808 )
809 .map_with(
810 |((expression, specification), extras), e| StringExpression {
811 span: e.span(),
812 extras,
813 expression: Box::new(expression),
814 specification: Box::new(specification),
815 },
816 )
817 .map(StringPart::Expression)
818 .labelled("string format expression")
819 .boxed();
820 let string_part = string_content_part
821 .or(string_format_part)
822 .labelled("format string content");
823
824 let string_format = string_part
825 .repeated()
826 .collect::<Vec<_>>()
827 .delimited_by(just(Token::FormatStringStart), just(Token::FormatStringEnd))
828 .with_extras()
829 .map_with(|(parts, extras), e| FormatString {
830 span: e.span(),
831 extras,
832 parts,
833 })
834 .map(Expression::String)
835 .boxed();
836
837 let tuple = tuple_body
838 .clone()
839 .with_extras()
840 .delimited_by(
841 just(Token::SigilOpenBracket),
842 just(Token::SigilCloseBracket),
843 )
844 .recover_with(via_parser(tuple_recovery))
845 .map_with(|(values, extras), e| {
846 Expression::Tuple(TupleExpression {
847 span: e.span(),
848 extras,
849 values,
850 })
851 })
852 .labelled("tuple");
853
854 let bracketed = expression_parser.clone().delimited_by(
855 just(Token::SigilOpenBracket),
856 just(Token::SigilCloseBracket),
857 );
858
859 let array_item = expression_parser
860 .clone()
861 .with_extras()
862 .map_with(|(expression, extras), e| ArrayItem {
863 span: e.span(),
864 extras,
865 expression,
866 })
867 .boxed();
868
869 let array_range = array_item
870 .clone()
871 .then_ignore(just(Token::SigilDoubleDot))
872 .then(array_item.clone())
873 .with_extras()
874 .delimited_by(
875 just(Token::SigilOpenSquareBracket),
876 just(Token::SigilCloseSquareBracket),
877 )
878 .then(single_type.clone().or_not())
879 .map_with(|(((start, end), extras), ty), e| {
880 Expression::ArrayRange(ArrayRangeExpression {
881 span: e.span(),
882 extras,
883 start: Box::new(start),
884 end: Box::new(end),
885 ty,
886 })
887 })
888 .labelled("array range")
889 .boxed();
890
891 let array_list = array_item
892 .clone()
893 .separated_by(just(Token::SigilComma))
894 .allow_trailing()
895 .collect::<Vec<_>>()
896 .with_extras()
897 .delimited_by(
898 just(Token::SigilOpenSquareBracket),
899 just(Token::SigilCloseSquareBracket),
900 )
901 .then(single_type.clone().or_not())
902 .map_with(|((items, extras), ty), e| {
903 Expression::ArrayList(ArrayListExpression {
904 span: e.span(),
905 extras,
906 items,
907 ty,
908 })
909 })
910 .labelled("array")
911 .boxed();
912
913 let block_expression = block
914 .clone()
915 .map(Expression::Block)
916 .labelled("block expression")
917 .boxed();
918
919 if_inner.define(
920 just(Token::KeywordIf)
921 .ignore_then(expression_parser.clone())
922 .then(block.clone())
923 .then(
924 just(Token::KeywordElse)
925 .ignore_then(if_inner.clone())
926 .map(Box::new)
927 .or_not(),
928 )
929 .then(just(Token::KeywordElse).ignore_then(block.clone()).or_not())
930 .with_extras()
931 .map_with(
932 |((((condition, body), next_if), else_body), extras), e| If {
933 span: e.span(),
934 extras,
935 condition: Box::new(condition),
936 body,
937 next_if,
938 else_body,
939 },
940 )
941 .boxed(),
942 );
943 let if_expression = if_inner
944 .map(Expression::If)
945 .labelled("if expression")
946 .boxed();
947
948 let qualified_name_expr = identifier_parser
949 .clone()
950 .map_with(|ident, e| QualifiedName {
951 span: e.span(),
952 parts: vec![ident],
953 extras: ItemExtras::default(),
954 })
955 .foldl_with(
956 just(Token::SigilDoubleColon)
957 .ignore_then(identifier_parser.clone())
958 .repeated(),
959 |mut acc, part, _| {
960 acc.span.end = part.span.end;
961 acc.parts.push(part);
962 acc
963 },
964 )
965 .with_extras()
966 .map(|(mut name, extras)| {
967 name.extras = extras;
968 name
969 })
970 .map(Expression::QualifiedName)
971 .boxed();
972
973 let call = call_inner
974 .clone()
975 .map(Expression::Call)
976 .labelled("method call");
977
978 let base = literal
979 .or(string_format)
980 .or(call)
981 .or(qualified_name_expr)
982 .or(marker)
983 .or(bracketed)
984 .or(tuple)
985 .or(array_range)
986 .or(array_list)
987 .or(block_expression)
988 .or(if_expression)
989 .boxed();
990
991 let access_attribute = just(Token::SigilHash)
992 .ignore_then(identifier_parser.clone())
993 .map(Element::Attribute)
994 .labelled("attribute access")
995 .boxed();
996
997 let access_tuple = just(Token::SigilDot)
998 .ignore_then(identifier_parser.clone())
999 .map(Element::Tuple)
1000 .labelled("tuple access")
1001 .boxed();
1002
1003 let access_method = just(Token::SigilDot)
1004 .ignore_then(call_inner)
1005 .map(Element::Method)
1006 .labelled("method call")
1007 .boxed();
1008
1009 let access_array = expression_parser
1010 .clone()
1011 .delimited_by(
1012 just(Token::SigilOpenSquareBracket),
1013 just(Token::SigilCloseSquareBracket),
1014 )
1015 .map(Box::new)
1016 .map(Element::ArrayElement)
1017 .labelled("array access")
1018 .boxed();
1019
1020 let access_item = access_attribute
1021 .or(access_method)
1022 .or(access_tuple)
1023 .or(access_array)
1024 .boxed();
1025
1026 let element_access = base
1027 .clone()
1028 .foldl_with(access_item.repeated(), |value, element, e| {
1029 Expression::ElementAccess(ElementAccess {
1030 span: e.span(),
1031 value: value.into(),
1032 element,
1033 })
1034 })
1035 .labelled("element access")
1036 .boxed();
1037
1038 let unary_expression = unary_operator_parser
1039 .then(element_access.clone())
1040 .with_extras()
1041 .map_with(|((op, rhs), extras), e| UnaryOperation {
1042 span: e.span(),
1043 extras,
1044 operation: op,
1045 rhs: rhs.into(),
1046 })
1047 .map(simplify_unary_op)
1048 .boxed();
1049
1050 let binary_param = element_access.or(unary_expression.clone());
1051
1052 let near = binop(binary_param, &[Token::OperatorNear]);
1053 let xor = binop(near, &[Token::OperatorPowerXor, Token::OperatorXor]);
1054 let union_intersect = binop(xor, &[Token::OperatorUnion, Token::OperatorIntersect]);
1055 let mul_div = binop(
1056 union_intersect,
1057 &[Token::OperatorMultiply, Token::OperatorDivide],
1058 );
1059 let add_sub = binop(mul_div, &[Token::OperatorAdd, Token::OperatorSubtract]);
1060 let less_greater_eq = binop(
1061 add_sub,
1062 &[Token::OperatorLessEqual, Token::OperatorGreaterEqual],
1063 );
1064 let less_greater = binop(
1065 less_greater_eq,
1066 &[Token::OperatorLessThan, Token::OperatorGreaterThan],
1067 );
1068 let eq_neq = binop(
1069 less_greater,
1070 &[Token::OperatorEqual, Token::OperatorNotEqual],
1071 );
1072 let or_and = binop(eq_neq, &[Token::OperatorOr, Token::OperatorAnd]);
1073
1074 or_and.labelled("expression").boxed()
1075 });
1076
1077 statement_list_parser.map_with(move |statements, ex| SourceFile {
1078 span: ex.span(),
1079 statements,
1080 })
1081}