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