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