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