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