Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

gleam / compiler-core / src / parse.rs
170 kB 4657 lines
1// Gleam Parser 2// 3// Terminology: 4// Expression Unit: 5// Essentially a thing that goes between operators. 6// Int, Bool, function call, "{" expression-sequence "}", case x {}, ..etc 7// 8// Expression: 9// One or more Expression Units separated by an operator 10// 11// Binding: 12// (let|let assert|use) name (:TypeAnnotation)? = Expression 13// 14// Expression Sequence: 15// * One or more Expressions 16// * A Binding followed by at least one more Expression Sequences 17// 18// Naming Conventions: 19// parse_x 20// Parse a specific part of the grammar, not erroring if it cannot. 21// Generally returns `Result<Option<A>, ParseError>`, note the inner Option 22// 23// expect_x 24// Parse a generic or specific part of the grammar, erroring if it cannot. 25// Generally returns `Result<A, ParseError>`, note no inner Option 26// 27// maybe_x 28// Parse a generic part of the grammar. Returning `None` if it cannot. 29// Returns `Some(x)` and advances the token stream if it can. 30// 31// Operator Precedence Parsing: 32// Needs to take place in expressions and in clause guards. 33// It is accomplished using the Simple Precedence Parser algorithm. 34// See: https://en.wikipedia.org/wiki/Simple_precedence_parser 35// 36// It relies or the operator grammar being in the general form: 37// e ::= expr op expr | expr 38// Which just means that exprs and operators always alternate, starting with an expr 39// 40// The gist of the algorithm is: 41// Create 2 stacks, one to hold expressions, and one to hold un-reduced operators. 42// While consuming the input stream, if an expression is encountered add it to the top 43// of the expression stack. If an operator is encountered, compare its precedence to the 44// top of the operator stack and perform the appropriate action, which is either using an 45// operator to reduce 2 expressions on the top of the expression stack or put it on the top 46// of the operator stack. When the end of the input is reached, attempt to reduce all of the 47// expressions down to a single expression(or no expression) using the remaining operators 48// on the operator stack. If there are any operators left, or more than 1 expression left 49// this is a syntax error. But the implementation here shouldn't need to handle that case 50// as the outer parser ensures the correct structure. 51// 52pub mod error; 53pub mod extra; 54pub mod lexer; 55mod token; 56 57use crate::Warning; 58use crate::analyse::Inferred; 59use crate::ast::{ 60 Arg, ArgNames, Assert, AssignName, Assignment, AssignmentKind, BinOp, BitArrayOption, 61 BitArraySegment, BitArraySize, CAPTURE_VARIABLE, CallArg, Clause, ClauseGuard, Constant, 62 CustomType, Definition, Function, FunctionLiteralKind, HasLocation, Import, IntOperator, 63 Module, ModuleConstant, Pattern, Publicity, RecordBeingUpdated, RecordConstructor, 64 RecordConstructorArg, SrcSpan, Statement, TargetedDefinition, TodoKind, TypeAlias, TypeAst, 65 TypeAstConstructor, TypeAstFn, TypeAstHole, TypeAstTuple, TypeAstVar, UnqualifiedImport, 66 UntypedArg, UntypedClause, UntypedClauseGuard, UntypedConstant, UntypedDefinition, UntypedExpr, 67 UntypedModule, UntypedPattern, UntypedRecordUpdateArg, UntypedStatement, UntypedUseAssignment, 68 Use, UseAssignment, 69}; 70use crate::build::Target; 71use crate::error::wrap; 72use crate::exhaustiveness::CompiledCase; 73use crate::parse::extra::ModuleExtra; 74use crate::type_::Deprecation; 75use crate::type_::error::{VariableDeclaration, VariableOrigin, VariableSyntax}; 76use crate::type_::expression::{Implementations, Purity}; 77use crate::warning::{DeprecatedSyntaxWarning, WarningEmitter}; 78use camino::Utf8PathBuf; 79use ecow::EcoString; 80use error::{LexicalError, ParseError, ParseErrorType}; 81use lexer::{LexResult, Spanned}; 82use num_bigint::BigInt; 83use std::cmp::Ordering; 84use std::collections::VecDeque; 85use std::str::FromStr; 86pub use token::Token; 87use vec1::{Vec1, vec1}; 88 89#[cfg(test)] 90mod tests; 91 92#[derive(Debug)] 93pub struct Parsed { 94 pub module: UntypedModule, 95 pub extra: ModuleExtra, 96} 97 98/// We use this to keep track of the `@internal` annotation for top level 99/// definitions. Instead of using just a boolean we want to keep track of the 100/// source position of the annotation in case it is present. This way we can 101/// report a better error message highlighting the annotation in case it is 102/// used on a private definition (it doesn't make sense to mark something 103/// private as internal): 104/// 105/// ```txt 106/// @internal 107/// ^^^^^^^^^ we first get to the annotation 108/// fn wibble() {} 109/// ^^ and only later discover it's applied on a private definition 110/// so we have to keep track of the attribute's position to highlight it 111/// in the resulting error message. 112/// ``` 113#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] 114enum InternalAttribute { 115 #[default] 116 Missing, 117 Present(SrcSpan), 118} 119 120#[derive(Debug, Default)] 121struct Attributes { 122 target: Option<Target>, 123 deprecated: Deprecation, 124 external_erlang: Option<(EcoString, EcoString, SrcSpan)>, 125 external_javascript: Option<(EcoString, EcoString, SrcSpan)>, 126 internal: InternalAttribute, 127} 128 129impl Attributes { 130 fn has_function_only(&self) -> bool { 131 self.external_erlang.is_some() || self.external_javascript.is_some() 132 } 133 134 fn has_external_for(&self, target: Target) -> bool { 135 match target { 136 Target::Erlang => self.external_erlang.is_some(), 137 Target::JavaScript => self.external_javascript.is_some(), 138 } 139 } 140 141 fn set_external_for(&mut self, target: Target, ext: Option<(EcoString, EcoString, SrcSpan)>) { 142 match target { 143 Target::Erlang => self.external_erlang = ext, 144 Target::JavaScript => self.external_javascript = ext, 145 } 146 } 147} 148 149// 150// Public Interface 151// 152 153pub type SpannedString = (SrcSpan, EcoString); 154 155pub fn parse_module( 156 path: Utf8PathBuf, 157 src: &str, 158 warnings: &WarningEmitter, 159) -> Result<Parsed, ParseError> { 160 let lex = lexer::make_tokenizer(src); 161 let mut parser = Parser::new(lex); 162 let mut parsed = parser.parse_module()?; 163 parsed.extra = parser.extra; 164 165 let src = EcoString::from(src); 166 for warning in parser.warnings { 167 warnings.emit(Warning::DeprecatedSyntax { 168 path: path.clone(), 169 src: src.clone(), 170 warning, 171 }); 172 } 173 174 Ok(parsed) 175} 176 177// 178// Test Interface 179// 180#[cfg(test)] 181pub fn parse_statement_sequence(src: &str) -> Result<Vec1<UntypedStatement>, ParseError> { 182 let lex = lexer::make_tokenizer(src); 183 let mut parser = Parser::new(lex); 184 let expr = parser.parse_statement_seq(); 185 let expr = parser.ensure_no_errors_or_remaining_input(expr)?; 186 match expr { 187 Some((e, _)) => Ok(e), 188 _ => parse_error(ParseErrorType::ExpectedExpr, SrcSpan { start: 0, end: 0 }), 189 } 190} 191 192// 193// Test Interface 194// 195#[cfg(test)] 196pub fn parse_const_value(src: &str) -> Result<Constant<(), ()>, ParseError> { 197 let lex = lexer::make_tokenizer(src); 198 let mut parser = Parser::new(lex); 199 let expr = parser.parse_const_value(); 200 let expr = parser.ensure_no_errors_or_remaining_input(expr)?; 201 match expr { 202 Some(e) => Ok(e), 203 _ => parse_error(ParseErrorType::ExpectedExpr, SrcSpan { start: 0, end: 0 }), 204 } 205} 206 207// 208// Parser 209// 210#[derive(Debug)] 211pub struct Parser<T: Iterator<Item = LexResult>> { 212 tokens: T, 213 lex_errors: Vec<LexicalError>, 214 warnings: Vec<DeprecatedSyntaxWarning>, 215 tok0: Option<Spanned>, 216 tok1: Option<Spanned>, 217 extra: ModuleExtra, 218 doc_comments: VecDeque<(u32, EcoString)>, 219} 220impl<T> Parser<T> 221where 222 T: Iterator<Item = LexResult>, 223{ 224 pub fn new(input: T) -> Self { 225 let mut parser = Parser { 226 tokens: input, 227 lex_errors: vec![], 228 warnings: vec![], 229 tok0: None, 230 tok1: None, 231 extra: ModuleExtra::new(), 232 doc_comments: VecDeque::new(), 233 }; 234 parser.advance(); 235 parser.advance(); 236 parser 237 } 238 239 fn parse_module(&mut self) -> Result<Parsed, ParseError> { 240 let definitions = Parser::series_of(self, &Parser::parse_definition, None); 241 let definitions = self.ensure_no_errors_or_remaining_input(definitions)?; 242 let module = Module { 243 name: "".into(), 244 documentation: vec![], 245 type_info: (), 246 definitions, 247 names: Default::default(), 248 unused_definition_positions: Default::default(), 249 }; 250 Ok(Parsed { 251 module, 252 extra: Default::default(), 253 }) 254 } 255 256 // The way the parser is currently implemented, it cannot exit immediately while advancing 257 // the token stream upon seeing a LexError. That is to avoid having to put `?` all over the 258 // place and instead we collect LexErrors in `self.lex_errors` and attempt to continue parsing. 259 // Once parsing has returned we want to surface an error in the order: 260 // 1) LexError, 2) ParseError, 3) More Tokens Left 261 fn ensure_no_errors_or_remaining_input<A>( 262 &mut self, 263 parse_result: Result<A, ParseError>, 264 ) -> Result<A, ParseError> { 265 let parse_result = self.ensure_no_errors(parse_result)?; 266 if let Some((start, token, end)) = self.next_tok() { 267 // there are still more tokens 268 let expected = vec!["An import, const, type, or function.".into()]; 269 return parse_error( 270 ParseErrorType::UnexpectedToken { 271 token, 272 expected, 273 hint: None, 274 }, 275 SrcSpan { start, end }, 276 ); 277 } 278 // no errors 279 Ok(parse_result) 280 } 281 282 // The way the parser is currently implemented, it cannot exit immediately 283 // while advancing the token stream upon seeing a LexError. That is to avoid 284 // having to put `?` all over the place and instead we collect LexErrors in 285 // `self.lex_errors` and attempt to continue parsing. 286 // Once parsing has returned we want to surface an error in the order: 287 // 1) LexError, 2) ParseError 288 fn ensure_no_errors<A>( 289 &mut self, 290 parse_result: Result<A, ParseError>, 291 ) -> Result<A, ParseError> { 292 if let Some(error) = self.lex_errors.first() { 293 // Lex errors first 294 let location = error.location; 295 let error = *error; 296 parse_error(ParseErrorType::LexError { error }, location) 297 } else { 298 // Return any existing parse error 299 parse_result 300 } 301 } 302 303 fn parse_definition(&mut self) -> Result<Option<TargetedDefinition>, ParseError> { 304 let mut attributes = Attributes::default(); 305 let location = self.parse_attributes(&mut attributes)?; 306 307 let def = match (self.tok0.take(), self.tok1.as_ref()) { 308 // Imports 309 (Some((start, Token::Import, _)), _) => { 310 self.advance(); 311 self.parse_import(start) 312 } 313 // Module Constants 314 (Some((start, Token::Const, _)), _) => { 315 self.advance(); 316 self.parse_module_const(start, false, &attributes) 317 } 318 (Some((start, Token::Pub, _)), Some((_, Token::Const, _))) => { 319 self.advance(); 320 self.advance(); 321 self.parse_module_const(start, true, &attributes) 322 } 323 324 // Function 325 (Some((start, Token::Fn, _)), _) => { 326 self.advance(); 327 self.parse_function(start, false, false, &mut attributes) 328 } 329 (Some((start, Token::Pub, _)), Some((_, Token::Fn, _))) => { 330 self.advance(); 331 self.advance(); 332 self.parse_function(start, true, false, &mut attributes) 333 } 334 335 // Custom Types, and Type Aliases 336 (Some((start, Token::Type, _)), _) => { 337 self.advance(); 338 self.parse_custom_type(start, false, false, &mut attributes) 339 } 340 (Some((start, Token::Pub, _)), Some((_, Token::Opaque, _))) => { 341 self.advance(); 342 self.advance(); 343 let _ = self.expect_one(&Token::Type)?; 344 self.parse_custom_type(start, true, true, &mut attributes) 345 } 346 (Some((start, Token::Pub, _)), Some((_, Token::Type, _))) => { 347 self.advance(); 348 self.advance(); 349 self.parse_custom_type(start, true, false, &mut attributes) 350 } 351 (Some((start, Token::Opaque, _)), Some((_, Token::Type, _))) => { 352 // A private opaque type makes no sense! We still want to parse it 353 // and return an error later during the analysis phase. 354 self.advance(); 355 self.advance(); 356 self.parse_custom_type(start, false, true, &mut attributes) 357 } 358 359 (t0, _) => { 360 self.tok0 = t0; 361 Ok(None) 362 } 363 }?; 364 365 match (def, location) { 366 (Some(definition), _) if definition.is_function() => Ok(Some(TargetedDefinition { 367 definition, 368 target: attributes.target, 369 })), 370 371 (Some(definition), None) => Ok(Some(TargetedDefinition { 372 definition, 373 target: attributes.target, 374 })), 375 376 (_, Some(location)) if attributes.has_function_only() => { 377 parse_error(ParseErrorType::ExpectedFunctionDefinition, location) 378 } 379 380 (Some(definition), _) => Ok(Some(TargetedDefinition { 381 definition, 382 target: attributes.target, 383 })), 384 385 (_, Some(location)) => parse_error(ParseErrorType::ExpectedDefinition, location), 386 387 (None, None) => Ok(None), 388 } 389 } 390 391 // 392 // Parse Expressions 393 // 394 395 // examples: 396 // unit 397 // unit op unit 398 // unit op unit pipe unit(call) 399 // unit op unit pipe unit(call) pipe unit(call) 400 fn parse_expression(&mut self) -> Result<Option<UntypedExpr>, ParseError> { 401 self.parse_expression_inner(false) 402 } 403 404 fn parse_expression_inner( 405 &mut self, 406 is_let_binding: bool, 407 ) -> Result<Option<UntypedExpr>, ParseError> { 408 // uses the simple operator parser algorithm 409 let mut opstack = vec![]; 410 let mut estack = vec![]; 411 let mut last_op_start = 0; 412 let mut last_op_end = 0; 413 414 // This is used to keep track if we've just ran into a `|>` operator in 415 // order to properly parse an echo based on its position: if it is in a 416 // pipeline then it isn't expected to be followed by an expression. 417 // Otherwise, it's expected to be followed by an expression. 418 let mut expression_unit_context = ExpressionUnitContext::Other; 419 420 loop { 421 match self.parse_expression_unit(expression_unit_context)? { 422 Some(unit) => { 423 self.post_process_expression_unit(&unit, is_let_binding)?; 424 estack.push(unit) 425 } 426 _ if estack.is_empty() => return Ok(None), 427 _ => { 428 return parse_error( 429 ParseErrorType::OpNakedRight, 430 SrcSpan { 431 start: last_op_start, 432 end: last_op_end, 433 }, 434 ); 435 } 436 } 437 438 let Some((op_s, t, op_e)) = self.tok0.take() else { 439 break; 440 }; 441 442 let Some(p) = precedence(&t) else { 443 self.tok0 = Some((op_s, t, op_e)); 444 break; 445 }; 446 447 expression_unit_context = if t == Token::Pipe { 448 ExpressionUnitContext::FollowingPipe 449 } else { 450 ExpressionUnitContext::Other 451 }; 452 453 // Is Op 454 self.advance(); 455 last_op_start = op_s; 456 last_op_end = op_e; 457 let _ = handle_op( 458 Some(((op_s, t, op_e), p)), 459 &mut opstack, 460 &mut estack, 461 &do_reduce_expression, 462 ); 463 } 464 465 Ok(handle_op( 466 None, 467 &mut opstack, 468 &mut estack, 469 &do_reduce_expression, 470 )) 471 } 472 473 fn post_process_expression_unit( 474 &mut self, 475 unit: &UntypedExpr, 476 is_let_binding: bool, 477 ) -> Result<(), ParseError> { 478 // Produce better error message for `[x] = [1]` outside 479 // of `let` statement. 480 if !is_let_binding 481 && let UntypedExpr::List { .. } = unit 482 && let Some((start, Token::Equal, end)) = self.tok0 483 { 484 return parse_error(ParseErrorType::NoLetBinding, SrcSpan { start, end }); 485 } 486 Ok(()) 487 } 488 489 // examples: 490 // 1 491 // "one" 492 // True 493 // fn() { "hi" } 494 // unit().unit().unit() 495 // A(a.., label: tuple(1)) 496 // { expression_sequence } 497 fn parse_expression_unit( 498 &mut self, 499 context: ExpressionUnitContext, 500 ) -> Result<Option<UntypedExpr>, ParseError> { 501 let mut expr = match self.tok0.take() { 502 Some((start, Token::String { value }, end)) => { 503 self.advance(); 504 UntypedExpr::String { 505 location: SrcSpan { start, end }, 506 value, 507 } 508 } 509 Some((start, Token::Int { value, int_value }, end)) => { 510 self.advance(); 511 UntypedExpr::Int { 512 location: SrcSpan { start, end }, 513 value, 514 int_value, 515 } 516 } 517 518 Some((start, Token::Float { value }, end)) => { 519 self.advance(); 520 UntypedExpr::Float { 521 location: SrcSpan { start, end }, 522 value, 523 } 524 } 525 526 // var lower_name and UpName 527 Some((start, Token::Name { name } | Token::UpName { name }, end)) => { 528 self.advance(); 529 UntypedExpr::Var { 530 location: SrcSpan { start, end }, 531 name, 532 } 533 } 534 535 Some((start, Token::Todo, end)) => { 536 self.advance(); 537 let message = self.maybe_parse_as_message()?; 538 let end = message.as_ref().map_or(end, |m| m.location().end); 539 UntypedExpr::Todo { 540 location: SrcSpan { start, end }, 541 kind: TodoKind::Keyword, 542 message, 543 } 544 } 545 546 Some((start, Token::Panic, end)) => { 547 self.advance(); 548 let message = self.maybe_parse_as_message()?; 549 let end = message.as_ref().map_or(end, |m| m.location().end); 550 UntypedExpr::Panic { 551 location: SrcSpan { start, end }, 552 message, 553 } 554 } 555 556 Some((start, Token::Echo, echo_end)) => { 557 self.advance(); 558 if context == ExpressionUnitContext::FollowingPipe { 559 // If an echo is used as a step in a pipeline (`|> echo`) 560 // then it cannot be followed by an expression. 561 let message = self.maybe_parse_as_message()?; 562 let end = message.as_ref().map_or(echo_end, |m| m.location().end); 563 UntypedExpr::Echo { 564 location: SrcSpan { start, end }, 565 keyword_end: echo_end, 566 expression: None, 567 message, 568 } 569 } else { 570 // Otherwise it must be followed by an expression. 571 // However, you might have noticed we're not erroring if the 572 // expression is not there. Instead we move this error to 573 // the analysis phase so that a wrong usage of echo won't 574 // stop analysis from happening everywhere and be fault 575 // tolerant like everything else. 576 let expression = self.parse_expression()?; 577 let end = expression.as_ref().map_or(echo_end, |e| e.location().end); 578 579 let message = self.maybe_parse_as_message()?; 580 let end = message.as_ref().map_or(end, |m| m.location().end); 581 582 UntypedExpr::Echo { 583 location: SrcSpan { start, end }, 584 keyword_end: echo_end, 585 expression: expression.map(Box::new), 586 message, 587 } 588 } 589 } 590 591 Some((start, Token::Hash, _)) => { 592 self.advance(); 593 let _ = self.expect_one(&Token::LeftParen)?; 594 let elements = 595 Parser::series_of(self, &Parser::parse_expression, Some(&Token::Comma))?; 596 let (_, end) = 597 self.expect_one_following_series(&Token::RightParen, "an expression")?; 598 UntypedExpr::Tuple { 599 location: SrcSpan { start, end }, 600 elements, 601 } 602 } 603 604 // list 605 Some((start, Token::LeftSquare, _)) => { 606 self.advance(); 607 let (elements, elements_end_with_comma) = self.series_of_has_trailing_separator( 608 &Parser::parse_expression, 609 Some(&Token::Comma), 610 )?; 611 612 // Parse an optional tail 613 let mut tail = None; 614 let mut elements_after_tail = None; 615 let mut dot_dot_location = None; 616 617 if let Some((start, end)) = self.maybe_one(&Token::DotDot) { 618 dot_dot_location = Some((start, end)); 619 tail = self.parse_expression()?.map(Box::new); 620 if self.maybe_one(&Token::Comma).is_some() { 621 // See if there's a list of items after the tail, 622 // like `[..wibble, wobble, wabble]` 623 let elements = 624 self.series_of(&Parser::parse_expression, Some(&Token::Comma)); 625 match elements { 626 Err(_) => {} 627 Ok(elements) => { 628 elements_after_tail = Some(elements); 629 } 630 }; 631 }; 632 633 if tail.is_some() { 634 if !elements_end_with_comma { 635 self.warnings 636 .push(DeprecatedSyntaxWarning::DeprecatedListPrepend { 637 location: SrcSpan { start, end }, 638 }); 639 } 640 641 // Give a better error when there is two consecutive spreads 642 // like `[..wibble, ..wabble, woo]`. However, if there's other 643 // elements after the tail of the list 644 if let Some((second_start, second_end)) = self.maybe_one(&Token::DotDot) { 645 let _second_tail = self.parse_expression(); 646 647 if elements_after_tail.is_none() 648 || elements_after_tail 649 .as_ref() 650 .is_some_and(|vec| vec.is_empty()) 651 { 652 return parse_error( 653 ParseErrorType::ListSpreadWithAnotherSpread { 654 first_spread_location: SrcSpan { start, end }, 655 }, 656 SrcSpan { 657 start: second_start, 658 end: second_end, 659 }, 660 ); 661 } 662 } 663 } 664 } 665 666 let (_, end) = self.expect_one(&Token::RightSquare)?; 667 668 // Return errors for malformed lists 669 match dot_dot_location { 670 Some((start, end)) if tail.is_none() => { 671 return parse_error( 672 ParseErrorType::ListSpreadWithoutTail, 673 SrcSpan { start, end }, 674 ); 675 } 676 _ => {} 677 } 678 if tail.is_some() 679 && elements.is_empty() 680 && elements_after_tail.as_ref().is_none_or(|e| e.is_empty()) 681 { 682 return parse_error( 683 ParseErrorType::ListSpreadWithoutElements, 684 SrcSpan { start, end }, 685 ); 686 } 687 688 match elements_after_tail { 689 Some(elements) if !elements.is_empty() => { 690 let (start, end) = match (dot_dot_location, tail) { 691 (Some((start, _)), Some(tail)) => (start, tail.location().end), 692 (_, _) => (start, end), 693 }; 694 return parse_error( 695 ParseErrorType::ListSpreadFollowedByElements, 696 SrcSpan { start, end }, 697 ); 698 } 699 _ => {} 700 } 701 702 UntypedExpr::List { 703 location: SrcSpan { start, end }, 704 elements, 705 tail, 706 } 707 } 708 709 // BitArray 710 Some((start, Token::LtLt, _)) => { 711 self.advance(); 712 let segments = Parser::series_of( 713 self, 714 &|s| { 715 Parser::parse_bit_array_segment( 716 s, 717 &(|this| this.parse_expression_unit(ExpressionUnitContext::Other)), 718 &Parser::expect_expression, 719 &bit_array_expr_int, 720 ) 721 }, 722 Some(&Token::Comma), 723 )?; 724 let (_, end) = 725 self.expect_one_following_series(&Token::GtGt, "a bit array segment")?; 726 UntypedExpr::BitArray { 727 location: SrcSpan { start, end }, 728 segments, 729 } 730 } 731 Some((start, Token::Fn, _)) => { 732 self.advance(); 733 let mut attributes = Attributes::default(); 734 match self.parse_function(start, false, true, &mut attributes)? { 735 Some(Definition::Function(Function { 736 location, 737 arguments, 738 body, 739 return_annotation, 740 end_position, 741 .. 742 })) => UntypedExpr::Fn { 743 location: SrcSpan::new(location.start, end_position), 744 end_of_head_byte_index: location.end, 745 kind: FunctionLiteralKind::Anonymous { head: location }, 746 arguments, 747 body, 748 return_annotation, 749 }, 750 751 _ => { 752 // this isn't just none, it could also be Some(UntypedExpr::..) 753 return self.next_tok_unexpected(vec!["An opening parenthesis.".into()]); 754 } 755 } 756 } 757 758 // expression block "{" "}" 759 Some((start, Token::LeftBrace, _)) => { 760 self.advance(); 761 self.parse_block(start)? 762 } 763 764 // case 765 Some((start, Token::Case, case_e)) => { 766 self.advance(); 767 let subjects = 768 Parser::series_of(self, &Parser::parse_expression, Some(&Token::Comma))?; 769 if self.maybe_one(&Token::LeftBrace).is_some() { 770 let clauses = Parser::series_of(self, &Parser::parse_case_clause, None)?; 771 let (_, end) = 772 self.expect_one_following_series(&Token::RightBrace, "a case clause")?; 773 if subjects.is_empty() { 774 return parse_error( 775 ParseErrorType::ExpectedExpr, 776 SrcSpan { start, end: case_e }, 777 ); 778 } else { 779 UntypedExpr::Case { 780 location: SrcSpan { start, end }, 781 subjects, 782 clauses: Some(clauses), 783 } 784 } 785 } else { 786 UntypedExpr::Case { 787 location: SrcSpan::new( 788 start, 789 subjects 790 .last() 791 .map(|subject| subject.location().end) 792 .unwrap_or(case_e), 793 ), 794 subjects, 795 clauses: None, 796 } 797 } 798 } 799 800 // Helpful error if trying to write an if expression instead of a 801 // case. 802 Some((start, Token::If, end)) => { 803 return parse_error(ParseErrorType::IfExpression, SrcSpan { start, end }); 804 } 805 806 // Helpful error on possibly trying to group with "(". 807 Some((start, Token::LeftParen, _)) => { 808 return parse_error(ParseErrorType::ExprLparStart, SrcSpan { start, end: start }); 809 } 810 811 // Boolean negation 812 Some((start, Token::Bang, _end)) => { 813 self.advance(); 814 match self.parse_expression_unit(ExpressionUnitContext::Other)? { 815 Some(value) => UntypedExpr::NegateBool { 816 location: SrcSpan { 817 start, 818 end: value.location().end, 819 }, 820 value: Box::from(value), 821 }, 822 None => { 823 return parse_error( 824 ParseErrorType::ExpectedExpr, 825 SrcSpan { start, end: start }, 826 ); 827 } 828 } 829 } 830 831 // Int negation 832 Some((start, Token::Minus, _end)) => { 833 self.advance(); 834 match self.parse_expression_unit(ExpressionUnitContext::Other)? { 835 Some(value) => UntypedExpr::NegateInt { 836 location: SrcSpan { 837 start, 838 end: value.location().end, 839 }, 840 value: Box::from(value), 841 }, 842 None => { 843 return parse_error( 844 ParseErrorType::ExpectedExpr, 845 SrcSpan { start, end: start }, 846 ); 847 } 848 } 849 } 850 851 t0 => { 852 self.tok0 = t0; 853 return Ok(None); 854 } 855 }; 856 857 // field access and call can stack up 858 loop { 859 match self.maybe_one(&Token::Dot) { 860 Some((dot_start, _)) => { 861 let start = expr.location().start; 862 // field access 863 match self.tok0.take() { 864 // tuple access 865 Some(( 866 _, 867 Token::Int { 868 value, 869 int_value: _, 870 }, 871 end, 872 )) => { 873 self.advance(); 874 let v = value.replace("_", ""); 875 match u64::from_str(&v) { 876 Ok(index) => { 877 expr = UntypedExpr::TupleIndex { 878 location: SrcSpan { start, end }, 879 index, 880 tuple: Box::new(expr), 881 } 882 } 883 _ => { 884 return parse_error( 885 ParseErrorType::InvalidTupleAccess, 886 SrcSpan { start, end }, 887 ); 888 } 889 } 890 } 891 892 Some((label_start, Token::Name { name: label }, end)) => { 893 self.advance(); 894 expr = UntypedExpr::FieldAccess { 895 location: SrcSpan { start, end }, 896 label_location: SrcSpan { 897 start: label_start, 898 end, 899 }, 900 label, 901 container: Box::new(expr), 902 } 903 } 904 905 Some((label_start, Token::UpName { name: label }, end)) => { 906 self.advance(); 907 expr = UntypedExpr::FieldAccess { 908 location: SrcSpan { start, end }, 909 label_location: SrcSpan { 910 start: label_start, 911 end, 912 }, 913 label, 914 container: Box::new(expr), 915 } 916 } 917 918 t0 => { 919 // parse a field access with no label 920 self.tok0 = t0; 921 let end = dot_start + 1; 922 expr = UntypedExpr::FieldAccess { 923 location: SrcSpan { start, end }, 924 label_location: SrcSpan { 925 start: dot_start, 926 end, 927 }, 928 label: "".into(), 929 container: Box::new(expr), 930 }; 931 return Ok(Some(expr)); 932 } 933 } 934 } 935 _ => { 936 if self.maybe_one(&Token::LeftParen).is_some() { 937 let start = expr.location().start; 938 match self.maybe_one(&Token::DotDot) { 939 Some((dot_s, _)) => { 940 // Record update 941 let base = self.expect_expression()?; 942 let base_e = base.location().end; 943 let record = RecordBeingUpdated { 944 base: Box::new(base), 945 location: SrcSpan { 946 start: dot_s, 947 end: base_e, 948 }, 949 }; 950 let mut arguments = vec![]; 951 if self.maybe_one(&Token::Comma).is_some() { 952 arguments = Parser::series_of( 953 self, 954 &Parser::parse_record_update_arg, 955 Some(&Token::Comma), 956 )?; 957 } 958 let (_, end) = self.expect_one(&Token::RightParen)?; 959 960 expr = UntypedExpr::RecordUpdate { 961 location: SrcSpan { start, end }, 962 constructor: Box::new(expr), 963 record, 964 arguments, 965 }; 966 } 967 _ => { 968 // Call 969 let arguments = self.parse_fn_arguments()?; 970 let (_, end) = self.expect_one(&Token::RightParen)?; 971 expr = make_call(expr, arguments, start, end)?; 972 } 973 } 974 } else { 975 // done 976 break; 977 } 978 } 979 } 980 } 981 982 Ok(Some(expr)) 983 } 984 985 // A `use` expression 986 // use <- function 987 // use <- function() 988 // use <- function(a, b) 989 // use <- module.function(a, b) 990 // use a, b, c <- function(a, b) 991 // use a, b, c, <- function(a, b) 992 fn parse_use(&mut self, start: u32, end: u32) -> Result<UntypedStatement, ParseError> { 993 let assignments = match self.tok0 { 994 Some((_, Token::LArrow, _)) => { 995 vec![] 996 } 997 _ => Parser::series_of(self, &Parser::parse_use_assignment, Some(&Token::Comma))?, 998 }; 999 1000 _ = self.expect_one_following_series(&Token::LArrow, "a use variable assignment")?; 1001 let call = self.expect_expression()?; 1002 1003 let assignments_location = match (assignments.first(), assignments.last()) { 1004 (Some(first), Some(last)) => SrcSpan { 1005 start: first.location.start, 1006 end: last.location.end, 1007 }, 1008 (_, _) => SrcSpan { start, end }, 1009 }; 1010 1011 Ok(Statement::Use(Use { 1012 location: SrcSpan::new(start, call.location().end), 1013 assignments_location, 1014 right_hand_side_location: call.location(), 1015 assignments, 1016 call: Box::new(call), 1017 })) 1018 } 1019 1020 fn parse_use_assignment(&mut self) -> Result<Option<UntypedUseAssignment>, ParseError> { 1021 let start = self.tok0.as_ref().map(|t| t.0).unwrap_or(0); 1022 1023 let pattern = self 1024 .parse_pattern(PatternPosition::UsePattern)? 1025 .ok_or_else(|| ParseError { 1026 error: ParseErrorType::ExpectedPattern, 1027 location: SrcSpan { start, end: start }, 1028 })?; 1029 1030 let annotation = self.parse_type_annotation(&Token::Colon)?; 1031 let end = match annotation { 1032 Some(ref a) => a.location().end, 1033 None => pattern.location().end, 1034 }; 1035 1036 Ok(Some(UseAssignment { 1037 location: SrcSpan { start, end }, 1038 pattern, 1039 annotation, 1040 })) 1041 } 1042 1043 fn maybe_parse_as_message(&mut self) -> Result<Option<Box<UntypedExpr>>, ParseError> { 1044 let message = if self.maybe_one(&Token::As).is_some() { 1045 let expression = self.expect_expression_unit(ExpressionUnitContext::Other)?; 1046 Some(Box::new(expression)) 1047 } else { 1048 None 1049 }; 1050 1051 Ok(message) 1052 } 1053 1054 // An assignment, with `Let` already consumed 1055 fn parse_assignment(&mut self, start: u32) -> Result<UntypedStatement, ParseError> { 1056 let mut kind = match self.tok0 { 1057 Some((assert_keyword_start, Token::Assert, assert_end)) => { 1058 _ = self.next_tok(); 1059 AssignmentKind::Assert { 1060 location: SrcSpan::new(start, assert_end), 1061 assert_keyword_start, 1062 message: None, 1063 } 1064 } 1065 _ => AssignmentKind::Let, 1066 }; 1067 let pattern = match self.parse_pattern(PatternPosition::LetAssignment)? { 1068 Some(p) => p, 1069 _ => { 1070 // DUPE: 62884 1071 return self.next_tok_unexpected(vec!["A pattern".into()])?; 1072 } 1073 }; 1074 let annotation = self.parse_type_annotation(&Token::Colon)?; 1075 let (eq_s, eq_e) = self.maybe_one(&Token::Equal).ok_or(ParseError { 1076 error: ParseErrorType::ExpectedEqual, 1077 location: SrcSpan { 1078 start: pattern.location().start, 1079 end: pattern.location().end, 1080 }, 1081 })?; 1082 let value = self.parse_expression_inner(true)?.ok_or(match self.tok0 { 1083 Some((start, Token::DiscardName { .. }, end)) => ParseError { 1084 error: ParseErrorType::IncorrectName, 1085 location: SrcSpan { start, end }, 1086 }, 1087 1088 _ => ParseError { 1089 error: ParseErrorType::ExpectedValue, 1090 location: SrcSpan { 1091 start: eq_s, 1092 end: eq_e, 1093 }, 1094 }, 1095 })?; 1096 1097 let mut end = value.location().end; 1098 1099 match &mut kind { 1100 AssignmentKind::Let | AssignmentKind::Generated => {} 1101 AssignmentKind::Assert { message, .. } => { 1102 if self.maybe_one(&Token::As).is_some() { 1103 let message_expression = 1104 self.expect_expression_unit(ExpressionUnitContext::Other)?; 1105 end = message_expression.location().end; 1106 *message = Some(message_expression); 1107 } 1108 } 1109 } 1110 1111 Ok(Statement::Assignment(Box::new(Assignment { 1112 location: SrcSpan { start, end }, 1113 value, 1114 compiled_case: CompiledCase::failure(), 1115 pattern, 1116 annotation, 1117 kind, 1118 }))) 1119 } 1120 1121 // An assert statement, with `Assert` already consumed 1122 fn parse_assert(&mut self, start: u32) -> Result<UntypedStatement, ParseError> { 1123 let value = self.expect_expression()?; 1124 let mut end = value.location().end; 1125 1126 let message = if self.maybe_one(&Token::As).is_some() { 1127 let message_expression = self.expect_expression_unit(ExpressionUnitContext::Other)?; 1128 end = message_expression.location().end; 1129 Some(message_expression) 1130 } else { 1131 None 1132 }; 1133 1134 Ok(Statement::Assert(Assert { 1135 location: SrcSpan { start, end }, 1136 value, 1137 message, 1138 })) 1139 } 1140 1141 // examples: 1142 // expr 1143 // expr expr.. 1144 // expr assignment.. 1145 // assignment 1146 // assignment expr.. 1147 // assignment assignment.. 1148 fn parse_statement_seq(&mut self) -> Result<Option<(Vec1<UntypedStatement>, u32)>, ParseError> { 1149 let mut statements = vec![]; 1150 let mut start = None; 1151 let mut end = 0; 1152 1153 // Try and parse as many expressions as possible 1154 while let Some(statement) = self.parse_statement()? { 1155 if start.is_none() { 1156 start = Some(statement.location().start); 1157 } 1158 end = statement.location().end; 1159 statements.push(statement); 1160 } 1161 1162 match Vec1::try_from_vec(statements) { 1163 Ok(statements) => Ok(Some((statements, end))), 1164 Err(_) => Ok(None), 1165 } 1166 } 1167 1168 fn parse_statement(&mut self) -> Result<Option<UntypedStatement>, ParseError> { 1169 match self.tok0.take() { 1170 Some((start, Token::Use, end)) => { 1171 self.advance(); 1172 Ok(Some(self.parse_use(start, end)?)) 1173 } 1174 1175 Some((start, Token::Let, _)) => { 1176 self.advance(); 1177 Ok(Some(self.parse_assignment(start)?)) 1178 } 1179 1180 Some((start, Token::Assert, _)) => { 1181 self.advance(); 1182 Ok(Some(self.parse_assert(start)?)) 1183 } 1184 1185 // Helpful error when trying to define a constant inside a function. 1186 Some((start, Token::Const, end)) => parse_error( 1187 ParseErrorType::ConstantInsideFunction, 1188 SrcSpan { start, end }, 1189 ), 1190 1191 token => { 1192 self.tok0 = token; 1193 self.parse_statement_errors()?; 1194 let expression = self.parse_expression()?.map(Statement::Expression); 1195 Ok(expression) 1196 } 1197 } 1198 } 1199 1200 fn parse_statement_errors(&mut self) -> Result<(), ParseError> { 1201 // Better error: name definitions must start with `let` 1202 if let Some((_, Token::Name { .. }, _)) = self.tok0.as_ref() 1203 && let Some((start, Token::Equal | Token::Colon, end)) = self.tok1 1204 { 1205 return parse_error(ParseErrorType::NoLetBinding, SrcSpan { start, end }); 1206 } 1207 Ok(()) 1208 } 1209 1210 fn parse_block(&mut self, start: u32) -> Result<UntypedExpr, ParseError> { 1211 let body = self.parse_statement_seq()?; 1212 let (_, end) = self.expect_one(&Token::RightBrace)?; 1213 let location = SrcSpan { start, end }; 1214 let statements = match body { 1215 Some((statements, _)) => statements, 1216 None => vec1![Statement::Expression(UntypedExpr::Todo { 1217 kind: TodoKind::EmptyBlock, 1218 location, 1219 message: None 1220 })], 1221 }; 1222 1223 Ok(UntypedExpr::Block { 1224 location, 1225 statements, 1226 }) 1227 } 1228 1229 // The left side of an "=" or a "->" 1230 fn parse_pattern( 1231 &mut self, 1232 position: PatternPosition, 1233 ) -> Result<Option<UntypedPattern>, ParseError> { 1234 let pattern = match self.tok0.take() { 1235 // Pattern::Var or Pattern::Constructor start 1236 Some((start, Token::Name { name }, end)) => { 1237 self.advance(); 1238 1239 // A variable is not permitted on the left hand side of a `<>` 1240 if let Some((_, Token::LtGt, _)) = self.tok0.as_ref() { 1241 return concat_pattern_variable_left_hand_side_error(start, end); 1242 } 1243 1244 if self.maybe_one(&Token::Dot).is_some() { 1245 // We're doing this to get a better error message instead of a generic 1246 // `I was expecting a type`, you can have a look at this issue to get 1247 // a better idea: https://github.com/gleam-lang/gleam/issues/2841. 1248 match self.expect_constructor_pattern(Some((start, name, end)), position) { 1249 Ok(result) => result, 1250 Err(ParseError { 1251 location: SrcSpan { end, .. }, 1252 .. 1253 }) => { 1254 return parse_error( 1255 ParseErrorType::InvalidModuleTypePattern, 1256 SrcSpan { start, end }, 1257 ); 1258 } 1259 } 1260 } else { 1261 match name.as_str() { 1262 "true" | "false" => { 1263 return parse_error( 1264 ParseErrorType::LowcaseBooleanPattern, 1265 SrcSpan { start, end }, 1266 ); 1267 } 1268 _ => Pattern::Variable { 1269 origin: VariableOrigin { 1270 syntax: VariableSyntax::Variable(name.clone()), 1271 declaration: position.to_declaration(), 1272 }, 1273 location: SrcSpan { start, end }, 1274 name, 1275 type_: (), 1276 }, 1277 } 1278 } 1279 } 1280 // Constructor 1281 Some((start, tok @ Token::UpName { .. }, end)) => { 1282 self.tok0 = Some((start, tok, end)); 1283 self.expect_constructor_pattern(None, position)? 1284 } 1285 1286 Some((start, Token::DiscardName { name }, end)) => { 1287 self.advance(); 1288 1289 // A discard is not permitted on the left hand side of a `<>` 1290 if let Some((_, Token::LtGt, _)) = self.tok0.as_ref() { 1291 return concat_pattern_variable_left_hand_side_error(start, end); 1292 } 1293 1294 Pattern::Discard { 1295 location: SrcSpan { start, end }, 1296 name, 1297 type_: (), 1298 } 1299 } 1300 1301 Some((start, Token::String { value }, end)) => { 1302 self.advance(); 1303 1304 match self.tok0 { 1305 // String matching with assignment, it could either be a 1306 // String prefix matching: "Hello, " as greeting <> name -> ... 1307 // or a full string matching: "Hello, World!" as greeting -> ... 1308 Some((_, Token::As, _)) => { 1309 self.advance(); 1310 let (name_start, name, name_end) = self.expect_name()?; 1311 let name_span = SrcSpan { 1312 start: name_start, 1313 end: name_end, 1314 }; 1315 1316 match self.tok0 { 1317 // String prefix matching with assignment 1318 // "Hello, " as greeting <> name -> ... 1319 Some((_, Token::LtGt, _)) => { 1320 self.advance(); 1321 let (r_start, right, r_end) = self.expect_assign_name()?; 1322 Pattern::StringPrefix { 1323 location: SrcSpan { start, end: r_end }, 1324 left_location: SrcSpan { 1325 start, 1326 end: name_end, 1327 }, 1328 right_location: SrcSpan { 1329 start: r_start, 1330 end: r_end, 1331 }, 1332 left_side_string: value, 1333 left_side_assignment: Some((name, name_span)), 1334 right_side_assignment: right, 1335 } 1336 } 1337 // Full string matching with assignment 1338 _ => { 1339 return Ok(Some(Pattern::Assign { 1340 name, 1341 location: name_span, 1342 pattern: Box::new(Pattern::String { 1343 location: SrcSpan { start, end }, 1344 value, 1345 }), 1346 })); 1347 } 1348 } 1349 } 1350 1351 // String prefix matching with no left side assignment 1352 // "Hello, " <> name -> ... 1353 Some((_, Token::LtGt, _)) => { 1354 self.advance(); 1355 let (r_start, right, r_end) = self.expect_assign_name()?; 1356 Pattern::StringPrefix { 1357 location: SrcSpan { start, end: r_end }, 1358 left_location: SrcSpan { start, end }, 1359 right_location: SrcSpan { 1360 start: r_start, 1361 end: r_end, 1362 }, 1363 left_side_string: value, 1364 left_side_assignment: None, 1365 right_side_assignment: right, 1366 } 1367 } 1368 1369 // Full string matching 1370 // "Hello, World!" -> ... 1371 _ => Pattern::String { 1372 location: SrcSpan { start, end }, 1373 value, 1374 }, 1375 } 1376 } 1377 Some((start, Token::Int { value, int_value }, end)) => { 1378 self.advance(); 1379 Pattern::Int { 1380 location: SrcSpan { start, end }, 1381 value, 1382 int_value, 1383 } 1384 } 1385 Some((start, Token::Float { value }, end)) => { 1386 self.advance(); 1387 Pattern::Float { 1388 location: SrcSpan { start, end }, 1389 value, 1390 } 1391 } 1392 Some((start, Token::Hash, _)) => { 1393 self.advance(); 1394 let _ = self.expect_one(&Token::LeftParen)?; 1395 let elements = Parser::series_of( 1396 self, 1397 &|this| this.parse_pattern(position), 1398 Some(&Token::Comma), 1399 )?; 1400 let (_, end) = self.expect_one_following_series(&Token::RightParen, "a pattern")?; 1401 Pattern::Tuple { 1402 location: SrcSpan { start, end }, 1403 elements, 1404 } 1405 } 1406 // BitArray 1407 Some((start, Token::LtLt, _)) => { 1408 self.advance(); 1409 let segments = Parser::series_of( 1410 self, 1411 &|s| { 1412 Parser::parse_bit_array_segment( 1413 s, 1414 &|s| match s.parse_pattern(position) { 1415 Ok(Some(Pattern::BitArray { location, .. })) => { 1416 parse_error(ParseErrorType::NestedBitArrayPattern, location) 1417 } 1418 x => x, 1419 }, 1420 &Parser::expect_bit_array_pattern_segment_arg, 1421 &bit_array_size_int, 1422 ) 1423 }, 1424 Some(&Token::Comma), 1425 )?; 1426 let (_, end) = 1427 self.expect_one_following_series(&Token::GtGt, "a bit array segment pattern")?; 1428 Pattern::BitArray { 1429 location: SrcSpan { start, end }, 1430 segments, 1431 } 1432 } 1433 // List 1434 Some((start, Token::LeftSquare, _)) => { 1435 self.advance(); 1436 let (elements, elements_end_with_comma) = self.series_of_has_trailing_separator( 1437 &|this| this.parse_pattern(position), 1438 Some(&Token::Comma), 1439 )?; 1440 1441 let mut elements_after_tail = None; 1442 let mut dot_dot_location = None; 1443 let tail = match self.tok0 { 1444 Some((dot_dot_start, Token::DotDot, dot_dot_end)) => { 1445 dot_dot_location = Some((dot_dot_start, dot_dot_end)); 1446 if !elements.is_empty() && !elements_end_with_comma { 1447 self.warnings 1448 .push(DeprecatedSyntaxWarning::DeprecatedListPattern { 1449 location: SrcSpan { 1450 start: dot_dot_start, 1451 end: dot_dot_end, 1452 }, 1453 }); 1454 } 1455 1456 self.advance(); 1457 let pat = self.parse_pattern(position)?; 1458 if self.maybe_one(&Token::Comma).is_some() { 1459 // See if there's a list of items after the tail, 1460 // like `[..wibble, wobble, wabble]` 1461 let elements = Parser::series_of( 1462 self, 1463 &|this| this.parse_pattern(position), 1464 Some(&Token::Comma), 1465 ); 1466 match elements { 1467 Err(_) => {} 1468 Ok(elements) => { 1469 elements_after_tail = Some(elements); 1470 } 1471 }; 1472 }; 1473 Some(pat) 1474 } 1475 _ => None, 1476 }; 1477 1478 let (end, rsqb_e) = 1479 self.expect_one_following_series(&Token::RightSquare, "a pattern")?; 1480 1481 // If there are elements after the tail, return an error 1482 match elements_after_tail { 1483 Some(elements) if !elements.is_empty() => { 1484 let (start, end) = match (dot_dot_location, tail) { 1485 (Some((start, _)), Some(Some(tail))) => (start, tail.location().end), 1486 (Some((start, end)), Some(None)) => (start, end), 1487 (_, _) => (start, end), 1488 }; 1489 return parse_error( 1490 ParseErrorType::ListPatternSpreadFollowedByElements, 1491 SrcSpan { start, end }, 1492 ); 1493 } 1494 _ => {} 1495 } 1496 1497 let tail = match tail { 1498 // There is a tail and it has a Pattern::Var or Pattern::Discard 1499 Some(Some(pat @ (Pattern::Variable { .. } | Pattern::Discard { .. }))) => { 1500 Some(pat) 1501 } 1502 // There is a tail and but it has no content, implicit discard 1503 Some(Some(pat)) => { 1504 return parse_error(ParseErrorType::InvalidTailPattern, pat.location()); 1505 } 1506 Some(None) => Some(Pattern::Discard { 1507 location: SrcSpan { 1508 start: rsqb_e - 1, 1509 end: rsqb_e, 1510 }, 1511 name: "_".into(), 1512 type_: (), 1513 }), 1514 // No tail specified 1515 None => None, 1516 }; 1517 1518 if elements.is_empty() && tail.as_ref().is_some_and(|p| p.is_discard()) { 1519 self.warnings 1520 .push(DeprecatedSyntaxWarning::DeprecatedListCatchAllPattern { 1521 location: SrcSpan { start, end: rsqb_e }, 1522 }) 1523 } 1524 1525 Pattern::List { 1526 location: SrcSpan { start, end: rsqb_e }, 1527 elements, 1528 tail: tail.map(Box::new), 1529 type_: (), 1530 } 1531 } 1532 1533 // No pattern 1534 t0 => { 1535 self.tok0 = t0; 1536 return Ok(None); 1537 } 1538 }; 1539 1540 match self.tok0 { 1541 Some((_, Token::As, _)) => { 1542 self.advance(); 1543 let (start, name, end) = self.expect_name()?; 1544 Ok(Some(Pattern::Assign { 1545 name, 1546 location: SrcSpan { start, end }, 1547 pattern: Box::new(pattern), 1548 })) 1549 } 1550 _ => Ok(Some(pattern)), 1551 } 1552 } 1553 1554 fn add_multi_line_clause_hint(&self, mut err: ParseError) -> ParseError { 1555 if let ParseErrorType::UnexpectedToken { ref mut hint, .. } = err.error { 1556 *hint = Some("Did you mean to wrap a multi line clause in curly braces?".into()); 1557 } 1558 err 1559 } 1560 1561 // examples: 1562 // pattern -> expr 1563 // pattern, pattern if -> expr 1564 // pattern, pattern | pattern, pattern if -> expr 1565 fn parse_case_clause(&mut self) -> Result<Option<UntypedClause>, ParseError> { 1566 let patterns = self.parse_patterns(PatternPosition::CaseClause)?; 1567 match &patterns.first() { 1568 Some(lead) => { 1569 let mut alternative_patterns = vec![]; 1570 loop { 1571 if self.maybe_one(&Token::Vbar).is_none() { 1572 break; 1573 } 1574 alternative_patterns.push(self.parse_patterns(PatternPosition::CaseClause)?); 1575 } 1576 let guard = self.parse_case_clause_guard()?; 1577 let (arr_s, arr_e) = self 1578 .expect_one(&Token::RArrow) 1579 .map_err(|e| self.add_multi_line_clause_hint(e))?; 1580 let then = self.parse_expression()?; 1581 match then { 1582 Some(then) => Ok(Some(Clause { 1583 location: SrcSpan { 1584 start: lead.location().start, 1585 end: then.location().end, 1586 }, 1587 pattern: patterns, 1588 alternative_patterns, 1589 guard, 1590 then, 1591 })), 1592 _ => match self.tok0 { 1593 Some((start, Token::DiscardName { .. }, end)) => { 1594 parse_error(ParseErrorType::IncorrectName, SrcSpan { start, end }) 1595 } 1596 _ => parse_error( 1597 ParseErrorType::ExpectedExpr, 1598 SrcSpan { 1599 start: arr_s, 1600 end: arr_e, 1601 }, 1602 ), 1603 }, 1604 } 1605 } 1606 _ => Ok(None), 1607 } 1608 } 1609 fn parse_patterns( 1610 &mut self, 1611 position: PatternPosition, 1612 ) -> Result<Vec<UntypedPattern>, ParseError> { 1613 Parser::series_of( 1614 self, 1615 &|this| this.parse_pattern(position), 1616 Some(&Token::Comma), 1617 ) 1618 } 1619 1620 // examples: 1621 // if a 1622 // if a < b 1623 // if a < b || b < c 1624 fn parse_case_clause_guard(&mut self) -> Result<Option<UntypedClauseGuard>, ParseError> { 1625 let Some((start, end)) = self.maybe_one(&Token::If) else { 1626 return Ok(None); 1627 }; 1628 let clause_guard_result = self.parse_clause_guard_inner(); 1629 // If inner clause is none, a warning should be shown to let the user 1630 // know that empty clauses in guards are deprecated. 1631 if let Ok(None) = clause_guard_result { 1632 self.warnings 1633 .push(DeprecatedSyntaxWarning::DeprecatedEmptyClauseGuard { 1634 location: SrcSpan { start, end }, 1635 }); 1636 } 1637 clause_guard_result 1638 } 1639 1640 fn parse_clause_guard_inner(&mut self) -> Result<Option<UntypedClauseGuard>, ParseError> { 1641 let mut opstack = vec![]; 1642 let mut estack = vec![]; 1643 let mut last_op_start = 0; 1644 let mut last_op_end = 0; 1645 loop { 1646 match self.parse_case_clause_guard_unit()? { 1647 Some(unit) => estack.push(unit), 1648 _ => { 1649 if estack.is_empty() { 1650 return Ok(None); 1651 } else { 1652 return parse_error( 1653 ParseErrorType::OpNakedRight, 1654 SrcSpan { 1655 start: last_op_start, 1656 end: last_op_end, 1657 }, 1658 ); 1659 } 1660 } 1661 } 1662 1663 let Some((op_s, t, op_e)) = self.tok0.take() else { 1664 break; 1665 }; 1666 1667 let Some(precedence) = t.guard_precedence() else { 1668 // Is not Op 1669 self.tok0 = Some((op_s, t, op_e)); 1670 break; 1671 }; 1672 1673 // Is Op 1674 self.advance(); 1675 last_op_start = op_s; 1676 last_op_end = op_e; 1677 let _ = handle_op( 1678 Some(((op_s, t, op_e), precedence)), 1679 &mut opstack, 1680 &mut estack, 1681 &do_reduce_clause_guard, 1682 ); 1683 } 1684 1685 Ok(handle_op( 1686 None, 1687 &mut opstack, 1688 &mut estack, 1689 &do_reduce_clause_guard, 1690 )) 1691 } 1692 1693 /// Checks if we have an unexpected left parenthesis and returns appropriate 1694 /// error if it is a function call. 1695 fn parse_function_call_in_clause_guard(&mut self, start: u32) -> Result<(), ParseError> { 1696 if let Some((l_paren_start, l_paren_end)) = self.maybe_one(&Token::LeftParen) { 1697 if let Ok((_, end)) = self 1698 .parse_fn_arguments() 1699 .and(self.expect_one(&Token::RightParen)) 1700 { 1701 return parse_error(ParseErrorType::CallInClauseGuard, SrcSpan { start, end }); 1702 } 1703 1704 return parse_error( 1705 ParseErrorType::UnexpectedToken { 1706 token: Token::LeftParen, 1707 expected: vec![Token::RArrow.to_string().into()], 1708 hint: None, 1709 }, 1710 SrcSpan { 1711 start: l_paren_start, 1712 end: l_paren_end, 1713 }, 1714 ) 1715 .map_err(|e| self.add_multi_line_clause_hint(e)); 1716 } 1717 1718 Ok(()) 1719 } 1720 1721 // examples 1722 // a 1723 // 1 1724 // a.1 1725 // { a } 1726 // a || b 1727 // a < b || b < c 1728 fn parse_case_clause_guard_unit(&mut self) -> Result<Option<UntypedClauseGuard>, ParseError> { 1729 match self.tok0.take() { 1730 Some((start, Token::Bang, _)) => { 1731 self.advance(); 1732 match self.parse_case_clause_guard_unit()? { 1733 Some(unit) => Ok(Some(ClauseGuard::Not { 1734 location: SrcSpan { 1735 start, 1736 end: unit.location().end, 1737 }, 1738 expression: Box::new(unit), 1739 })), 1740 None => { 1741 parse_error(ParseErrorType::ExpectedValue, SrcSpan { start, end: start }) 1742 } 1743 } 1744 } 1745 1746 Some((start, Token::Name { name }, end)) => { 1747 self.advance(); 1748 1749 self.parse_function_call_in_clause_guard(start)?; 1750 1751 let mut unit = 1752 match self.parse_record_in_clause_guard(&name, SrcSpan { start, end })? { 1753 Some(record) => record, 1754 _ => ClauseGuard::Var { 1755 location: SrcSpan { start, end }, 1756 type_: (), 1757 name, 1758 definition_location: SrcSpan::default(), 1759 }, 1760 }; 1761 1762 loop { 1763 let dot_s = match self.maybe_one(&Token::Dot) { 1764 Some((dot_s, _)) => dot_s, 1765 None => return Ok(Some(unit)), 1766 }; 1767 1768 match self.next_tok() { 1769 Some(( 1770 _, 1771 Token::Int { 1772 value, 1773 int_value: _, 1774 }, 1775 int_e, 1776 )) => { 1777 let v = value.replace("_", ""); 1778 match u64::from_str(&v) { 1779 Ok(index) => { 1780 unit = ClauseGuard::TupleIndex { 1781 location: SrcSpan { 1782 start: dot_s, 1783 end: int_e, 1784 }, 1785 index, 1786 type_: (), 1787 tuple: Box::new(unit), 1788 }; 1789 } 1790 _ => { 1791 return parse_error( 1792 ParseErrorType::InvalidTupleAccess, 1793 SrcSpan { start, end }, 1794 ); 1795 } 1796 } 1797 } 1798 1799 Some((name_start, Token::Name { name: label }, name_end)) => { 1800 self.parse_function_call_in_clause_guard(start)?; 1801 1802 unit = ClauseGuard::FieldAccess { 1803 label_location: SrcSpan { 1804 start: name_start, 1805 end: name_end, 1806 }, 1807 index: None, 1808 label, 1809 type_: (), 1810 container: Box::new(unit), 1811 }; 1812 } 1813 1814 Some((start, _, end)) => { 1815 return parse_error( 1816 ParseErrorType::IncorrectName, 1817 SrcSpan { start, end }, 1818 ); 1819 } 1820 1821 _ => return self.next_tok_unexpected(vec!["A positive integer".into()]), 1822 } 1823 } 1824 } 1825 1826 Some((start, Token::LeftBrace, _)) => { 1827 self.advance(); 1828 Ok(Some(self.parse_case_clause_guard_block(start)?)) 1829 } 1830 1831 t0 => { 1832 self.tok0 = t0; 1833 match self.parse_const_value()? { 1834 Some(const_val) => { 1835 // Constant 1836 Ok(Some(ClauseGuard::Constant(const_val))) 1837 } 1838 _ => Ok(None), 1839 } 1840 } 1841 } 1842 } 1843 1844 fn parse_case_clause_guard_block( 1845 &mut self, 1846 start: u32, 1847 ) -> Result<UntypedClauseGuard, ParseError> { 1848 let body = self.parse_clause_guard_inner()?; 1849 1850 let Some(body) = body else { 1851 let location = match self.next_tok() { 1852 Some((_, Token::RightBrace, end)) => SrcSpan { start, end }, 1853 Some((_, _, _)) | None => SrcSpan { 1854 start, 1855 end: start + 1, 1856 }, 1857 }; 1858 1859 return parse_error(ParseErrorType::EmptyGuardBlock, location); 1860 }; 1861 1862 let (_, end) = self.expect_one(&Token::RightBrace)?; 1863 Ok(ClauseGuard::Block { 1864 location: SrcSpan { start, end }, 1865 value: Box::new(body), 1866 }) 1867 } 1868 1869 fn parse_record_in_clause_guard( 1870 &mut self, 1871 module: &EcoString, 1872 module_location: SrcSpan, 1873 ) -> Result<Option<UntypedClauseGuard>, ParseError> { 1874 let (name, end) = match (self.tok0.take(), self.peek_tok1()) { 1875 (Some((_, Token::Dot, _)), Some(Token::UpName { .. })) => { 1876 self.advance(); // dot 1877 let Some((_, Token::UpName { name }, end)) = self.next_tok() else { 1878 return Ok(None); 1879 }; 1880 (name, end) 1881 } 1882 (tok0, _) => { 1883 self.tok0 = tok0; 1884 return Ok(None); 1885 } 1886 }; 1887 1888 match self.parse_const_record_finish( 1889 module_location.start, 1890 Some((module.clone(), module_location)), 1891 name, 1892 end, 1893 )? { 1894 Some(record) => Ok(Some(ClauseGuard::Constant(record))), 1895 _ => Ok(None), 1896 } 1897 } 1898 1899 // examples: 1900 // UpName( args ) 1901 fn expect_constructor_pattern( 1902 &mut self, 1903 module: Option<(u32, EcoString, u32)>, 1904 position: PatternPosition, 1905 ) -> Result<UntypedPattern, ParseError> { 1906 let (name_start, name, name_end) = self.expect_upname()?; 1907 let mut start = name_start; 1908 let (arguments, spread, end) = 1909 self.parse_constructor_pattern_arguments(name_end, position)?; 1910 if let Some((s, _, _)) = module { 1911 start = s; 1912 } 1913 Ok(Pattern::Constructor { 1914 location: SrcSpan { start, end }, 1915 name_location: SrcSpan::new(name_start, name_end), 1916 arguments, 1917 module: module.map(|(start, n, end)| (n, SrcSpan { start, end })), 1918 name, 1919 spread, 1920 constructor: Inferred::Unknown, 1921 type_: (), 1922 }) 1923 } 1924 1925 // examples: 1926 // ( args ) 1927 #[allow(clippy::type_complexity)] 1928 fn parse_constructor_pattern_arguments( 1929 &mut self, 1930 upname_end: u32, 1931 position: PatternPosition, 1932 ) -> Result<(Vec<CallArg<UntypedPattern>>, Option<SrcSpan>, u32), ParseError> { 1933 if self.maybe_one(&Token::LeftParen).is_some() { 1934 let (arguments, arguments_end_with_comma) = self.series_of_has_trailing_separator( 1935 &|this| this.parse_constructor_pattern_arg(position), 1936 Some(&Token::Comma), 1937 )?; 1938 1939 let spread = self 1940 .maybe_one(&Token::DotDot) 1941 .map(|(start, end)| SrcSpan { start, end }); 1942 1943 if let Some(spread_location) = spread { 1944 let _ = self.maybe_one(&Token::Comma); 1945 if !arguments.is_empty() && !arguments_end_with_comma { 1946 self.warnings 1947 .push(DeprecatedSyntaxWarning::DeprecatedRecordSpreadPattern { 1948 location: spread_location, 1949 }) 1950 } 1951 } 1952 let (_, end) = self.expect_one(&Token::RightParen)?; 1953 Ok((arguments, spread, end)) 1954 } else { 1955 Ok((vec![], None, upname_end)) 1956 } 1957 } 1958 1959 // examples: 1960 // a: <pattern> 1961 // a: 1962 // <pattern> 1963 fn parse_constructor_pattern_arg( 1964 &mut self, 1965 position: PatternPosition, 1966 ) -> Result<Option<CallArg<UntypedPattern>>, ParseError> { 1967 match (self.tok0.take(), self.tok1.take()) { 1968 // named arg 1969 (Some((start, Token::Name { name }, _)), Some((_, Token::Colon, end))) => { 1970 self.advance(); 1971 self.advance(); 1972 match self.parse_pattern(position)? { 1973 Some(value) => Ok(Some(CallArg { 1974 implicit: None, 1975 location: SrcSpan { 1976 start, 1977 end: value.location().end, 1978 }, 1979 label: Some(name), 1980 value, 1981 })), 1982 _ => { 1983 // Argument supplied with a label shorthand. 1984 Ok(Some(CallArg { 1985 implicit: None, 1986 location: SrcSpan { start, end }, 1987 label: Some(name.clone()), 1988 value: UntypedPattern::Variable { 1989 origin: VariableOrigin { 1990 syntax: VariableSyntax::LabelShorthand(name.clone()), 1991 declaration: position.to_declaration(), 1992 }, 1993 name, 1994 location: SrcSpan { start, end }, 1995 type_: (), 1996 }, 1997 })) 1998 } 1999 } 2000 } 2001 // unnamed arg 2002 (t0, t1) => { 2003 self.tok0 = t0; 2004 self.tok1 = t1; 2005 match self.parse_pattern(position)? { 2006 Some(value) => Ok(Some(CallArg { 2007 implicit: None, 2008 location: value.location(), 2009 label: None, 2010 value, 2011 })), 2012 _ => Ok(None), 2013 } 2014 } 2015 } 2016 } 2017 2018 // examples: 2019 // a: expr 2020 // a: 2021 fn parse_record_update_arg(&mut self) -> Result<Option<UntypedRecordUpdateArg>, ParseError> { 2022 match self.maybe_name() { 2023 Some((start, label, _)) => { 2024 let (_, end) = self.expect_one(&Token::Colon)?; 2025 let value = self.parse_expression()?; 2026 match value { 2027 Some(value) => Ok(Some(UntypedRecordUpdateArg { 2028 label, 2029 location: SrcSpan { 2030 start, 2031 end: value.location().end, 2032 }, 2033 value, 2034 })), 2035 _ => { 2036 // Argument supplied with a label shorthand. 2037 Ok(Some(UntypedRecordUpdateArg { 2038 label: label.clone(), 2039 location: SrcSpan { start, end }, 2040 value: UntypedExpr::Var { 2041 name: label, 2042 location: SrcSpan { start, end }, 2043 }, 2044 })) 2045 } 2046 } 2047 } 2048 _ => Ok(None), 2049 } 2050 } 2051 2052 // 2053 // Parse Functions 2054 // 2055 2056 // Starts after "fn" 2057 // 2058 // examples: 2059 // fn a(name: String) -> String { .. } 2060 // pub fn a(name name: String) -> String { .. } 2061 fn parse_function( 2062 &mut self, 2063 start: u32, 2064 public: bool, 2065 is_anon: bool, 2066 attributes: &mut Attributes, 2067 ) -> Result<Option<UntypedDefinition>, ParseError> { 2068 let documentation = if is_anon { 2069 None 2070 } else { 2071 self.take_documentation(start) 2072 }; 2073 let mut name = None; 2074 if !is_anon { 2075 let (name_start, n, name_end) = self.expect_name()?; 2076 name = Some(( 2077 SrcSpan { 2078 start: name_start, 2079 end: name_end, 2080 }, 2081 n, 2082 )); 2083 } 2084 if let Some((less_start, less_end)) = self.maybe_one(&Token::Less) { 2085 return Err(ParseError { 2086 error: ParseErrorType::FunctionDefinitionAngleGenerics, 2087 location: SrcSpan { 2088 start: less_start, 2089 end: less_end, 2090 }, 2091 }); 2092 } 2093 let _ = self 2094 .expect_one(&Token::LeftParen) 2095 .map_err(|e| self.add_anon_function_hint(e))?; 2096 let arguments = Parser::series_of( 2097 self, 2098 &|parser| Parser::parse_fn_param(parser, is_anon), 2099 Some(&Token::Comma), 2100 )?; 2101 let (_, rpar_e) = 2102 self.expect_one_following_series(&Token::RightParen, "a function parameter")?; 2103 let return_annotation = self.parse_type_annotation(&Token::RArrow)?; 2104 2105 let (body_start, body, end, end_position) = match self.maybe_one(&Token::LeftBrace) { 2106 Some((left_brace_start, _)) => { 2107 let some_body = self.parse_statement_seq()?; 2108 let (_, right_brace_end) = self.expect_one(&Token::RightBrace)?; 2109 let end = return_annotation 2110 .as_ref() 2111 .map(|l| l.location().end) 2112 .unwrap_or(rpar_e); 2113 let body = match some_body { 2114 None => vec1![Statement::Expression(UntypedExpr::Todo { 2115 kind: TodoKind::EmptyFunction { 2116 function_location: SrcSpan { start, end } 2117 }, 2118 location: SrcSpan { 2119 start: left_brace_start + 1, 2120 end: right_brace_end 2121 }, 2122 message: None, 2123 })], 2124 Some((body, _)) => body, 2125 }; 2126 2127 (Some(left_brace_start), body, end, right_brace_end) 2128 } 2129 2130 None if is_anon => { 2131 return parse_error( 2132 ParseErrorType::ExpectedFunctionBody, 2133 SrcSpan { start, end: rpar_e }, 2134 ); 2135 } 2136 2137 None => { 2138 let body = vec1![Statement::Expression(UntypedExpr::Placeholder { 2139 location: SrcSpan::new(start, rpar_e) 2140 })]; 2141 (None, body, rpar_e, rpar_e) 2142 } 2143 }; 2144 2145 Ok(Some(Definition::Function(Function { 2146 documentation, 2147 location: SrcSpan { start, end }, 2148 end_position, 2149 body_start, 2150 publicity: self.publicity(public, attributes.internal)?, 2151 name, 2152 arguments, 2153 body, 2154 return_type: (), 2155 return_annotation, 2156 deprecation: std::mem::take(&mut attributes.deprecated), 2157 external_erlang: attributes.external_erlang.take(), 2158 external_javascript: attributes.external_javascript.take(), 2159 implementations: Implementations { 2160 gleam: true, 2161 can_run_on_erlang: true, 2162 can_run_on_javascript: true, 2163 uses_erlang_externals: false, 2164 uses_javascript_externals: false, 2165 }, 2166 purity: Purity::Pure, 2167 }))) 2168 } 2169 2170 fn add_anon_function_hint(&self, mut err: ParseError) -> ParseError { 2171 if let ParseErrorType::UnexpectedToken { 2172 ref mut hint, 2173 token: Token::Name { .. }, 2174 .. 2175 } = err.error 2176 { 2177 *hint = Some("Only module-level functions can be named.".into()); 2178 } 2179 err 2180 } 2181 2182 fn publicity( 2183 &self, 2184 public: bool, 2185 internal: InternalAttribute, 2186 ) -> Result<Publicity, ParseError> { 2187 match (internal, public) { 2188 (InternalAttribute::Missing, true) => Ok(Publicity::Public), 2189 (InternalAttribute::Missing, false) => Ok(Publicity::Private), 2190 (InternalAttribute::Present(location), true) => Ok(Publicity::Internal { 2191 attribute_location: Some(location), 2192 }), 2193 (InternalAttribute::Present(location), false) => Err(ParseError { 2194 error: ParseErrorType::RedundantInternalAttribute, 2195 location, 2196 }), 2197 } 2198 } 2199 2200 // Parse a single function definition param 2201 // 2202 // examples: 2203 // _ 2204 // a 2205 // a a 2206 // a _ 2207 // a _:A 2208 // a a:A 2209 fn parse_fn_param(&mut self, is_anon: bool) -> Result<Option<UntypedArg>, ParseError> { 2210 let (start, names, mut end) = match (self.tok0.take(), self.tok1.take()) { 2211 // labeled discard 2212 ( 2213 Some((start, Token::Name { name: label }, tok0_end)), 2214 Some((name_start, Token::DiscardName { name }, end)), 2215 ) => { 2216 if is_anon { 2217 return parse_error( 2218 ParseErrorType::UnexpectedLabel, 2219 SrcSpan { 2220 start, 2221 end: tok0_end, 2222 }, 2223 ); 2224 } 2225 2226 self.advance(); 2227 self.advance(); 2228 ( 2229 start, 2230 ArgNames::LabelledDiscard { 2231 name, 2232 name_location: SrcSpan::new(name_start, end), 2233 label, 2234 label_location: SrcSpan::new(start, tok0_end), 2235 }, 2236 end, 2237 ) 2238 } 2239 // discard 2240 (Some((start, Token::DiscardName { name }, end)), t1) => { 2241 self.tok1 = t1; 2242 self.advance(); 2243 ( 2244 start, 2245 ArgNames::Discard { 2246 name, 2247 location: SrcSpan { start, end }, 2248 }, 2249 end, 2250 ) 2251 } 2252 // labeled name 2253 ( 2254 Some((start, Token::Name { name: label }, tok0_end)), 2255 Some((name_start, Token::Name { name }, end)), 2256 ) => { 2257 if is_anon { 2258 return parse_error( 2259 ParseErrorType::UnexpectedLabel, 2260 SrcSpan { 2261 start, 2262 end: tok0_end, 2263 }, 2264 ); 2265 } 2266 2267 self.advance(); 2268 self.advance(); 2269 ( 2270 start, 2271 ArgNames::NamedLabelled { 2272 name, 2273 name_location: SrcSpan::new(name_start, end), 2274 label, 2275 label_location: SrcSpan::new(start, tok0_end), 2276 }, 2277 end, 2278 ) 2279 } 2280 // name 2281 (Some((start, Token::Name { name }, end)), t1) => { 2282 self.tok1 = t1; 2283 self.advance(); 2284 ( 2285 start, 2286 ArgNames::Named { 2287 name, 2288 location: SrcSpan { start, end }, 2289 }, 2290 end, 2291 ) 2292 } 2293 (t0, t1) => { 2294 self.tok0 = t0; 2295 self.tok1 = t1; 2296 return Ok(None); 2297 } 2298 }; 2299 let annotation = match self.parse_type_annotation(&Token::Colon)? { 2300 Some(a) => { 2301 end = a.location().end; 2302 Some(a) 2303 } 2304 _ => None, 2305 }; 2306 Ok(Some(Arg { 2307 location: SrcSpan { start, end }, 2308 type_: (), 2309 names, 2310 annotation, 2311 })) 2312 } 2313 2314 // Parse function call arguments, no parens 2315 // 2316 // examples: 2317 // _ 2318 // expr, expr 2319 // a: _, expr 2320 // a: expr, _, b: _ 2321 fn parse_fn_arguments(&mut self) -> Result<Vec<ParserArg>, ParseError> { 2322 let arguments = Parser::series_of(self, &Parser::parse_fn_argument, Some(&Token::Comma))?; 2323 Ok(arguments) 2324 } 2325 2326 // Parse a single function call arg 2327 // 2328 // examples: 2329 // _ 2330 // expr 2331 // a: _ 2332 // a: expr 2333 fn parse_fn_argument(&mut self) -> Result<Option<ParserArg>, ParseError> { 2334 let label = match (self.tok0.take(), self.tok1.take()) { 2335 (Some((start, Token::Name { name }, _)), Some((_, Token::Colon, end))) => { 2336 self.advance(); 2337 self.advance(); 2338 Some((start, name, end)) 2339 } 2340 (t0, t1) => { 2341 self.tok0 = t0; 2342 self.tok1 = t1; 2343 None 2344 } 2345 }; 2346 2347 match self.parse_expression()? { 2348 Some(value) => { 2349 let arg = match label { 2350 Some((start, label, _)) => CallArg { 2351 implicit: None, 2352 label: Some(label), 2353 location: SrcSpan { 2354 start, 2355 end: value.location().end, 2356 }, 2357 value, 2358 }, 2359 _ => CallArg { 2360 implicit: None, 2361 label: None, 2362 location: value.location(), 2363 value, 2364 }, 2365 }; 2366 Ok(Some(ParserArg::Arg(Box::new(arg)))) 2367 } 2368 _ => { 2369 match self.maybe_discard_name() { 2370 Some((name_start, name, name_end)) => { 2371 let arg = match label { 2372 Some((label_start, label, _)) => ParserArg::Hole { 2373 label: Some(label), 2374 arg_location: SrcSpan { 2375 start: label_start, 2376 end: name_end, 2377 }, 2378 discard_location: SrcSpan { 2379 start: name_start, 2380 end: name_end, 2381 }, 2382 name, 2383 }, 2384 _ => ParserArg::Hole { 2385 label: None, 2386 arg_location: SrcSpan { 2387 start: name_start, 2388 end: name_end, 2389 }, 2390 discard_location: SrcSpan { 2391 start: name_start, 2392 end: name_end, 2393 }, 2394 name, 2395 }, 2396 }; 2397 2398 Ok(Some(arg)) 2399 } 2400 _ => { 2401 match label { 2402 Some((start, label, end)) => { 2403 // Argument supplied with a label shorthand. 2404 Ok(Some(ParserArg::Arg(Box::new(CallArg { 2405 implicit: None, 2406 label: Some(label.clone()), 2407 location: SrcSpan { start, end }, 2408 value: UntypedExpr::Var { 2409 name: label, 2410 location: SrcSpan { start, end }, 2411 }, 2412 })))) 2413 } 2414 _ => Ok(None), 2415 } 2416 } 2417 } 2418 } 2419 } 2420 } 2421 2422 // 2423 // Parse Custom Types 2424 // 2425 2426 // examples: 2427 // type A { A } 2428 // type A { A(String) } 2429 // type Box(inner_type) { Box(inner: inner_type) } 2430 // type NamedBox(inner_type) { Box(String, inner: inner_type) } 2431 fn parse_custom_type( 2432 &mut self, 2433 start: u32, 2434 public: bool, 2435 opaque: bool, 2436 attributes: &mut Attributes, 2437 ) -> Result<Option<UntypedDefinition>, ParseError> { 2438 let documentation = self.take_documentation(start); 2439 let (name_start, name, parameters, end, name_end) = self.expect_type_name()?; 2440 let name_location = SrcSpan::new(name_start, name_end); 2441 let (constructors, end_position) = if self.maybe_one(&Token::LeftBrace).is_some() { 2442 // Custom Type 2443 let constructors = Parser::series_of( 2444 self, 2445 &|p| { 2446 // The only attribute supported on constructors is @deprecated 2447 let mut attributes = Attributes::default(); 2448 let attr_loc = Parser::parse_attributes(p, &mut attributes)?; 2449 2450 if let Some(attr_span) = attr_loc { 2451 // Expecting all but the deprecated atterbutes to be default 2452 if attributes.external_erlang.is_some() 2453 || attributes.external_javascript.is_some() 2454 || attributes.target.is_some() 2455 || attributes.internal != InternalAttribute::Missing 2456 { 2457 return parse_error( 2458 ParseErrorType::UnknownAttributeRecordVariant, 2459 attr_span, 2460 ); 2461 } 2462 } 2463 2464 match Parser::maybe_upname(p) { 2465 Some((c_s, c_n, c_e)) => { 2466 let documentation = p.take_documentation(c_s); 2467 let (arguments, arguments_e) = 2468 Parser::parse_type_constructor_arguments(p)?; 2469 let end = arguments_e.max(c_e); 2470 Ok(Some(RecordConstructor { 2471 location: SrcSpan { start: c_s, end }, 2472 name_location: SrcSpan { 2473 start: c_s, 2474 end: c_e, 2475 }, 2476 name: c_n, 2477 arguments, 2478 documentation, 2479 deprecation: attributes.deprecated, 2480 })) 2481 } 2482 _ => Ok(None), 2483 } 2484 }, 2485 // No separator 2486 None, 2487 )?; 2488 let (_, close_end) = self.expect_custom_type_close(&name, public, opaque)?; 2489 (constructors, close_end) 2490 } else { 2491 match self.maybe_one(&Token::Equal) { 2492 Some((eq_s, eq_e)) => { 2493 // Type Alias 2494 if opaque { 2495 return parse_error( 2496 ParseErrorType::OpaqueTypeAlias, 2497 SrcSpan { start, end }, 2498 ); 2499 } 2500 2501 match self.parse_type()? { 2502 Some(t) => { 2503 let type_end = t.location().end; 2504 return Ok(Some(Definition::TypeAlias(TypeAlias { 2505 documentation, 2506 location: SrcSpan::new(start, type_end), 2507 publicity: self.publicity(public, attributes.internal)?, 2508 alias: name, 2509 name_location, 2510 parameters, 2511 type_ast: t, 2512 type_: (), 2513 deprecation: std::mem::take(&mut attributes.deprecated), 2514 }))); 2515 } 2516 _ => { 2517 return parse_error( 2518 ParseErrorType::ExpectedType, 2519 SrcSpan::new(eq_s, eq_e), 2520 ); 2521 } 2522 } 2523 } 2524 _ => (vec![], end), 2525 } 2526 }; 2527 2528 Ok(Some(Definition::CustomType(CustomType { 2529 documentation, 2530 location: SrcSpan { start, end }, 2531 end_position, 2532 publicity: self.publicity(public, attributes.internal)?, 2533 opaque, 2534 name, 2535 name_location, 2536 parameters, 2537 constructors, 2538 typed_parameters: vec![], 2539 deprecation: std::mem::take(&mut attributes.deprecated), 2540 }))) 2541 } 2542 2543 // examples: 2544 // A 2545 // A(one, two) 2546 fn expect_type_name( 2547 &mut self, 2548 ) -> Result<(u32, EcoString, Vec<SpannedString>, u32, u32), ParseError> { 2549 let (start, upname, end) = self.expect_upname()?; 2550 match self.maybe_one(&Token::LeftParen) { 2551 Some((par_s, _)) => { 2552 let arguments = 2553 Parser::series_of(self, &|p| Ok(Parser::maybe_name(p)), Some(&Token::Comma))?; 2554 let (_, par_e) = self.expect_one_following_series(&Token::RightParen, "a name")?; 2555 if arguments.is_empty() { 2556 return parse_error( 2557 ParseErrorType::TypeDefinitionNoArguments, 2558 SrcSpan::new(par_s, par_e), 2559 ); 2560 } 2561 let arguments2 = arguments 2562 .into_iter() 2563 .map(|(start, name, end)| (SrcSpan { start, end }, name)) 2564 .collect(); 2565 Ok((start, upname, arguments2, par_e, end)) 2566 } 2567 _ => Ok((start, upname, vec![], end, end)), 2568 } 2569 } 2570 2571 // examples: 2572 // *no args* 2573 // () 2574 // (a, b) 2575 fn parse_type_constructor_arguments( 2576 &mut self, 2577 ) -> Result<(Vec<RecordConstructorArg<()>>, u32), ParseError> { 2578 if self.maybe_one(&Token::LeftParen).is_some() { 2579 let arguments = Parser::series_of( 2580 self, 2581 &|p| match (p.tok0.take(), p.tok1.take()) { 2582 ( 2583 Some((start, Token::Name { name }, name_end)), 2584 Some((_, Token::Colon, end)), 2585 ) => { 2586 let _ = Parser::next_tok(p); 2587 let _ = Parser::next_tok(p); 2588 let doc = p.take_documentation(start); 2589 match Parser::parse_type(p)? { 2590 Some(type_ast) => { 2591 let end = type_ast.location().end; 2592 Ok(Some(RecordConstructorArg { 2593 label: Some((SrcSpan::new(start, name_end), name)), 2594 ast: type_ast, 2595 location: SrcSpan { start, end }, 2596 type_: (), 2597 doc, 2598 })) 2599 } 2600 None => { 2601 parse_error(ParseErrorType::ExpectedType, SrcSpan { start, end }) 2602 } 2603 } 2604 } 2605 (t0, t1) => { 2606 p.tok0 = t0; 2607 p.tok1 = t1; 2608 match Parser::parse_type(p)? { 2609 Some(type_ast) => { 2610 let doc = match &p.tok0 { 2611 Some((start, _, _)) => p.take_documentation(*start), 2612 None => None, 2613 }; 2614 let type_location = type_ast.location(); 2615 Ok(Some(RecordConstructorArg { 2616 label: None, 2617 ast: type_ast, 2618 location: type_location, 2619 type_: (), 2620 doc, 2621 })) 2622 } 2623 None => Ok(None), 2624 } 2625 } 2626 }, 2627 Some(&Token::Comma), 2628 )?; 2629 let (_, end) = self 2630 .expect_one_following_series(&Token::RightParen, "a constructor argument name")?; 2631 Ok((arguments, end)) 2632 } else { 2633 Ok((vec![], 0)) 2634 } 2635 } 2636 2637 // 2638 // Parse Type Annotations 2639 // 2640 2641 // examples: 2642 // :a 2643 // :Int 2644 // :Result(a, _) 2645 // :Result(Result(a, e), #(_, String)) 2646 fn parse_type_annotation(&mut self, start_tok: &Token) -> Result<Option<TypeAst>, ParseError> { 2647 if let Some((start, end)) = self.maybe_one(start_tok) { 2648 match self.parse_type() { 2649 Ok(None) => parse_error(ParseErrorType::ExpectedType, SrcSpan { start, end }), 2650 other => other, 2651 } 2652 } else { 2653 Ok(None) 2654 } 2655 } 2656 2657 // Parse the type part of a type annotation, same as `parse_type_annotation` minus the ":" 2658 fn parse_type(&mut self) -> Result<Option<TypeAst>, ParseError> { 2659 match self.tok0.take() { 2660 // Type hole 2661 Some((start, Token::DiscardName { name }, end)) => { 2662 self.advance(); 2663 Ok(Some(TypeAst::Hole(TypeAstHole { 2664 location: SrcSpan { start, end }, 2665 name, 2666 }))) 2667 } 2668 2669 // Tuple 2670 Some((start, Token::Hash, _)) => { 2671 self.advance(); 2672 let _ = self.expect_one(&Token::LeftParen)?; 2673 let elements = self.parse_types()?; 2674 let (_, end) = self.expect_one(&Token::RightParen)?; 2675 Ok(Some(TypeAst::Tuple(TypeAstTuple { 2676 location: SrcSpan { start, end }, 2677 elements, 2678 }))) 2679 } 2680 2681 // Function 2682 Some((start, Token::Fn, _)) => { 2683 self.advance(); 2684 let _ = self.expect_one(&Token::LeftParen)?; 2685 let arguments = 2686 Parser::series_of(self, &|x| Parser::parse_type(x), Some(&Token::Comma))?; 2687 let _ = self.expect_one_following_series(&Token::RightParen, "a type")?; 2688 let (arr_s, arr_e) = self.expect_one(&Token::RArrow)?; 2689 let return_ = self.parse_type()?; 2690 match return_ { 2691 Some(return_) => Ok(Some(TypeAst::Fn(TypeAstFn { 2692 location: SrcSpan { 2693 start, 2694 end: return_.location().end, 2695 }, 2696 return_: Box::new(return_), 2697 arguments, 2698 }))), 2699 _ => parse_error( 2700 ParseErrorType::ExpectedType, 2701 SrcSpan { 2702 start: arr_s, 2703 end: arr_e, 2704 }, 2705 ), 2706 } 2707 } 2708 2709 // Constructor function 2710 Some((start, Token::UpName { name }, end)) => { 2711 self.advance(); 2712 self.parse_type_name_finish(start, start, None, name, end) 2713 } 2714 2715 // Constructor Module or type Variable 2716 Some((start, Token::Name { name: mod_name }, end)) => { 2717 self.advance(); 2718 if self.maybe_one(&Token::Dot).is_some() { 2719 let (name_start, upname, upname_e) = self.expect_upname()?; 2720 self.parse_type_name_finish( 2721 start, 2722 name_start, 2723 Some((mod_name, SrcSpan { start, end })), 2724 upname, 2725 upname_e, 2726 ) 2727 } else { 2728 Ok(Some(TypeAst::Var(TypeAstVar { 2729 location: SrcSpan { start, end }, 2730 name: mod_name, 2731 }))) 2732 } 2733 } 2734 2735 t0 => { 2736 self.tok0 = t0; 2737 Ok(None) 2738 } 2739 } 2740 } 2741 2742 // Parse the '( ... )' of a type name 2743 fn parse_type_name_finish( 2744 &mut self, 2745 start: u32, 2746 name_start: u32, 2747 module: Option<(EcoString, SrcSpan)>, 2748 name: EcoString, 2749 end: u32, 2750 ) -> Result<Option<TypeAst>, ParseError> { 2751 match self.maybe_one(&Token::LeftParen) { 2752 Some((par_s, _)) => { 2753 let arguments = self.parse_types()?; 2754 let (_, par_e) = self.expect_one(&Token::RightParen)?; 2755 if arguments.is_empty() { 2756 return parse_error( 2757 ParseErrorType::TypeConstructorNoArguments, 2758 SrcSpan::new(par_s, par_e), 2759 ); 2760 } 2761 Ok(Some(TypeAst::Constructor(TypeAstConstructor { 2762 location: SrcSpan { start, end: par_e }, 2763 name_location: SrcSpan { 2764 start: name_start, 2765 end, 2766 }, 2767 module, 2768 name, 2769 arguments, 2770 }))) 2771 } 2772 _ => Ok(Some(TypeAst::Constructor(TypeAstConstructor { 2773 location: SrcSpan { start, end }, 2774 name_location: SrcSpan { 2775 start: name_start, 2776 end, 2777 }, 2778 module, 2779 name, 2780 arguments: vec![], 2781 }))), 2782 } 2783 } 2784 2785 // For parsing a comma separated "list" of types, for tuple, constructor, and function 2786 fn parse_types(&mut self) -> Result<Vec<TypeAst>, ParseError> { 2787 let elements = Parser::series_of(self, &|p| Parser::parse_type(p), Some(&Token::Comma))?; 2788 Ok(elements) 2789 } 2790 2791 // 2792 // Parse Imports 2793 // 2794 2795 // examples: 2796 // import a 2797 // import a/b 2798 // import a/b.{c} 2799 // import a/b.{c as d} as e 2800 fn parse_import(&mut self, import_start: u32) -> Result<Option<UntypedDefinition>, ParseError> { 2801 let mut start = 0; 2802 let mut end; 2803 let mut module = EcoString::new(); 2804 // Gather module names 2805 loop { 2806 let (s, name, e) = self.expect_name()?; 2807 if module.is_empty() { 2808 start = s; 2809 } else { 2810 module.push('/'); 2811 } 2812 module.push_str(&name); 2813 end = e; 2814 2815 // Useful error for : import a/.{b} 2816 if let Some((s, _)) = self.maybe_one(&Token::SlashDot) { 2817 return parse_error( 2818 ParseErrorType::ExpectedName, 2819 SrcSpan { 2820 start: s + 1, 2821 end: s + 1, 2822 }, 2823 ); 2824 } 2825 2826 // break if there's no trailing slash 2827 if self.maybe_one(&Token::Slash).is_none() { 2828 break; 2829 } 2830 } 2831 2832 let (_, documentation) = self.take_documentation(start).unzip(); 2833 2834 // Gather imports 2835 let mut unqualified_values = vec![]; 2836 let mut unqualified_types = vec![]; 2837 2838 if let Some((dot_start, dot_end)) = self.maybe_one(&Token::Dot) { 2839 if let Err(e) = self.expect_one(&Token::LeftBrace) { 2840 // If the module does contain a '/', then it's unlikely that the user 2841 // intended for the import to be pythonic, so skip this. 2842 if module.contains('/') { 2843 return Err(e); 2844 } 2845 2846 // Catch `import gleam.io` and provide a more helpful error... 2847 let ParseErrorType::UnexpectedToken { 2848 token: Token::Name { name } | Token::UpName { name }, 2849 .. 2850 } = &e.error 2851 else { 2852 return Err(e); 2853 }; 2854 2855 return Err(ParseError { 2856 error: ParseErrorType::IncorrectImportModuleSeparator { 2857 module, 2858 item: name.clone(), 2859 }, 2860 location: SrcSpan::new(dot_start, dot_end), 2861 }); 2862 }; 2863 2864 let parsed = self.parse_unqualified_imports()?; 2865 unqualified_types = parsed.types; 2866 unqualified_values = parsed.values; 2867 let (_, e) = self.expect_one(&Token::RightBrace)?; 2868 end = e; 2869 } 2870 2871 // Parse as_name 2872 let mut as_name = None; 2873 if let Some((as_start, _)) = self.maybe_one(&Token::As) { 2874 let (_, name, e) = self.expect_assign_name()?; 2875 2876 end = e; 2877 as_name = Some(( 2878 name, 2879 SrcSpan { 2880 start: as_start, 2881 end, 2882 }, 2883 )); 2884 } 2885 2886 Ok(Some(Definition::Import(Import { 2887 documentation, 2888 location: SrcSpan { 2889 start: import_start, 2890 end, 2891 }, 2892 unqualified_values, 2893 unqualified_types, 2894 module, 2895 as_name, 2896 package: (), 2897 }))) 2898 } 2899 2900 // [Name (as Name)? | UpName (as Name)? ](, [Name (as Name)? | UpName (as Name)?])*,? 2901 fn parse_unqualified_imports(&mut self) -> Result<ParsedUnqualifiedImports, ParseError> { 2902 let mut imports = ParsedUnqualifiedImports::default(); 2903 loop { 2904 // parse imports 2905 match self.tok0.take() { 2906 Some((start, Token::Name { name }, end)) => { 2907 self.advance(); 2908 let location = SrcSpan { start, end }; 2909 let mut import = UnqualifiedImport { 2910 name, 2911 location, 2912 imported_name_location: location, 2913 as_name: None, 2914 }; 2915 if self.maybe_one(&Token::As).is_some() { 2916 let (_, as_name, end) = self.expect_name()?; 2917 import.as_name = Some(as_name); 2918 import.location.end = end; 2919 } 2920 imports.values.push(import) 2921 } 2922 2923 Some((start, Token::UpName { name }, end)) => { 2924 self.advance(); 2925 let location = SrcSpan { start, end }; 2926 let mut import = UnqualifiedImport { 2927 name, 2928 location, 2929 imported_name_location: location, 2930 as_name: None, 2931 }; 2932 if self.maybe_one(&Token::As).is_some() { 2933 let (_, as_name, end) = self.expect_upname()?; 2934 import.as_name = Some(as_name); 2935 import.location.end = end; 2936 } 2937 imports.values.push(import) 2938 } 2939 2940 Some((start, Token::Type, _)) => { 2941 self.advance(); 2942 let (name_start, name, end) = self.expect_upname()?; 2943 let location = SrcSpan { start, end }; 2944 let mut import = UnqualifiedImport { 2945 name, 2946 location, 2947 imported_name_location: SrcSpan::new(name_start, end), 2948 as_name: None, 2949 }; 2950 if self.maybe_one(&Token::As).is_some() { 2951 let (_, as_name, end) = self.expect_upname()?; 2952 import.as_name = Some(as_name); 2953 import.location.end = end; 2954 } 2955 imports.types.push(import) 2956 } 2957 2958 t0 => { 2959 self.tok0 = t0; 2960 break; 2961 } 2962 } 2963 // parse comma 2964 match self.tok0 { 2965 Some((_, Token::Comma, _)) => { 2966 self.advance(); 2967 } 2968 _ => break, 2969 } 2970 } 2971 Ok(imports) 2972 } 2973 2974 // 2975 // Parse Constants 2976 // 2977 2978 // examples: 2979 // const a = 1 2980 // const a:Int = 1 2981 // pub const a:Int = 1 2982 fn parse_module_const( 2983 &mut self, 2984 start: u32, 2985 public: bool, 2986 attributes: &Attributes, 2987 ) -> Result<Option<UntypedDefinition>, ParseError> { 2988 let (name_start, name, name_end) = self.expect_name()?; 2989 let documentation = self.take_documentation(name_start); 2990 2991 let annotation = self.parse_type_annotation(&Token::Colon)?; 2992 2993 let (eq_s, eq_e) = self.expect_one(&Token::Equal)?; 2994 match self.parse_const_value()? { 2995 Some(value) => { 2996 Ok(Some(Definition::ModuleConstant(ModuleConstant { 2997 documentation, 2998 location: SrcSpan { 2999 start, 3000 3001 // End after the type annotation if it's there, otherwise after the name 3002 end: annotation 3003 .as_ref() 3004 .map(|annotation| annotation.location().end) 3005 .unwrap_or(0) 3006 .max(name_end), 3007 }, 3008 publicity: self.publicity(public, attributes.internal)?, 3009 name, 3010 name_location: SrcSpan::new(name_start, name_end), 3011 annotation, 3012 value: Box::new(value), 3013 type_: (), 3014 deprecation: attributes.deprecated.clone(), 3015 implementations: Implementations { 3016 gleam: true, 3017 can_run_on_erlang: true, 3018 can_run_on_javascript: true, 3019 uses_erlang_externals: false, 3020 uses_javascript_externals: false, 3021 }, 3022 }))) 3023 } 3024 _ => parse_error( 3025 ParseErrorType::NoValueAfterEqual, 3026 SrcSpan { 3027 start: eq_s, 3028 end: eq_e, 3029 }, 3030 ), 3031 } 3032 } 3033 3034 // examples: 3035 // 1 3036 // "hi" 3037 // True 3038 // [1,2,3] 3039 // foo <> "bar" 3040 fn parse_const_value(&mut self) -> Result<Option<UntypedConstant>, ParseError> { 3041 let constant_result = self.parse_const_value_unit(); 3042 match constant_result { 3043 Ok(Some(constant)) => self.parse_const_maybe_concatenation(constant), 3044 _ => constant_result, 3045 } 3046 } 3047 3048 fn parse_const_value_unit(&mut self) -> Result<Option<UntypedConstant>, ParseError> { 3049 match self.tok0.take() { 3050 Some((start, Token::String { value }, end)) => { 3051 self.advance(); 3052 Ok(Some(Constant::String { 3053 value, 3054 location: SrcSpan { start, end }, 3055 })) 3056 } 3057 3058 Some((start, Token::Float { value }, end)) => { 3059 self.advance(); 3060 Ok(Some(Constant::Float { 3061 value, 3062 location: SrcSpan { start, end }, 3063 })) 3064 } 3065 3066 Some((start, Token::Int { value, int_value }, end)) => { 3067 self.advance(); 3068 Ok(Some(Constant::Int { 3069 value, 3070 int_value, 3071 location: SrcSpan { start, end }, 3072 })) 3073 } 3074 3075 Some((start, Token::Hash, _)) => { 3076 self.advance(); 3077 let _ = self.expect_one(&Token::LeftParen)?; 3078 let elements = 3079 Parser::series_of(self, &Parser::parse_const_value, Some(&Token::Comma))?; 3080 let (_, end) = 3081 self.expect_one_following_series(&Token::RightParen, "a constant value")?; 3082 Ok(Some(Constant::Tuple { 3083 elements, 3084 location: SrcSpan { start, end }, 3085 })) 3086 } 3087 3088 Some((start, Token::LeftSquare, _)) => { 3089 self.advance(); 3090 let elements = 3091 Parser::series_of(self, &Parser::parse_const_value, Some(&Token::Comma))?; 3092 let (_, end) = 3093 self.expect_one_following_series(&Token::RightSquare, "a constant value")?; 3094 Ok(Some(Constant::List { 3095 elements, 3096 location: SrcSpan { start, end }, 3097 type_: (), 3098 })) 3099 } 3100 // BitArray 3101 Some((start, Token::LtLt, _)) => { 3102 self.advance(); 3103 let segments = Parser::series_of( 3104 self, 3105 &|s| { 3106 Parser::parse_bit_array_segment( 3107 s, 3108 &Parser::parse_const_value, 3109 &Parser::expect_const_int, 3110 &bit_array_const_int, 3111 ) 3112 }, 3113 Some(&Token::Comma), 3114 )?; 3115 let (_, end) = 3116 self.expect_one_following_series(&Token::GtGt, "a bit array segment")?; 3117 Ok(Some(Constant::BitArray { 3118 location: SrcSpan { start, end }, 3119 segments, 3120 })) 3121 } 3122 3123 Some((start, Token::UpName { name }, end)) => { 3124 self.advance(); 3125 self.parse_const_record_finish(start, None, name, end) 3126 } 3127 3128 Some((start, Token::Name { name }, module_end)) 3129 if self.peek_tok1() == Some(&Token::Dot) => 3130 { 3131 self.advance(); // name 3132 self.advance(); // dot 3133 3134 match self.tok0.take() { 3135 Some((_, Token::UpName { name: upname }, end)) => { 3136 self.advance(); // upname 3137 self.parse_const_record_finish( 3138 start, 3139 Some((name, SrcSpan::new(start, module_end))), 3140 upname, 3141 end, 3142 ) 3143 } 3144 Some((_, Token::Name { name: end_name }, end)) => { 3145 self.advance(); // name 3146 3147 match self.tok0 { 3148 Some((_, Token::LeftParen, _)) => parse_error( 3149 ParseErrorType::UnexpectedFunction, 3150 SrcSpan { 3151 start, 3152 end: end + 1, 3153 }, 3154 ), 3155 _ => Ok(Some(Constant::Var { 3156 location: SrcSpan { start, end }, 3157 module: Some((name, SrcSpan::new(start, module_end))), 3158 name: end_name, 3159 constructor: None, 3160 type_: (), 3161 })), 3162 } 3163 } 3164 Some((start, token, end)) => parse_error( 3165 ParseErrorType::UnexpectedToken { 3166 token, 3167 expected: vec!["UpName".into(), "Name".into()], 3168 hint: None, 3169 }, 3170 SrcSpan { start, end }, 3171 ), 3172 None => { 3173 parse_error(ParseErrorType::UnexpectedEof, SrcSpan { start: 0, end: 0 }) 3174 } 3175 } 3176 } 3177 3178 Some((start, Token::Name { name }, end)) => { 3179 self.advance(); // name 3180 3181 match self.tok0 { 3182 Some((_, Token::LeftParen, _)) => parse_error( 3183 ParseErrorType::UnexpectedFunction, 3184 SrcSpan { 3185 start, 3186 end: end + 1, 3187 }, 3188 ), 3189 _ => Ok(Some(Constant::Var { 3190 location: SrcSpan { start, end }, 3191 module: None, 3192 name, 3193 constructor: None, 3194 type_: (), 3195 })), 3196 } 3197 } 3198 3199 // Helpful error for fn 3200 Some((start, Token::Fn, end)) => { 3201 parse_error(ParseErrorType::NotConstType, SrcSpan { start, end }) 3202 } 3203 3204 t0 => { 3205 self.tok0 = t0; 3206 Ok(None) 3207 } 3208 } 3209 } 3210 3211 fn parse_const_maybe_concatenation( 3212 &mut self, 3213 left: UntypedConstant, 3214 ) -> Result<Option<UntypedConstant>, ParseError> { 3215 match self.tok0.take() { 3216 Some((op_start, Token::LtGt, op_end)) => { 3217 self.advance(); 3218 3219 match self.parse_const_value() { 3220 Ok(Some(right_constant_value)) => Ok(Some(Constant::StringConcatenation { 3221 location: SrcSpan { 3222 start: left.location().start, 3223 end: right_constant_value.location().end, 3224 }, 3225 left: Box::new(left), 3226 right: Box::new(right_constant_value), 3227 })), 3228 _ => parse_error( 3229 ParseErrorType::OpNakedRight, 3230 SrcSpan { 3231 start: op_start, 3232 end: op_end, 3233 }, 3234 ), 3235 } 3236 } 3237 t0 => { 3238 self.tok0 = t0; 3239 Ok(Some(left)) 3240 } 3241 } 3242 } 3243 3244 // Parse the '( .. )' of a const type constructor 3245 fn parse_const_record_finish( 3246 &mut self, 3247 start: u32, 3248 module: Option<(EcoString, SrcSpan)>, 3249 name: EcoString, 3250 end: u32, 3251 ) -> Result<Option<UntypedConstant>, ParseError> { 3252 match self.maybe_one(&Token::LeftParen) { 3253 Some((par_s, _)) => { 3254 let arguments = 3255 Parser::series_of(self, &Parser::parse_const_record_arg, Some(&Token::Comma))?; 3256 let (_, par_e) = self.expect_one_following_series( 3257 &Token::RightParen, 3258 "a constant record argument", 3259 )?; 3260 if arguments.is_empty() { 3261 return parse_error( 3262 ParseErrorType::ConstantRecordConstructorNoArguments, 3263 SrcSpan::new(par_s, par_e), 3264 ); 3265 } 3266 Ok(Some(Constant::Record { 3267 location: SrcSpan { start, end: par_e }, 3268 module, 3269 name, 3270 arguments, 3271 tag: (), 3272 type_: (), 3273 field_map: None, 3274 record_constructor: None, 3275 })) 3276 } 3277 _ => Ok(Some(Constant::Record { 3278 location: SrcSpan { start, end }, 3279 module, 3280 name, 3281 arguments: vec![], 3282 tag: (), 3283 type_: (), 3284 field_map: None, 3285 record_constructor: None, 3286 })), 3287 } 3288 } 3289 3290 // examples: 3291 // name: const 3292 // const 3293 // name: 3294 fn parse_const_record_arg(&mut self) -> Result<Option<CallArg<UntypedConstant>>, ParseError> { 3295 let label = match (self.tok0.take(), self.tok1.take()) { 3296 // Named arg 3297 (Some((start, Token::Name { name }, _)), Some((_, Token::Colon, end))) => { 3298 self.advance(); 3299 self.advance(); 3300 Some((start, name, end)) 3301 } 3302 3303 // Unnamed arg 3304 (t0, t1) => { 3305 self.tok0 = t0; 3306 self.tok1 = t1; 3307 None 3308 } 3309 }; 3310 3311 match self.parse_const_value()? { 3312 Some(value) => match label { 3313 Some((start, label, _)) => Ok(Some(CallArg { 3314 implicit: None, 3315 location: SrcSpan { 3316 start, 3317 end: value.location().end, 3318 }, 3319 value, 3320 label: Some(label), 3321 })), 3322 _ => Ok(Some(CallArg { 3323 implicit: None, 3324 location: value.location(), 3325 value, 3326 label: None, 3327 })), 3328 }, 3329 _ => { 3330 match label { 3331 Some((start, label, end)) => { 3332 // Argument supplied with a label shorthand. 3333 Ok(Some(CallArg { 3334 implicit: None, 3335 location: SrcSpan { start, end }, 3336 label: Some(label.clone()), 3337 value: UntypedConstant::Var { 3338 location: SrcSpan { start, end }, 3339 constructor: None, 3340 module: None, 3341 name: label, 3342 type_: (), 3343 }, 3344 })) 3345 } 3346 _ => Ok(None), 3347 } 3348 } 3349 } 3350 } 3351 3352 // 3353 // Bit String parsing 3354 // 3355 3356 // The structure is roughly the same for pattern, const, and expr 3357 // that's why these functions take functions 3358 // 3359 // pattern (: option)? 3360 fn parse_bit_array_segment<A>( 3361 &mut self, 3362 value_parser: &impl Fn(&mut Self) -> Result<Option<A>, ParseError>, 3363 arg_parser: &impl Fn(&mut Self) -> Result<A, ParseError>, 3364 to_int_segment: &impl Fn(EcoString, BigInt, u32, u32) -> A, 3365 ) -> Result<Option<BitArraySegment<A, ()>>, ParseError> 3366 where 3367 A: HasLocation + std::fmt::Debug, 3368 { 3369 match value_parser(self)? { 3370 Some(value) => { 3371 let options = if self.maybe_one(&Token::Colon).is_some() { 3372 Parser::series_of( 3373 self, 3374 &|s| Parser::parse_bit_array_option(s, &arg_parser, &to_int_segment), 3375 Some(&Token::Minus), 3376 )? 3377 } else { 3378 vec![] 3379 }; 3380 let end = options 3381 .last() 3382 .map(|o| o.location().end) 3383 .unwrap_or_else(|| value.location().end); 3384 Ok(Some(BitArraySegment { 3385 location: SrcSpan { 3386 start: value.location().start, 3387 end, 3388 }, 3389 value: Box::new(value), 3390 type_: (), 3391 options, 3392 })) 3393 } 3394 _ => Ok(None), 3395 } 3396 } 3397 3398 // examples: 3399 // 1 3400 // size(1) 3401 // size(five) 3402 // utf8 3403 fn parse_bit_array_option<A: std::fmt::Debug>( 3404 &mut self, 3405 arg_parser: &impl Fn(&mut Self) -> Result<A, ParseError>, 3406 to_int_segment: &impl Fn(EcoString, BigInt, u32, u32) -> A, 3407 ) -> Result<Option<BitArrayOption<A>>, ParseError> { 3408 match self.next_tok() { 3409 // named segment 3410 Some((start, Token::Name { name }, end)) => { 3411 if self.maybe_one(&Token::LeftParen).is_some() { 3412 // named function segment 3413 match name.as_str() { 3414 "unit" => match self.next_tok() { 3415 Some((int_s, Token::Int { value, .. }, int_e)) => { 3416 let (_, end) = self.expect_one(&Token::RightParen)?; 3417 let v = value.replace("_", ""); 3418 match u8::from_str(&v) { 3419 Ok(units) if units > 0 => Ok(Some(BitArrayOption::Unit { 3420 location: SrcSpan { start, end }, 3421 value: units, 3422 })), 3423 3424 _ => Err(ParseError { 3425 error: ParseErrorType::InvalidBitArrayUnit, 3426 location: SrcSpan { 3427 start: int_s, 3428 end: int_e, 3429 }, 3430 }), 3431 } 3432 } 3433 _ => self.next_tok_unexpected(vec!["positive integer".into()]), 3434 }, 3435 3436 "size" => { 3437 let value = arg_parser(self)?; 3438 let (_, end) = self.expect_one(&Token::RightParen)?; 3439 Ok(Some(BitArrayOption::Size { 3440 location: SrcSpan { start, end }, 3441 value: Box::new(value), 3442 short_form: false, 3443 })) 3444 } 3445 _ => parse_error( 3446 ParseErrorType::InvalidBitArraySegment, 3447 SrcSpan { start, end }, 3448 ), 3449 } 3450 } else { 3451 str_to_bit_array_option(&name, SrcSpan { start, end }) 3452 .ok_or(ParseError { 3453 error: ParseErrorType::InvalidBitArraySegment, 3454 location: SrcSpan { start, end }, 3455 }) 3456 .map(Some) 3457 } 3458 } 3459 // int segment 3460 Some((start, Token::Int { value, int_value }, end)) => Ok(Some(BitArrayOption::Size { 3461 location: SrcSpan { start, end }, 3462 value: Box::new(to_int_segment(value, int_value, start, end)), 3463 short_form: true, 3464 })), 3465 // invalid 3466 _ => self.next_tok_unexpected(vec![ 3467 "A valid bit array segment type".into(), 3468 "See: https://tour.gleam.run/data-types/bit-arrays/".into(), 3469 ]), 3470 } 3471 } 3472 3473 fn expect_bit_array_pattern_segment_arg(&mut self) -> Result<UntypedPattern, ParseError> { 3474 Ok(Pattern::BitArraySize(self.expect_bit_array_size()?)) 3475 } 3476 3477 fn expect_bit_array_size(&mut self) -> Result<BitArraySize<()>, ParseError> { 3478 let left = match self.next_tok() { 3479 Some((start, Token::Name { name }, end)) => BitArraySize::Variable { 3480 location: SrcSpan { start, end }, 3481 name, 3482 constructor: None, 3483 type_: (), 3484 }, 3485 Some((start, Token::Int { value, int_value }, end)) => BitArraySize::Int { 3486 location: SrcSpan { start, end }, 3487 value, 3488 int_value, 3489 }, 3490 Some((start, Token::LeftBrace, _)) => { 3491 let inner = self.expect_bit_array_size()?; 3492 let (_, end) = self.expect_one(&Token::RightBrace)?; 3493 3494 BitArraySize::Block { 3495 location: SrcSpan { start, end }, 3496 inner: Box::new(inner), 3497 } 3498 } 3499 _ => return self.next_tok_unexpected(vec!["A variable name or an integer".into()]), 3500 }; 3501 3502 let Some((start, token, end)) = self.tok0.take() else { 3503 return Ok(left); 3504 }; 3505 3506 match token { 3507 Token::Plus => { 3508 _ = self.next_tok(); 3509 let right = self.expect_bit_array_size()?; 3510 3511 Ok(self.bit_array_size_binary_operator(left, right, IntOperator::Add)) 3512 } 3513 Token::Minus => { 3514 _ = self.next_tok(); 3515 let right = self.expect_bit_array_size()?; 3516 3517 Ok(self.bit_array_size_binary_operator(left, right, IntOperator::Subtract)) 3518 } 3519 Token::Star => { 3520 _ = self.next_tok(); 3521 let right = self.expect_bit_array_size()?; 3522 3523 Ok( 3524 self.bit_array_size_high_precedence_operator( 3525 left, 3526 right, 3527 IntOperator::Multiply, 3528 ), 3529 ) 3530 } 3531 Token::Slash => { 3532 _ = self.next_tok(); 3533 let right = self.expect_bit_array_size()?; 3534 3535 Ok(self.bit_array_size_high_precedence_operator(left, right, IntOperator::Divide)) 3536 } 3537 Token::Percent => { 3538 _ = self.next_tok(); 3539 let right = self.expect_bit_array_size()?; 3540 3541 Ok(self.bit_array_size_high_precedence_operator( 3542 left, 3543 right, 3544 IntOperator::Remainder, 3545 )) 3546 } 3547 _ => { 3548 self.tok0 = Some((start, token, end)); 3549 Ok(left) 3550 } 3551 } 3552 } 3553 3554 fn bit_array_size_binary_operator( 3555 &self, 3556 left: BitArraySize<()>, 3557 right: BitArraySize<()>, 3558 operator: IntOperator, 3559 ) -> BitArraySize<()> { 3560 let start = left.location().start; 3561 let end = right.location().end; 3562 3563 BitArraySize::BinaryOperator { 3564 left: Box::new(left), 3565 right: Box::new(right), 3566 operator, 3567 location: SrcSpan { start, end }, 3568 } 3569 } 3570 3571 fn bit_array_size_high_precedence_operator( 3572 &self, 3573 left: BitArraySize<()>, 3574 right: BitArraySize<()>, 3575 operator: IntOperator, 3576 ) -> BitArraySize<()> { 3577 match right { 3578 BitArraySize::Int { .. } 3579 | BitArraySize::Variable { .. } 3580 | BitArraySize::Block { .. } => { 3581 self.bit_array_size_binary_operator(left, right, operator) 3582 } 3583 // This operator has the highest precedence of the possible operators 3584 // for bit array size patterns. So, `a * b + c` should be parsed as 3585 // `(a * b) + c`. If the right-hand side of this operator is another 3586 // operator, we rearrange it to ensure correct precedence. 3587 BitArraySize::BinaryOperator { 3588 operator: right_operator, 3589 left: middle, 3590 right, 3591 .. 3592 } => self.bit_array_size_binary_operator( 3593 self.bit_array_size_binary_operator(left, *middle, operator), 3594 *right, 3595 right_operator, 3596 ), 3597 } 3598 } 3599 3600 fn expect_const_int(&mut self) -> Result<UntypedConstant, ParseError> { 3601 match self.next_tok() { 3602 Some((start, Token::Int { value, int_value }, end)) => Ok(Constant::Int { 3603 location: SrcSpan { start, end }, 3604 value, 3605 int_value, 3606 }), 3607 _ => self.next_tok_unexpected(vec!["A variable name or an integer".into()]), 3608 } 3609 } 3610 3611 fn expect_expression(&mut self) -> Result<UntypedExpr, ParseError> { 3612 match self.parse_expression()? { 3613 Some(e) => Ok(e), 3614 _ => self.next_tok_unexpected(vec!["An expression".into()]), 3615 } 3616 } 3617 3618 fn expect_expression_unit( 3619 &mut self, 3620 context: ExpressionUnitContext, 3621 ) -> Result<UntypedExpr, ParseError> { 3622 if let Some(e) = self.parse_expression_unit(context)? { 3623 Ok(e) 3624 } else { 3625 self.next_tok_unexpected(vec!["An expression".into()]) 3626 } 3627 } 3628 3629 // 3630 // Parse Helpers 3631 // 3632 3633 /// Expect a particular token, advances the token stream 3634 fn expect_one(&mut self, wanted: &Token) -> Result<(u32, u32), ParseError> { 3635 match self.maybe_one(wanted) { 3636 Some((start, end)) => Ok((start, end)), 3637 None => self.next_tok_unexpected(vec![wanted.to_string().into()]), 3638 } 3639 } 3640 3641 // Expect a particular token after having parsed a series, advances the token stream 3642 // Used for giving a clearer error message in cases where the series item is what failed to parse 3643 fn expect_one_following_series( 3644 &mut self, 3645 wanted: &Token, 3646 series: &'static str, 3647 ) -> Result<(u32, u32), ParseError> { 3648 match self.maybe_one(wanted) { 3649 Some((start, end)) => Ok((start, end)), 3650 None => self.next_tok_unexpected(vec![wanted.to_string().into(), series.into()]), 3651 } 3652 } 3653 3654 /// Expect the end to a custom type definiton or handle an incorrect 3655 /// record constructor definition. 3656 /// 3657 /// Used for mapping to a more specific error type and message. 3658 fn expect_custom_type_close( 3659 &mut self, 3660 name: &EcoString, 3661 public: bool, 3662 opaque: bool, 3663 ) -> Result<(u32, u32), ParseError> { 3664 match self.maybe_one(&Token::RightBrace) { 3665 Some((start, end)) => Ok((start, end)), 3666 None => match self.next_tok() { 3667 None => parse_error(ParseErrorType::UnexpectedEof, SrcSpan { start: 0, end: 0 }), 3668 Some((start, token, end)) => { 3669 // If provided a Name, map to a more detailed error 3670 // message to nudge the user. 3671 // Else, handle as an unexpected token. 3672 let field = match token { 3673 Token::Name { name } => name, 3674 token => { 3675 let hint = match (&token, self.tok0.take()) { 3676 (&Token::Fn, _) | (&Token::Pub, Some((_, Token::Fn, _))) => { 3677 let text = 3678 "Gleam is not an object oriented programming language so 3679functions are declared separately from types."; 3680 Some(wrap(text).into()) 3681 } 3682 (_, _) => None, 3683 }; 3684 3685 return parse_error( 3686 ParseErrorType::UnexpectedToken { 3687 token, 3688 expected: vec![ 3689 Token::RightBrace.to_string().into(), 3690 "a record constructor".into(), 3691 ], 3692 hint, 3693 }, 3694 SrcSpan { start, end }, 3695 ); 3696 } 3697 }; 3698 let field_type = match self.parse_type_annotation(&Token::Colon) { 3699 Ok(Some(annotation)) => Some(Box::new(annotation)), 3700 _ => None, 3701 }; 3702 parse_error( 3703 ParseErrorType::ExpectedRecordConstructor { 3704 name: name.clone(), 3705 public, 3706 opaque, 3707 field, 3708 field_type, 3709 }, 3710 SrcSpan { start, end }, 3711 ) 3712 } 3713 }, 3714 } 3715 } 3716 3717 // Expect a Name else a token dependent helpful error 3718 fn expect_name(&mut self) -> Result<(u32, EcoString, u32), ParseError> { 3719 let (start, token, end) = self.expect_assign_name()?; 3720 match token { 3721 AssignName::Variable(name) => Ok((start, name, end)), 3722 AssignName::Discard(_) => { 3723 parse_error(ParseErrorType::IncorrectName, SrcSpan { start, end }) 3724 } 3725 } 3726 } 3727 3728 fn expect_assign_name(&mut self) -> Result<(u32, AssignName, u32), ParseError> { 3729 let t = self.next_tok(); 3730 match t { 3731 Some((start, tok, end)) => match tok { 3732 Token::Name { name } => Ok((start, AssignName::Variable(name), end)), 3733 Token::DiscardName { name, .. } => Ok((start, AssignName::Discard(name), end)), 3734 Token::UpName { .. } => { 3735 parse_error(ParseErrorType::IncorrectName, SrcSpan { start, end }) 3736 } 3737 _ if tok.is_reserved_word() => parse_error( 3738 ParseErrorType::UnexpectedReservedWord, 3739 SrcSpan { start, end }, 3740 ), 3741 _ => parse_error(ParseErrorType::ExpectedName, SrcSpan { start, end }), 3742 }, 3743 None => parse_error(ParseErrorType::UnexpectedEof, SrcSpan { start: 0, end: 0 }), 3744 } 3745 } 3746 3747 // Expect an UpName else a token dependent helpful error 3748 fn expect_upname(&mut self) -> Result<(u32, EcoString, u32), ParseError> { 3749 let t = self.next_tok(); 3750 match t { 3751 Some((start, tok, end)) => match tok { 3752 Token::Name { .. } => { 3753 parse_error(ParseErrorType::IncorrectUpName, SrcSpan { start, end }) 3754 } 3755 _ => match tok { 3756 Token::UpName { name } => Ok((start, name, end)), 3757 _ => match tok { 3758 Token::DiscardName { .. } => { 3759 parse_error(ParseErrorType::IncorrectUpName, SrcSpan { start, end }) 3760 } 3761 _ => parse_error(ParseErrorType::ExpectedUpName, SrcSpan { start, end }), 3762 }, 3763 }, 3764 }, 3765 None => parse_error(ParseErrorType::UnexpectedEof, SrcSpan { start: 0, end: 0 }), 3766 } 3767 } 3768 3769 // Expect a target name. e.g. `javascript` or `erlang`. 3770 // The location of the preceding left parenthesis is required 3771 // to give the correct error span in case the target name is missing. 3772 fn expect_target(&mut self, paren_location: SrcSpan) -> Result<Target, ParseError> { 3773 let (start, t, end) = match self.next_tok() { 3774 Some(t) => t, 3775 None => { 3776 return parse_error(ParseErrorType::UnexpectedEof, SrcSpan { start: 0, end: 0 }); 3777 } 3778 }; 3779 match t { 3780 Token::Name { name } => match name.as_str() { 3781 "javascript" => Ok(Target::JavaScript), 3782 "erlang" => Ok(Target::Erlang), 3783 "js" => { 3784 self.warnings 3785 .push(DeprecatedSyntaxWarning::DeprecatedTargetShorthand { 3786 location: SrcSpan::new(start, end), 3787 target: Target::JavaScript, 3788 }); 3789 Ok(Target::JavaScript) 3790 } 3791 "erl" => { 3792 self.warnings 3793 .push(DeprecatedSyntaxWarning::DeprecatedTargetShorthand { 3794 location: SrcSpan::new(start, end), 3795 target: Target::Erlang, 3796 }); 3797 Ok(Target::Erlang) 3798 } 3799 _ => parse_error(ParseErrorType::UnknownTarget, SrcSpan::new(start, end)), 3800 }, 3801 _ => parse_error(ParseErrorType::ExpectedTargetName, paren_location), 3802 } 3803 } 3804 3805 // Expect a String else error 3806 fn expect_string(&mut self) -> Result<(u32, EcoString, u32), ParseError> { 3807 match self.next_tok() { 3808 Some((start, Token::String { value }, end)) => Ok((start, value, end)), 3809 _ => self.next_tok_unexpected(vec!["a string".into()]), 3810 } 3811 } 3812 3813 fn peek_tok1(&mut self) -> Option<&Token> { 3814 self.tok1.as_ref().map(|(_, token, _)| token) 3815 } 3816 3817 // If the next token matches the requested, consume it and return (start, end) 3818 fn maybe_one(&mut self, tok: &Token) -> Option<(u32, u32)> { 3819 match self.tok0.take() { 3820 Some((s, t, e)) if t == *tok => { 3821 self.advance(); 3822 Some((s, e)) 3823 } 3824 3825 t0 => { 3826 self.tok0 = t0; 3827 None 3828 } 3829 } 3830 } 3831 3832 // Parse a series by repeating a parser, and possibly a separator 3833 fn series_of<A>( 3834 &mut self, 3835 parser: &impl Fn(&mut Self) -> Result<Option<A>, ParseError>, 3836 sep: Option<&Token>, 3837 ) -> Result<Vec<A>, ParseError> { 3838 let (res, _) = self.series_of_has_trailing_separator(parser, sep)?; 3839 Ok(res) 3840 } 3841 3842 /// Parse a series by repeating a parser, and a separator. Returns true if 3843 /// the series ends with the trailing separator. 3844 fn series_of_has_trailing_separator<A>( 3845 &mut self, 3846 parser: &impl Fn(&mut Self) -> Result<Option<A>, ParseError>, 3847 sep: Option<&Token>, 3848 ) -> Result<(Vec<A>, bool), ParseError> { 3849 let mut results = vec![]; 3850 let mut final_separator = None; 3851 while let Some(result) = parser(self)? { 3852 results.push(result); 3853 if let Some(sep) = sep { 3854 if let Some(separator) = self.maybe_one(sep) { 3855 final_separator = Some(separator); 3856 } else { 3857 final_separator = None; 3858 break; 3859 } 3860 3861 // Helpful error if extra separator 3862 if let Some((start, end)) = self.maybe_one(sep) { 3863 return parse_error(ParseErrorType::ExtraSeparator, SrcSpan { start, end }); 3864 } 3865 } 3866 } 3867 3868 // If the sequence ends with a trailing comma we want to keep track of 3869 // its position. 3870 if let (Some(Token::Comma), Some((_, end))) = (sep, final_separator) { 3871 self.extra.trailing_commas.push(end) 3872 }; 3873 3874 Ok((results, final_separator.is_some())) 3875 } 3876 3877 // If next token is a Name, consume it and return relevant info, otherwise, return none 3878 fn maybe_name(&mut self) -> Option<(u32, EcoString, u32)> { 3879 match self.tok0.take() { 3880 Some((s, Token::Name { name }, e)) => { 3881 self.advance(); 3882 Some((s, name, e)) 3883 } 3884 t0 => { 3885 self.tok0 = t0; 3886 None 3887 } 3888 } 3889 } 3890 3891 // if next token is an UpName, consume it and return relevant info, otherwise, return none 3892 fn maybe_upname(&mut self) -> Option<(u32, EcoString, u32)> { 3893 match self.tok0.take() { 3894 Some((s, Token::UpName { name }, e)) => { 3895 self.advance(); 3896 Some((s, name, e)) 3897 } 3898 t0 => { 3899 self.tok0 = t0; 3900 None 3901 } 3902 } 3903 } 3904 3905 // if next token is a DiscardName, consume it and return relevant info, otherwise, return none 3906 fn maybe_discard_name(&mut self) -> Option<(u32, EcoString, u32)> { 3907 match self.tok0.take() { 3908 Some((s, Token::DiscardName { name }, e)) => { 3909 self.advance(); 3910 Some((s, name, e)) 3911 } 3912 t0 => { 3913 self.tok0 = t0; 3914 None 3915 } 3916 } 3917 } 3918 3919 // Unexpected token error on the next token or EOF 3920 fn next_tok_unexpected<A>(&mut self, expected: Vec<EcoString>) -> Result<A, ParseError> { 3921 match self.next_tok() { 3922 None => parse_error(ParseErrorType::UnexpectedEof, SrcSpan { start: 0, end: 0 }), 3923 Some((start, token, end)) => parse_error( 3924 ParseErrorType::UnexpectedToken { 3925 token, 3926 expected, 3927 hint: None, 3928 }, 3929 SrcSpan { start, end }, 3930 ), 3931 } 3932 } 3933 3934 // Moves the token stream forward 3935 fn advance(&mut self) { 3936 let _ = self.next_tok(); 3937 } 3938 3939 // Moving the token stream forward 3940 // returns old tok0 3941 fn next_tok(&mut self) -> Option<Spanned> { 3942 let t = self.tok0.take(); 3943 let mut previous_newline = None; 3944 let mut nxt; 3945 loop { 3946 match self.tokens.next() { 3947 // gather and skip extra 3948 Some(Ok((start, Token::CommentNormal, end))) => { 3949 self.extra.comments.push(SrcSpan { start, end }); 3950 previous_newline = None; 3951 } 3952 Some(Ok((start, Token::CommentDoc { content }, end))) => { 3953 self.extra.doc_comments.push(SrcSpan::new(start, end)); 3954 self.doc_comments.push_back((start, content)); 3955 previous_newline = None; 3956 } 3957 Some(Ok((start, Token::CommentModule, end))) => { 3958 self.extra.module_comments.push(SrcSpan { start, end }); 3959 previous_newline = None; 3960 } 3961 Some(Ok((start, Token::NewLine, _))) => { 3962 self.extra.new_lines.push(start); 3963 // If the previous token is a newline as well that means we 3964 // have run into an empty line. 3965 if let Some(start) = previous_newline { 3966 // We increase the byte position so that newline's start 3967 // doesn't overlap with the previous token's end. 3968 self.extra.empty_lines.push(start + 1); 3969 } 3970 previous_newline = Some(start); 3971 } 3972 3973 // die on lex error 3974 Some(Err(err)) => { 3975 nxt = None; 3976 self.lex_errors.push(err); 3977 break; 3978 } 3979 3980 Some(Ok(tok)) => { 3981 nxt = Some(tok); 3982 break; 3983 } 3984 None => { 3985 nxt = None; 3986 break; 3987 } 3988 } 3989 } 3990 self.tok0 = self.tok1.take(); 3991 self.tok1 = nxt.take(); 3992 t 3993 } 3994 3995 fn take_documentation(&mut self, until: u32) -> Option<(u32, EcoString)> { 3996 let mut content = String::new(); 3997 let mut doc_start = u32::MAX; 3998 while let Some((start, line)) = self.doc_comments.front() { 3999 if *start < doc_start { 4000 doc_start = *start; 4001 } 4002 if *start >= until { 4003 break; 4004 } 4005 if self.extra.has_comment_between(*start, until) { 4006 // We ignore doc comments that come before a regular comment. 4007 _ = self.doc_comments.pop_front(); 4008 continue; 4009 } 4010 4011 content.push_str(line); 4012 content.push('\n'); 4013 _ = self.doc_comments.pop_front(); 4014 } 4015 if content.is_empty() { 4016 None 4017 } else { 4018 Some((doc_start, content.into())) 4019 } 4020 } 4021 4022 fn parse_attributes( 4023 &mut self, 4024 attributes: &mut Attributes, 4025 ) -> Result<Option<SrcSpan>, ParseError> { 4026 let mut attributes_span = None; 4027 4028 while let Some((start, end)) = self.maybe_one(&Token::At) { 4029 if attributes_span.is_none() { 4030 attributes_span = Some(SrcSpan { start, end }); 4031 } 4032 4033 let end = self.parse_attribute(start, attributes)?; 4034 attributes_span = attributes_span.map(|span| SrcSpan { 4035 start: span.start, 4036 end, 4037 }); 4038 } 4039 4040 Ok(attributes_span) 4041 } 4042 4043 fn parse_attribute( 4044 &mut self, 4045 start: u32, 4046 attributes: &mut Attributes, 4047 ) -> Result<u32, ParseError> { 4048 // Parse the name of the attribute. 4049 4050 let (_, name, end) = self.expect_name()?; 4051 4052 let end = match name.as_str() { 4053 "external" => { 4054 let _ = self.expect_one(&Token::LeftParen)?; 4055 self.parse_external_attribute(start, end, attributes) 4056 } 4057 "target" => self.parse_target_attribute(start, end, attributes), 4058 "deprecated" => { 4059 let _ = self.expect_one(&Token::LeftParen)?; 4060 self.parse_deprecated_attribute(start, end, attributes) 4061 } 4062 "internal" => self.parse_internal_attribute(start, end, attributes), 4063 _ => parse_error(ParseErrorType::UnknownAttribute, SrcSpan { start, end }), 4064 }?; 4065 4066 Ok(end) 4067 } 4068 4069 fn parse_target_attribute( 4070 &mut self, 4071 start: u32, 4072 end: u32, 4073 attributes: &mut Attributes, 4074 ) -> Result<u32, ParseError> { 4075 let (paren_start, paren_end) = self.expect_one(&Token::LeftParen)?; 4076 let target = self.expect_target(SrcSpan::new(paren_start, paren_end))?; 4077 if attributes.target.is_some() { 4078 return parse_error(ParseErrorType::DuplicateAttribute, SrcSpan { start, end }); 4079 } 4080 let (_, end) = self.expect_one(&Token::RightParen)?; 4081 if attributes.target.is_some() { 4082 return parse_error(ParseErrorType::DuplicateAttribute, SrcSpan { start, end }); 4083 } 4084 attributes.target = Some(target); 4085 Ok(end) 4086 } 4087 4088 fn parse_external_attribute( 4089 &mut self, 4090 start: u32, 4091 end: u32, 4092 attributes: &mut Attributes, 4093 ) -> Result<u32, ParseError> { 4094 let (_, name, _) = self.expect_name()?; 4095 4096 let target = match name.as_str() { 4097 "erlang" => Target::Erlang, 4098 "javascript" => Target::JavaScript, 4099 _ => return parse_error(ParseErrorType::UnknownTarget, SrcSpan::new(start, end)), 4100 }; 4101 4102 let _ = self.expect_one(&Token::Comma)?; 4103 let (_, module, _) = self.expect_string()?; 4104 let _ = self.expect_one(&Token::Comma)?; 4105 let (_, function, _) = self.expect_string()?; 4106 let _ = self.maybe_one(&Token::Comma); 4107 let (_, end) = self.expect_one(&Token::RightParen)?; 4108 4109 if attributes.has_external_for(target) { 4110 return parse_error(ParseErrorType::DuplicateAttribute, SrcSpan { start, end }); 4111 } 4112 4113 attributes.set_external_for(target, Some((module, function, SrcSpan { start, end }))); 4114 Ok(end) 4115 } 4116 4117 fn parse_deprecated_attribute( 4118 &mut self, 4119 start: u32, 4120 end: u32, 4121 attributes: &mut Attributes, 4122 ) -> Result<u32, ParseError> { 4123 if attributes.deprecated.is_deprecated() { 4124 return parse_error(ParseErrorType::DuplicateAttribute, SrcSpan::new(start, end)); 4125 } 4126 let (_, message, _) = self.expect_string().map_err(|_| ParseError { 4127 error: ParseErrorType::ExpectedDeprecationMessage, 4128 location: SrcSpan { start, end }, 4129 })?; 4130 let (_, end) = self.expect_one(&Token::RightParen)?; 4131 attributes.deprecated = Deprecation::Deprecated { message }; 4132 Ok(end) 4133 } 4134 4135 fn parse_internal_attribute( 4136 &mut self, 4137 start: u32, 4138 end: u32, 4139 attributes: &mut Attributes, 4140 ) -> Result<u32, ParseError> { 4141 match attributes.internal { 4142 // If `internal` is present that means that we have already run into 4143 // another `@internal` annotation, so it results in a `DuplicateAttribute` 4144 // error. 4145 InternalAttribute::Present(_) => { 4146 parse_error(ParseErrorType::DuplicateAttribute, SrcSpan::new(start, end)) 4147 } 4148 InternalAttribute::Missing => { 4149 attributes.internal = InternalAttribute::Present(SrcSpan::new(start, end)); 4150 Ok(end) 4151 } 4152 } 4153 } 4154} 4155 4156fn concat_pattern_variable_left_hand_side_error<T>(start: u32, end: u32) -> Result<T, ParseError> { 4157 Err(ParseError { 4158 error: ParseErrorType::ConcatPatternVariableLeftHandSide, 4159 location: SrcSpan::new(start, end), 4160 }) 4161} 4162 4163// Operator Precedence Parsing 4164// 4165// Higher number means higher precedence. 4166// All operators are left associative. 4167 4168/// Simple-Precedence-Parser, handle seeing an operator or end 4169fn handle_op<A>( 4170 next_op: Option<(Spanned, u8)>, 4171 opstack: &mut Vec<(Spanned, u8)>, 4172 estack: &mut Vec<A>, 4173 do_reduce: &impl Fn(Spanned, &mut Vec<A>), 4174) -> Option<A> { 4175 let mut next_op = next_op; 4176 loop { 4177 match (opstack.pop(), next_op.take()) { 4178 (None, None) => match estack.pop() { 4179 Some(fin) => { 4180 if estack.is_empty() { 4181 return Some(fin); 4182 } else { 4183 panic!("Expression not fully reduced.") 4184 } 4185 } 4186 _ => { 4187 return None; 4188 } 4189 }, 4190 4191 (None, Some(op)) => { 4192 opstack.push(op); 4193 break; 4194 } 4195 4196 (Some((op, _)), None) => do_reduce(op, estack), 4197 4198 (Some((opl, pl)), Some((opr, pr))) => { 4199 match pl.cmp(&pr) { 4200 // all ops are left associative 4201 Ordering::Greater | Ordering::Equal => { 4202 do_reduce(opl, estack); 4203 next_op = Some((opr, pr)); 4204 } 4205 Ordering::Less => { 4206 opstack.push((opl, pl)); 4207 opstack.push((opr, pr)); 4208 break; 4209 } 4210 } 4211 } 4212 } 4213 } 4214 None 4215} 4216 4217fn precedence(t: &Token) -> Option<u8> { 4218 if t == &Token::Pipe { 4219 return Some(6); 4220 }; 4221 tok_to_binop(t).map(|op| op.precedence()) 4222} 4223 4224fn tok_to_binop(t: &Token) -> Option<BinOp> { 4225 match t { 4226 Token::VbarVbar => Some(BinOp::Or), 4227 Token::AmperAmper => Some(BinOp::And), 4228 Token::EqualEqual => Some(BinOp::Eq), 4229 Token::NotEqual => Some(BinOp::NotEq), 4230 Token::Less => Some(BinOp::LtInt), 4231 Token::LessEqual => Some(BinOp::LtEqInt), 4232 Token::Greater => Some(BinOp::GtInt), 4233 Token::GreaterEqual => Some(BinOp::GtEqInt), 4234 Token::LessDot => Some(BinOp::LtFloat), 4235 Token::LessEqualDot => Some(BinOp::LtEqFloat), 4236 Token::GreaterDot => Some(BinOp::GtFloat), 4237 Token::GreaterEqualDot => Some(BinOp::GtEqFloat), 4238 Token::Plus => Some(BinOp::AddInt), 4239 Token::Minus => Some(BinOp::SubInt), 4240 Token::PlusDot => Some(BinOp::AddFloat), 4241 Token::MinusDot => Some(BinOp::SubFloat), 4242 Token::Percent => Some(BinOp::RemainderInt), 4243 Token::Star => Some(BinOp::MultInt), 4244 Token::StarDot => Some(BinOp::MultFloat), 4245 Token::Slash => Some(BinOp::DivInt), 4246 Token::SlashDot => Some(BinOp::DivFloat), 4247 Token::LtGt => Some(BinOp::Concatenate), 4248 _ => None, 4249 } 4250} 4251/// Simple-Precedence-Parser, perform reduction for expression 4252fn do_reduce_expression(op: Spanned, estack: &mut Vec<UntypedExpr>) { 4253 match (estack.pop(), estack.pop()) { 4254 (Some(er), Some(el)) => { 4255 let new_e = expr_op_reduction(op, el, er); 4256 estack.push(new_e); 4257 } 4258 _ => panic!("Tried to reduce without 2 expressions"), 4259 } 4260} 4261 4262/// Simple-Precedence-Parser, perform reduction for clause guard 4263fn do_reduce_clause_guard(op: Spanned, estack: &mut Vec<UntypedClauseGuard>) { 4264 match (estack.pop(), estack.pop()) { 4265 (Some(er), Some(el)) => { 4266 let new_e = clause_guard_reduction(op, el, er); 4267 estack.push(new_e); 4268 } 4269 _ => panic!("Tried to reduce without 2 guards"), 4270 } 4271} 4272 4273fn expr_op_reduction( 4274 (token_start, token, token_end): Spanned, 4275 l: UntypedExpr, 4276 r: UntypedExpr, 4277) -> UntypedExpr { 4278 if token == Token::Pipe { 4279 let expressions = match l { 4280 UntypedExpr::PipeLine { mut expressions } => { 4281 expressions.push(r); 4282 expressions 4283 } 4284 _ => { 4285 vec1![l, r] 4286 } 4287 }; 4288 UntypedExpr::PipeLine { expressions } 4289 } else { 4290 match tok_to_binop(&token) { 4291 Some(bin_op) => UntypedExpr::BinOp { 4292 location: SrcSpan { 4293 start: l.location().start, 4294 end: r.location().end, 4295 }, 4296 name: bin_op, 4297 name_location: SrcSpan { 4298 start: token_start, 4299 end: token_end, 4300 }, 4301 left: Box::new(l), 4302 right: Box::new(r), 4303 }, 4304 _ => { 4305 panic!("Token could not be converted to binop.") 4306 } 4307 } 4308 } 4309} 4310 4311fn clause_guard_reduction( 4312 (_, token, _): Spanned, 4313 l: UntypedClauseGuard, 4314 r: UntypedClauseGuard, 4315) -> UntypedClauseGuard { 4316 let location = SrcSpan { 4317 start: l.location().start, 4318 end: r.location().end, 4319 }; 4320 let left = Box::new(l); 4321 let right = Box::new(r); 4322 match token { 4323 Token::VbarVbar => ClauseGuard::Or { 4324 location, 4325 left, 4326 right, 4327 }, 4328 4329 Token::AmperAmper => ClauseGuard::And { 4330 location, 4331 left, 4332 right, 4333 }, 4334 4335 Token::EqualEqual => ClauseGuard::Equals { 4336 location, 4337 left, 4338 right, 4339 }, 4340 4341 Token::NotEqual => ClauseGuard::NotEquals { 4342 location, 4343 left, 4344 right, 4345 }, 4346 4347 Token::Greater => ClauseGuard::GtInt { 4348 location, 4349 left, 4350 right, 4351 }, 4352 4353 Token::GreaterEqual => ClauseGuard::GtEqInt { 4354 location, 4355 left, 4356 right, 4357 }, 4358 4359 Token::Less => ClauseGuard::LtInt { 4360 location, 4361 left, 4362 right, 4363 }, 4364 4365 Token::LessEqual => ClauseGuard::LtEqInt { 4366 location, 4367 left, 4368 right, 4369 }, 4370 4371 Token::GreaterDot => ClauseGuard::GtFloat { 4372 location, 4373 left, 4374 right, 4375 }, 4376 4377 Token::GreaterEqualDot => ClauseGuard::GtEqFloat { 4378 location, 4379 left, 4380 right, 4381 }, 4382 4383 Token::LessDot => ClauseGuard::LtFloat { 4384 location, 4385 left, 4386 right, 4387 }, 4388 4389 Token::LessEqualDot => ClauseGuard::LtEqFloat { 4390 location, 4391 left, 4392 right, 4393 }, 4394 4395 Token::Plus => ClauseGuard::AddInt { 4396 location, 4397 left, 4398 right, 4399 }, 4400 4401 Token::PlusDot => ClauseGuard::AddFloat { 4402 location, 4403 left, 4404 right, 4405 }, 4406 4407 Token::Minus => ClauseGuard::SubInt { 4408 location, 4409 left, 4410 right, 4411 }, 4412 4413 Token::MinusDot => ClauseGuard::SubFloat { 4414 location, 4415 left, 4416 right, 4417 }, 4418 4419 Token::Star => ClauseGuard::MultInt { 4420 location, 4421 left, 4422 right, 4423 }, 4424 4425 Token::StarDot => ClauseGuard::MultFloat { 4426 location, 4427 left, 4428 right, 4429 }, 4430 4431 Token::Slash => ClauseGuard::DivInt { 4432 location, 4433 left, 4434 right, 4435 }, 4436 4437 Token::SlashDot => ClauseGuard::DivFloat { 4438 location, 4439 left, 4440 right, 4441 }, 4442 4443 Token::Percent => ClauseGuard::RemainderInt { 4444 location, 4445 left, 4446 right, 4447 }, 4448 4449 _ => panic!("Token could not be converted to Guard Op."), 4450 } 4451} 4452 4453// BitArray Parse Helpers 4454// 4455// BitArrays in patterns, guards, and expressions have a very similar structure 4456// but need specific types. These are helpers for that. There is probably a 4457// rustier way to do this :) 4458fn bit_array_size_int(value: EcoString, int_value: BigInt, start: u32, end: u32) -> UntypedPattern { 4459 Pattern::BitArraySize(BitArraySize::Int { 4460 location: SrcSpan { start, end }, 4461 value, 4462 int_value, 4463 }) 4464} 4465 4466fn bit_array_expr_int(value: EcoString, int_value: BigInt, start: u32, end: u32) -> UntypedExpr { 4467 UntypedExpr::Int { 4468 location: SrcSpan { start, end }, 4469 value, 4470 int_value, 4471 } 4472} 4473 4474fn bit_array_const_int( 4475 value: EcoString, 4476 int_value: BigInt, 4477 start: u32, 4478 end: u32, 4479) -> UntypedConstant { 4480 Constant::Int { 4481 location: SrcSpan { start, end }, 4482 value, 4483 int_value, 4484 } 4485} 4486 4487fn str_to_bit_array_option<A>(lit: &str, location: SrcSpan) -> Option<BitArrayOption<A>> { 4488 match lit { 4489 "bytes" => Some(BitArrayOption::Bytes { location }), 4490 "int" => Some(BitArrayOption::Int { location }), 4491 "float" => Some(BitArrayOption::Float { location }), 4492 "bits" => Some(BitArrayOption::Bits { location }), 4493 "utf8" => Some(BitArrayOption::Utf8 { location }), 4494 "utf16" => Some(BitArrayOption::Utf16 { location }), 4495 "utf32" => Some(BitArrayOption::Utf32 { location }), 4496 "utf8_codepoint" => Some(BitArrayOption::Utf8Codepoint { location }), 4497 "utf16_codepoint" => Some(BitArrayOption::Utf16Codepoint { location }), 4498 "utf32_codepoint" => Some(BitArrayOption::Utf32Codepoint { location }), 4499 "signed" => Some(BitArrayOption::Signed { location }), 4500 "unsigned" => Some(BitArrayOption::Unsigned { location }), 4501 "big" => Some(BitArrayOption::Big { location }), 4502 "little" => Some(BitArrayOption::Little { location }), 4503 "native" => Some(BitArrayOption::Native { location }), 4504 _ => None, 4505 } 4506} 4507 4508// 4509// Error Helpers 4510// 4511fn parse_error<T>(error: ParseErrorType, location: SrcSpan) -> Result<T, ParseError> { 4512 Err(ParseError { error, location }) 4513} 4514 4515// 4516// Misc Helpers 4517// 4518 4519// Parsing a function call into the appropriate structure 4520#[derive(Debug)] 4521pub enum ParserArg { 4522 Arg(Box<CallArg<UntypedExpr>>), 4523 Hole { 4524 name: EcoString, 4525 /// The whole span of the argument. 4526 arg_location: SrcSpan, 4527 /// Just the span of the ignore name. 4528 discard_location: SrcSpan, 4529 label: Option<EcoString>, 4530 }, 4531} 4532 4533pub fn make_call( 4534 fun: UntypedExpr, 4535 arguments: Vec<ParserArg>, 4536 start: u32, 4537 end: u32, 4538) -> Result<UntypedExpr, ParseError> { 4539 let mut hole_location = None; 4540 4541 let arguments = arguments 4542 .into_iter() 4543 .map(|argument| match argument { 4544 ParserArg::Arg(arg) => Ok(*arg), 4545 ParserArg::Hole { 4546 arg_location, 4547 discard_location, 4548 name, 4549 label, 4550 } => { 4551 if hole_location.is_some() { 4552 return parse_error(ParseErrorType::TooManyArgHoles, SrcSpan { start, end }); 4553 } 4554 4555 hole_location = Some(discard_location); 4556 if name != "_" { 4557 return parse_error( 4558 ParseErrorType::UnexpectedToken { 4559 token: Token::Name { name }, 4560 expected: vec!["An expression".into(), "An underscore".into()], 4561 hint: None, 4562 }, 4563 arg_location, 4564 ); 4565 } 4566 4567 Ok(CallArg { 4568 implicit: None, 4569 label, 4570 location: arg_location, 4571 value: UntypedExpr::Var { 4572 location: discard_location, 4573 name: CAPTURE_VARIABLE.into(), 4574 }, 4575 }) 4576 } 4577 }) 4578 .collect::<Result<_, _>>()?; 4579 4580 let call = UntypedExpr::Call { 4581 location: SrcSpan { start, end }, 4582 fun: Box::new(fun), 4583 arguments, 4584 }; 4585 4586 match hole_location { 4587 // A normal call 4588 None => Ok(call), 4589 4590 // An anon function using the capture syntax run(_, 1, 2) 4591 Some(hole_location) => Ok(UntypedExpr::Fn { 4592 location: call.location(), 4593 end_of_head_byte_index: call.location().end, 4594 kind: FunctionLiteralKind::Capture { 4595 hole: hole_location, 4596 }, 4597 arguments: vec![Arg { 4598 location: hole_location, 4599 annotation: None, 4600 names: ArgNames::Named { 4601 name: CAPTURE_VARIABLE.into(), 4602 location: hole_location, 4603 }, 4604 type_: (), 4605 }], 4606 body: vec1![Statement::Expression(call)], 4607 return_annotation: None, 4608 }), 4609 } 4610} 4611 4612#[derive(Debug, Default)] 4613struct ParsedUnqualifiedImports { 4614 types: Vec<UnqualifiedImport>, 4615 values: Vec<UnqualifiedImport>, 4616} 4617 4618/// Parses an Int value to a bigint. 4619/// 4620pub fn parse_int_value(value: &str) -> Option<BigInt> { 4621 let (radix, value) = if let Some(value) = value.strip_prefix("0x") { 4622 (16, value) 4623 } else if let Some(value) = value.strip_prefix("0o") { 4624 (8, value) 4625 } else if let Some(value) = value.strip_prefix("0b") { 4626 (2, value) 4627 } else { 4628 (10, value) 4629 }; 4630 4631 let value = value.trim_start_matches('_'); 4632 4633 BigInt::parse_bytes(value.as_bytes(), radix) 4634} 4635 4636#[derive(Debug, PartialEq, Clone, Copy)] 4637enum ExpressionUnitContext { 4638 FollowingPipe, 4639 Other, 4640} 4641 4642#[derive(Debug, Clone, Copy)] 4643pub enum PatternPosition { 4644 LetAssignment, 4645 CaseClause, 4646 UsePattern, 4647} 4648 4649impl PatternPosition { 4650 pub fn to_declaration(&self) -> VariableDeclaration { 4651 match self { 4652 PatternPosition::LetAssignment => VariableDeclaration::LetPattern, 4653 PatternPosition::CaseClause => VariableDeclaration::ClausePattern, 4654 PatternPosition::UsePattern => VariableDeclaration::UsePattern, 4655 } 4656 } 4657}