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

Configure Feed

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

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