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