Actually just three programming languages in a trenchcoat
at string-repr-callable 783 lines 32 kB view raw
1use super::*; 2use crate::{Parser, Spanned, token_pattern::TokenPattern}; 3use become_expression::BecomeExpression; 4use trilogy_scanner::TokenType::{self, *}; 5 6/// The many kinds of expressions in a Trilogy program. 7#[derive(Clone, Debug, Spanned, PrettyPrintSExpr)] 8pub enum Expression { 9 Number(Box<NumberLiteral>), 10 Character(Box<CharacterLiteral>), 11 String(Box<StringLiteral>), 12 Bits(Box<BitsLiteral>), 13 Boolean(Box<BooleanLiteral>), 14 Unit(Box<UnitLiteral>), 15 Atom(Box<AtomLiteral>), 16 Struct(Box<StructLiteral>), 17 Array(Box<ArrayLiteral>), 18 Set(Box<SetLiteral>), 19 Record(Box<RecordLiteral>), 20 ArrayComprehension(Box<ArrayComprehension>), 21 SetComprehension(Box<SetComprehension>), 22 RecordComprehension(Box<RecordComprehension>), 23 Reference(Box<super::Identifier>), 24 Keyword(Box<KeywordReference>), 25 Application(Box<Application>), 26 Call(Box<CallExpression>), 27 Binary(Box<BinaryOperation>), 28 Unary(Box<UnaryOperation>), 29 Let(Box<LetExpression>), 30 IfElse(Box<IfElseExpression>), 31 Match(Box<MatchExpression>), 32 Is(Box<IsExpression>), 33 End(Box<EndExpression>), 34 Exit(Box<ExitExpression>), 35 Resume(Box<ResumeExpression>), 36 Become(Box<BecomeExpression>), 37 Cancel(Box<CancelExpression>), 38 Return(Box<ReturnExpression>), 39 Break(Box<BreakExpression>), 40 Continue(Box<ContinueExpression>), 41 Fn(Box<FnExpression>), 42 Do(Box<DoExpression>), 43 Qy(Box<QyExpression>), 44 Template(Box<Template>), 45 Handled(Box<HandledExpression>), 46 Parenthesized(Box<ParenthesizedExpression>), 47 ModuleAccess(Box<ModuleAccess>), 48} 49 50#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug)] 51pub(crate) enum Precedence { 52 None, 53 Sequence, 54 Continuation, 55 Or, 56 And, 57 Equality, 58 Comparison, 59 Pipe, 60 RPipe, 61 Cons, 62 Glue, 63 BitwiseOr, 64 BitwiseXor, 65 BitwiseShift, 66 BitwiseAnd, 67 Term, 68 Factor, 69 Exponent, 70 RCompose, 71 Compose, 72 Path, 73 Application, 74 Unary, 75 Call, 76 Access, 77} 78 79enum ExpressionResult { 80 Continue(Expression), 81 Done(Expression), 82 Pattern(Pattern), 83} 84 85impl Expression { 86 pub(crate) const PREFIX: [TokenType; 33] = [ 87 Numeric, 88 String, 89 Bits, 90 KwTrue, 91 KwFalse, 92 Atom, 93 Character, 94 KwUnit, 95 OBrack, 96 OBrackPipe, 97 OBracePipe, 98 OpBang, 99 OpTilde, 100 KwYield, 101 KwIf, 102 KwIs, 103 KwMatch, 104 KwEnd, 105 KwExit, 106 KwReturn, 107 KwResume, 108 KwBreak, 109 KwContinue, 110 KwCancel, 111 KwLet, 112 Identifier, 113 KwWith, 114 KwFn, 115 KwDo, 116 KwQy, 117 DollarString, 118 TemplateStart, 119 OParen, 120 ]; 121 122 fn binary(parser: &mut Parser, lhs: Expression) -> SyntaxResult<ExpressionResult> { 123 let binary = BinaryOperation::parse(parser, lhs)?; 124 match binary { 125 Ok(binary) => Ok(ExpressionResult::Continue(Self::Binary(Box::new(binary)))), 126 Err(pattern) => Ok(ExpressionResult::Pattern(pattern)), 127 } 128 } 129 130 fn parse_follow( 131 parser: &mut Parser, 132 precedence: Precedence, 133 lhs: Expression, 134 no_seq: bool, 135 ) -> SyntaxResult<ExpressionResult> { 136 // A bit of strangeness here because `peek()` takes a mutable reference, 137 // so we can't use the fields afterwards... but we need their value after 138 // and I'd really rather not clone every token of every expression, so 139 // instead we peek first, then do a force peek after (to skip an extra chomp). 140 parser.peek(); 141 let is_spaced = parser.is_spaced; 142 let is_line_start = parser.is_line_start; 143 let token = parser.force_peek(); 144 145 use ExpressionResult::{Continue, Done}; 146 147 match token.token_type { 148 OpDot if precedence < Precedence::Access => Self::binary(parser, lhs), 149 OpAmpAmp if precedence < Precedence::And => Self::binary(parser, lhs), 150 OpPipePipe if precedence < Precedence::Or => Self::binary(parser, lhs), 151 OpPlus | OpMinus if precedence < Precedence::Term => Self::binary(parser, lhs), 152 OpStar | OpSlash | OpPercent | OpSlashSlash if precedence < Precedence::Factor => { 153 Self::binary(parser, lhs) 154 } 155 OpStarStar if precedence <= Precedence::Exponent => Self::binary(parser, lhs), 156 OpLt | OpGt | OpLtEq | OpGtEq if precedence == Precedence::Comparison => { 157 let expr = Self::binary(parser, lhs); 158 if let Ok(Continue(expr)) = &expr { 159 parser.error(SyntaxError::new( 160 expr.span(), 161 "comparison operators cannot be chained, use parentheses to disambiguate", 162 )); 163 } 164 expr 165 } 166 OpLt | OpGt | OpLtEq | OpGtEq if precedence < Precedence::Comparison => { 167 Self::binary(parser, lhs) 168 } 169 OpEqEq | OpEqEqEq if precedence == Precedence::Equality => { 170 let expr = Self::binary(parser, lhs); 171 if let Ok(Continue(expr)) = &expr { 172 parser.error(SyntaxError::new( 173 expr.span(), 174 "equality operators cannot be chained, use parentheses to disambiguate", 175 )); 176 } 177 expr 178 } 179 OpBangEq | OpBangEqEq | OpEqEq | OpEqEqEq if precedence < Precedence::Equality => { 180 Self::binary(parser, lhs) 181 } 182 OpAmp if precedence < Precedence::BitwiseAnd => Self::binary(parser, lhs), 183 OpPipe if precedence < Precedence::BitwiseOr => Self::binary(parser, lhs), 184 OpCaret if precedence < Precedence::BitwiseXor => Self::binary(parser, lhs), 185 OpShr | OpShl | OpShrEx | OpShlEx | OpShrCon | OpShlCon 186 if precedence < Precedence::BitwiseShift => 187 { 188 Self::binary(parser, lhs) 189 } 190 OpColonColon if precedence < Precedence::Path => Ok(Continue(Self::ModuleAccess( 191 Box::new(ModuleAccess::parse(parser, lhs)?), 192 ))), 193 OpColon if precedence <= Precedence::Cons => Self::binary(parser, lhs), 194 OpLtLt if precedence < Precedence::Compose => Self::binary(parser, lhs), 195 OpGtGt if precedence < Precedence::RCompose => Self::binary(parser, lhs), 196 OpPipeGt if precedence < Precedence::Pipe => Self::binary(parser, lhs), 197 OpLtPipe if precedence < Precedence::RPipe => Self::binary(parser, lhs), 198 OpGlue if precedence < Precedence::Glue => Self::binary(parser, lhs), 199 OpBang if precedence < Precedence::Call && !is_spaced => Ok(Continue(Self::Call( 200 Box::new(CallExpression::parse(parser, lhs)?), 201 ))), 202 OpSemi if precedence <= Precedence::Sequence && !no_seq => Self::binary(parser, lhs), 203 204 // NOTE: despite and/or being allowed in patterns, we can't accept them here because 205 // they are also allowed in queries, in which case an expression was never an option, 206 // unless that expression was the start of a lookup, in which case the and/or is not 207 // permitted, so... if we're parsing as maybe expression or pattern, we aren't 208 // expecting and/or... 209 KwAnd | KwOr => Ok(Done(lhs)), 210 // Unary operators and keywords are not permitted here. They must be parenthesized 211 // to be considered an argument to an application. It messes with handler parsing 212 // otherwise, while also being confusing in terms of precedence rules. 213 KwYield | KwResume | KwCancel | KwReturn | KwContinue | KwBreak | KwBecome => { 214 Ok(Done(lhs)) 215 } 216 217 // A function application never spans across two lines. Furthermore, 218 // the application requires a space, even when the parse would be 219 // otherwise unambiguous. 220 // 221 // Sadly, the list of things that can follow, for an application, is 222 // anything prefix (except unary operators) so this becomes a very long list. 223 _ if Expression::PREFIX.matches(token) 224 && precedence < Precedence::Application 225 && !is_line_start 226 && is_spaced => 227 { 228 Ok(Continue(Self::Application(Box::new(Application::parse( 229 parser, lhs, 230 )?)))) 231 } 232 // If nothing matched, it must be the end of the expression 233 _ => Ok(Done(lhs)), 234 } 235 } 236 237 fn parse_prefix(parser: &mut Parser) -> SyntaxResult<Result<Self, Pattern>> { 238 let token = parser.peek(); 239 match token.token_type { 240 Numeric => Ok(Ok(Self::Number(Box::new(NumberLiteral::parse(parser)?)))), 241 String => Ok(Ok(Self::String(Box::new(StringLiteral::parse(parser)?)))), 242 Bits => Ok(Ok(Self::Bits(Box::new(BitsLiteral::parse(parser)?)))), 243 KwTrue | KwFalse => Ok(Ok(Self::Boolean(Box::new(BooleanLiteral::parse(parser)?)))), 244 Atom => { 245 let atom = AtomLiteral::parse(parser)?; 246 if parser.check(OParen).is_ok() { 247 let result = StructLiteral::parse(parser, atom)?; 248 match result { 249 Ok(expr) => Ok(Ok(Self::Struct(Box::new(expr)))), 250 Err(patt) => Ok(Err(Pattern::Struct(Box::new(patt)))), 251 } 252 } else { 253 Ok(Ok(Self::Atom(Box::new(atom)))) 254 } 255 } 256 Character => Ok(Ok(Self::Character(Box::new(CharacterLiteral::parse( 257 parser, 258 )?)))), 259 KwUnit => Ok(Ok(Self::Unit(Box::new(UnitLiteral::parse(parser)?)))), 260 OBrack => { 261 let start = parser.expect(OBrack).unwrap(); 262 if let Ok(end) = parser.expect(CBrack) { 263 return Ok(Ok(Self::Array(Box::new(ArrayLiteral::new_empty( 264 start, end, 265 ))))); 266 } 267 match ArrayElement::parse(parser)? { 268 Ok(ArrayElement::Element(expression)) if parser.check(KwFor).is_ok() => { 269 Ok(Ok(Self::ArrayComprehension(Box::new( 270 ArrayComprehension::parse_rest(parser, start, expression)?, 271 )))) 272 } 273 Ok(element) => match ArrayLiteral::parse_rest(parser, start, element)? { 274 Ok(expr) => Ok(Ok(Self::Array(Box::new(expr)))), 275 Err(patt) => Ok(Err(Pattern::Array(Box::new(patt)))), 276 }, 277 Err(next) => Ok(Err(Pattern::Array(Box::new( 278 ArrayPattern::parse_from_expression( 279 parser, 280 start, 281 Punctuated::new(), 282 next, 283 )?, 284 )))), 285 } 286 } 287 OBrackPipe => { 288 let start = parser.expect(OBrackPipe).unwrap(); 289 if let Ok(end) = parser.expect(CBrackPipe) { 290 return Ok(Ok(Self::Set(Box::new(SetLiteral::new_empty(start, end))))); 291 } 292 match SetElement::parse(parser)? { 293 Ok(SetElement::Element(expression)) if parser.expect(KwFor).is_ok() => { 294 Ok(Ok(Self::SetComprehension(Box::new( 295 SetComprehension::parse_rest(parser, start, expression)?, 296 )))) 297 } 298 Ok(element) => { 299 let result = SetLiteral::parse_rest(parser, start, element)?; 300 match result { 301 Ok(expr) => Ok(Ok(Self::Set(Box::new(expr)))), 302 Err(patt) => Ok(Err(Pattern::Set(Box::new(patt)))), 303 } 304 } 305 Err(next) => Ok(Err(Pattern::Set(Box::new( 306 SetPattern::parse_from_expression(parser, start, vec![], next)?, 307 )))), 308 } 309 } 310 OBracePipe => { 311 let start = parser.expect(OBracePipe).unwrap(); 312 if let Ok(end) = parser.expect(CBracePipe) { 313 return Ok(Ok(Self::Record(Box::new(RecordLiteral::new_empty( 314 start, end, 315 ))))); 316 } 317 match RecordElement::parse(parser)? { 318 Ok(RecordElement::Element(key, value)) if parser.expect(KwFor).is_ok() => { 319 Ok(Ok(Self::RecordComprehension(Box::new( 320 RecordComprehension::parse_rest(parser, start, key, value)?, 321 )))) 322 } 323 Ok(element) => { 324 let result = RecordLiteral::parse_rest(parser, start, element)?; 325 match result { 326 Ok(literal) => Ok(Ok(Self::Record(Box::new(literal)))), 327 Err(pattern) => Ok(Err(Pattern::Record(Box::new(pattern)))), 328 } 329 } 330 Err(next) => Ok(Err(Pattern::Record(Box::new( 331 RecordPattern::parse_from_expression(parser, start, vec![], next)?, 332 )))), 333 } 334 } 335 OpBang | OpMinus | OpTilde | KwYield | KwTypeof => match UnaryOperation::parse(parser)? 336 { 337 Ok(expr) => Ok(Ok(Self::Unary(Box::new(expr)))), 338 Err(patt) => Ok(Err(patt)), 339 }, 340 KwIf => { 341 let expr = IfElseExpression::parse(parser)?; 342 if !expr.is_strict_expression() { 343 parser.error(ErrorKind::IfExpressionRestriction.at(expr.span())); 344 } 345 Ok(Ok(Self::IfElse(Box::new(expr)))) 346 } 347 KwMatch => Ok(Ok(Self::Match(Box::new( 348 MatchExpression::parse(parser)?.strict_expression()?, 349 )))), 350 KwEnd => Ok(Ok(Self::End(Box::new(EndExpression::parse(parser)?)))), 351 KwExit => Ok(Ok(Self::Exit(Box::new(ExitExpression::parse(parser)?)))), 352 KwReturn => Ok(Ok(Self::Return(Box::new(ReturnExpression::parse(parser)?)))), 353 KwResume => Ok(Ok(Self::Resume(Box::new(ResumeExpression::parse(parser)?)))), 354 KwBecome => Ok(Ok(Self::Become(Box::new(BecomeExpression::parse(parser)?)))), 355 KwBreak => Ok(Ok(Self::Break(Box::new(BreakExpression::parse(parser)?)))), 356 KwContinue => Ok(Ok(Self::Continue(Box::new(ContinueExpression::parse( 357 parser, 358 )?)))), 359 KwCancel => Ok(Ok(Self::Cancel(Box::new(CancelExpression::parse(parser)?)))), 360 KwLet => Ok(Ok(Self::Let(Box::new(LetExpression::parse(parser)?)))), 361 Identifier => Ok(Ok(Self::Reference(Box::new(super::Identifier::parse( 362 parser, 363 )?)))), 364 KwWith => Ok(Ok(Self::Handled(Box::new(HandledExpression::parse( 365 parser, 366 )?)))), 367 KwFn => Ok(Ok(Self::Fn(Box::new(FnExpression::parse(parser)?)))), 368 KwDo => Ok(Ok(Self::Do(Box::new(DoExpression::parse(parser)?)))), 369 KwQy => Ok(Ok(Self::Qy(Box::new(QyExpression::parse(parser)?)))), 370 DollarString | TemplateStart => { 371 Ok(Ok(Self::Template(Box::new(Template::parse(parser)?)))) 372 } 373 OParen => match KeywordReference::try_parse(parser) { 374 Some(keyword) => Ok(Ok(Self::Keyword(Box::new(keyword)))), 375 None => match ParenthesizedExpression::parse(parser)? { 376 Ok(expression) => Ok(Ok(Self::Parenthesized(Box::new(expression)))), 377 Err(pattern) => Ok(Err(Pattern::Parenthesized(Box::new(pattern)))), 378 }, 379 }, 380 KwIs => Ok(Ok(Self::Is(Box::new(IsExpression::parse(parser)?)))), 381 KwMut | Discard | OpCaret => Ok(Err(Pattern::parse(parser)?)), 382 383 // Invalid stuff, but we can do better error messages by handling some specifically 384 KwNot => { 385 let error = ErrorKind::KwNotInExpression.at(token.span); 386 parser.error(error.clone()); 387 Err(error) 388 } 389 _ => { 390 let error = SyntaxError::new( 391 token.span, 392 format!("unexpected token {:?} in expression", token.token_type), 393 ); 394 parser.error(error.clone()); 395 Err(error) 396 } 397 } 398 } 399 400 fn parse_suffix( 401 parser: &mut Parser, 402 precedence: Precedence, 403 no_seq: bool, 404 mut expr: Expression, 405 ) -> SyntaxResult<Result<Self, Pattern>> { 406 loop { 407 match Self::parse_follow(parser, precedence, expr, no_seq)? { 408 ExpressionResult::Continue(updated) => expr = updated, 409 ExpressionResult::Done(expr) => return Ok(Ok(expr)), 410 ExpressionResult::Pattern(patt) => return Ok(Err(patt)), 411 } 412 } 413 } 414 415 fn parse_precedence_inner( 416 parser: &mut Parser, 417 precedence: Precedence, 418 no_seq: bool, 419 ) -> SyntaxResult<Result<Self, Pattern>> { 420 match Self::parse_prefix(parser)? { 421 Ok(expr) => Self::parse_suffix(parser, precedence, no_seq, expr), 422 Err(patt) => Ok(Err(Pattern::parse_suffix( 423 parser, 424 pattern::Precedence::None, 425 patt, 426 )?)), 427 } 428 } 429 430 pub(crate) fn parse_or_pattern_precedence( 431 parser: &mut Parser, 432 precedence: Precedence, 433 ) -> SyntaxResult<Result<Self, Pattern>> { 434 Self::parse_precedence_inner(parser, precedence, false) 435 } 436 437 pub(crate) fn parse_precedence( 438 parser: &mut Parser, 439 precedence: Precedence, 440 ) -> SyntaxResult<Self> { 441 Self::parse_or_pattern_precedence(parser, precedence)?.map_err(|patt| { 442 SyntaxError::new( 443 patt.span(), 444 "expected an expression in parameter list, but found a pattern", 445 ) 446 }) 447 } 448 449 pub(crate) fn parse_parameter_list(parser: &mut Parser) -> SyntaxResult<Result<Self, Pattern>> { 450 Self::parse_precedence_inner(parser, Precedence::None, true) 451 } 452 453 pub(crate) fn parse_or_pattern(parser: &mut Parser) -> SyntaxResult<Result<Self, Pattern>> { 454 Self::parse_or_pattern_precedence(parser, Precedence::None) 455 } 456 457 pub(crate) fn parse(parser: &mut Parser) -> SyntaxResult<Self> { 458 Self::parse_precedence(parser, Precedence::None) 459 } 460 461 pub(crate) fn parse_no_seq(parser: &mut Parser) -> SyntaxResult<Self> { 462 Self::parse_precedence_inner(parser, Precedence::None, true)?.map_err(|patt| { 463 SyntaxError::new(patt.span(), "expected an expression but found a pattern") 464 }) 465 } 466 467 pub(crate) fn is_lvalue(&self) -> bool { 468 match self { 469 Self::Binary(op) if matches!(op.operator, BinaryOperator::Access(..)) => true, 470 _ => self.is_pattern(), 471 } 472 } 473 474 pub(crate) fn is_pattern(&self) -> bool { 475 match self { 476 Self::Reference(..) => true, 477 Self::Atom(..) => true, 478 Self::Number(..) => true, 479 Self::Boolean(..) => true, 480 Self::Unit(..) => true, 481 Self::Bits(..) => true, 482 Self::String(..) => true, 483 Self::Character(..) => true, 484 Self::Unary(op) if matches!(op.operator, UnaryOperator::Negate(..)) => { 485 op.operand.is_pattern() 486 } 487 Self::Binary(op) 488 if matches!( 489 op.operator, 490 BinaryOperator::Glue(..) | BinaryOperator::Cons(..) 491 ) => 492 { 493 op.lhs.is_pattern() && op.rhs.is_pattern() 494 } 495 Self::Struct(inner) => inner.value.is_pattern(), 496 Self::Array(array) => { 497 array.elements.iter().all(|element| match element { 498 ArrayElement::Element(element) => element.is_pattern(), 499 ArrayElement::Spread(_, element) => element.is_pattern(), 500 }) && array 501 .elements 502 .iter() 503 .filter(|element| matches!(element, ArrayElement::Spread(..))) 504 .count() 505 <= 1 506 } 507 Self::Set(set) => set.elements.iter().all(|element| match element { 508 SetElement::Element(element) => element.is_pattern(), 509 SetElement::Spread(_, spread) 510 if std::ptr::eq(element, set.elements.last().unwrap()) => 511 { 512 spread.is_pattern() 513 } 514 _ => false, 515 }), 516 Self::Record(record) => record.elements.iter().all(|element| match element { 517 RecordElement::Element(key, value) => key.is_pattern() && value.is_pattern(), 518 RecordElement::Spread(_, spread) 519 if std::ptr::eq(element, record.elements.last().unwrap()) => 520 { 521 spread.is_pattern() 522 } 523 _ => false, 524 }), 525 Self::Parenthesized(paren) => paren.expression.is_pattern(), 526 _ => false, 527 } 528 } 529} 530 531#[cfg(test)] 532mod test { 533 use super::*; 534 535 test_parse!(expr_prec_boolean: "!true && false || true && !false" => Expression::parse => " 536 (Expression::Binary 537 (BinaryOperation 538 (Expression::Binary (BinaryOperation (Expression::Unary _) (BinaryOperator::And _) _)) 539 (BinaryOperator::Or _) 540 (Expression::Binary (BinaryOperation _ (BinaryOperator::And _) (Expression::Unary _)))))"); 541 test_parse!(expr_prec_arithmetic: "- 1 / 2 + 3 ** e - 4 * 5" => Expression::parse => " 542 (Expression::Binary 543 (BinaryOperation 544 (Expression::Binary 545 (BinaryOperation 546 (Expression::Binary (BinaryOperation (Expression::Unary _) (BinaryOperator::Divide _) _)) 547 (BinaryOperator::Add _) 548 (Expression::Binary (BinaryOperation _ (BinaryOperator::Power _) _)))) 549 (BinaryOperator::Subtract _) 550 (Expression::Binary 551 (BinaryOperation 552 _ 553 (BinaryOperator::Multiply _) 554 _))))"); 555 test_parse!(expr_prec_factor: "1 / 2 % 3 // 4 * 5" => Expression::parse => " 556 (Expression::Binary 557 (BinaryOperation 558 (Expression::Binary 559 (BinaryOperation 560 (Expression::Binary 561 (BinaryOperation 562 (Expression::Binary 563 (BinaryOperation 564 _ 565 (BinaryOperator::Divide _) 566 _)) 567 (BinaryOperator::Remainder _) 568 _)) 569 (BinaryOperator::IntDivide _) 570 _)) 571 (BinaryOperator::Multiply _) 572 _))"); 573 test_parse!(expr_prec_bitwise: "~x & y <~ 4 | x ^ y ~> 3" => Expression::parse => " 574 (Expression::Binary 575 (BinaryOperation 576 (Expression::Binary 577 (BinaryOperation 578 (Expression::Binary (BinaryOperation (Expression::Unary _) (BinaryOperator::BitwiseAnd _) _)) 579 (BinaryOperator::LeftShift _) 580 _)) 581 (BinaryOperator::BitwiseOr _) 582 (Expression::Binary 583 (BinaryOperation 584 _ 585 (BinaryOperator::BitwiseXor _) 586 (Expression::Binary 587 (BinaryOperation 588 _ 589 (BinaryOperator::RightShift _) 590 _))))))"); 591 test_parse!(expr_prec_app_pipe: "f x |> map (fn y. 2 * y) |> print" => Expression::parse => " 592 (Expression::Binary 593 (BinaryOperation 594 (Expression::Binary 595 (BinaryOperation 596 (Expression::Application _) 597 (BinaryOperator::Pipe _) 598 (Expression::Application _))) 599 (BinaryOperator::Pipe _) 600 (Expression::Reference _)))"); 601 test_parse!(expr_prec_pipe_rpipe: "x |> f <| g <| y |> h" => Expression::parse => " 602 (Expression::Binary 603 (BinaryOperation 604 (Expression::Binary 605 (BinaryOperation 606 (Expression::Reference _) 607 (BinaryOperator::Pipe _) 608 (Expression::Binary 609 (BinaryOperation 610 (Expression::Binary 611 (BinaryOperation 612 (Expression::Reference _) 613 (BinaryOperator::RPipe _) 614 (Expression::Reference _))) 615 (BinaryOperator::RPipe _) 616 (Expression::Reference _))))) 617 (BinaryOperator::Pipe _) 618 (Expression::Reference _)))"); 619 test_parse!(expr_prec_compose_rcompose: "x >> f << g << y >> h" => Expression::parse => " 620 (Expression::Binary 621 (BinaryOperation 622 (Expression::Binary 623 (BinaryOperation 624 (Expression::Reference _) 625 (BinaryOperator::RCompose _) 626 (Expression::Binary 627 (BinaryOperation 628 (Expression::Binary 629 (BinaryOperation 630 (Expression::Reference _) 631 (BinaryOperator::Compose _) 632 (Expression::Reference _))) 633 (BinaryOperator::Compose _) 634 (Expression::Reference _))))) 635 (BinaryOperator::RCompose _) 636 (Expression::Reference _)))"); 637 test_parse!(expr_prec_application: "x - f y + f y <| -z" => Expression::parse => " 638 (Expression::Binary 639 (BinaryOperation 640 (Expression::Binary 641 (BinaryOperation 642 (Expression::Binary 643 (BinaryOperation 644 (Expression::Reference _) 645 (BinaryOperator::Subtract _) 646 (Expression::Application _))) 647 (BinaryOperator::Add _) 648 (Expression::Application _))) 649 (BinaryOperator::RPipe _) 650 (Expression::Unary _)))"); 651 test_parse!(expr_prec_if_else: "if true then 5 + 6 else 7 + 8" => Expression::parse => " 652 (Expression::IfElse 653 (IfElseExpression 654 _ 655 (Expression::Boolean _) 656 (IfBody::Then _ _) 657 (ElseClause _ _)))"); 658 659 test_parse_error!(expr_eq_without_parens: "x == y == z" => Expression::parse => "equality operators cannot be chained, use parentheses to disambiguate"); 660 test_parse_error!(expr_cmp_without_parens: "x <= y <= z" => Expression::parse => "comparison operators cannot be chained, use parentheses to disambiguate"); 661 test_parse!(expr_prec_cmp_eq: "x < y == y > z" => Expression::parse => " 662 (Expression::Binary 663 (BinaryOperation 664 (Expression::Binary _) 665 (BinaryOperator::StructuralEquality _) 666 (Expression::Binary _)))"); 667 668 test_parse_error!(expr_multiline_application: "f\nx" => Expression::parse); 669 test_parse_error!(expr_application_no_space: "f(x)" => Expression::parse); 670 test_parse!(expr_multiline_operators: "f\n<| x" => Expression::parse => " 671 (Expression::Binary 672 (BinaryOperation 673 (Expression::Reference _) 674 (BinaryOperator::RPipe _) 675 (Expression::Reference _)))"); 676 677 test_parse!(expr_is: "true && is check(y) and also(z) && false" => Expression::parse => " 678 (Expression::Binary 679 (BinaryOperation 680 (Expression::Binary 681 (BinaryOperation 682 (Expression::Boolean _) 683 (BinaryOperator::And _) 684 (Expression::Is _))) 685 (BinaryOperator::And _) 686 (Expression::Boolean _)))"); 687 test_parse!(expr_is_prec: "false || is x = y && z" => Expression::parse => " 688 (Expression::Binary 689 (BinaryOperation 690 (Expression::Boolean _) 691 (BinaryOperator::Or _) 692 (Expression::Is _)))"); 693 694 test_parse!(expr_prec_glue_cons: "\"hello\" : \"hello\" <> \"world\" : 3 + 3 : \"world\"" => Expression::parse => " 695 (Expression::Binary 696 (BinaryOperation 697 (Expression::String _) 698 (BinaryOperator::Cons _) 699 (Expression::Binary 700 (BinaryOperation 701 (Expression::Binary 702 (BinaryOperation 703 (Expression::String _) 704 (BinaryOperator::Glue _) 705 (Expression::String _))) 706 (BinaryOperator::Cons _) 707 (Expression::Binary 708 (BinaryOperation 709 (Expression::Binary 710 (BinaryOperation 711 (Expression::Number _) 712 (BinaryOperator::Add _) 713 (Expression::Number _))) 714 (BinaryOperator::Cons _) 715 (Expression::String _)))))))"); 716 717 test_parse!(expr_prec_call: "a + b!() + c!()" => Expression::parse => " 718 (Expression::Binary 719 (BinaryOperation 720 (Expression::Binary 721 (BinaryOperation 722 (Expression::Reference _) 723 (BinaryOperator::Add _) 724 (Expression::Call _))) 725 (BinaryOperator::Add _) 726 (Expression::Call _)))"); 727 728 test_parse!(expr_prec_access: "a.1!() + b.'hello 3" => Expression::parse => " 729 (Expression::Binary 730 (BinaryOperation 731 (Expression::Call 732 (CallExpression 733 (Expression::Binary 734 (BinaryOperation 735 (Expression::Reference _) 736 (BinaryOperator::Access _) 737 (Expression::Number _))) 738 _ _ 739 [] 740 _)) 741 (BinaryOperator::Add _) 742 (Expression::Application 743 (Application 744 (Expression::Binary 745 (BinaryOperation 746 (Expression::Reference _) 747 (BinaryOperator::Access _) 748 (Expression::Atom _))) 749 (Expression::Number _)))))"); 750 test_parse!(expr_let_seq: "b; let a = b, a; b" => Expression::parse => " 751 (Expression::Binary 752 (BinaryOperation 753 _ 754 (BinaryOperator::Sequence _) 755 (Expression::Binary 756 (BinaryOperation 757 (Expression::Let _) 758 (BinaryOperator::Sequence _) 759 _))))"); 760 test_parse!(expr_mod_access: "mod1::mod2::member" => Expression::parse => " 761 (Expression::ModuleAccess 762 (ModuleAccess 763 (Expression::ModuleAccess 764 (ModuleAccess 765 (Expression::Reference _) 766 _ 767 (Identifier))) 768 _ 769 (Identifier)))"); 770 test_parse!(expr_prec_paths: "a b::c d::e f" => Expression::parse => " 771 (Expression::Application 772 (Application 773 (Expression::ModuleAccess 774 (ModuleAccess 775 (Expression::Application 776 (Application 777 (Expression::ModuleAccess _) 778 (Expression::Reference _))) 779 _ 780 (Identifier))) 781 (Expression::Reference _))) 782 "); 783}