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