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
175 kB 4810 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, SrcSpan, Statement, TailPattern, TargetedDefinition, TodoKind, TypeAlias, 65 TypeAst, TypeAstConstructor, TypeAstFn, TypeAstHole, TypeAstTuple, TypeAstVar, 66 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::LtGt, _)) = 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::LtGt, _)) = 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::LtGt, _)) => { 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::LtGt, _)) => { 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 }, 1809 }; 1810 1811 loop { 1812 let dot_s = match self.maybe_one(&Token::Dot) { 1813 Some((dot_s, _)) => dot_s, 1814 None => return Ok(Some(unit)), 1815 }; 1816 1817 match self.next_tok() { 1818 Some(( 1819 _, 1820 Token::Int { 1821 value, 1822 int_value: _, 1823 }, 1824 int_e, 1825 )) => { 1826 let v = value.replace("_", ""); 1827 match u64::from_str(&v) { 1828 Ok(index) => { 1829 unit = ClauseGuard::TupleIndex { 1830 location: SrcSpan { 1831 start: dot_s, 1832 end: int_e, 1833 }, 1834 index, 1835 type_: (), 1836 tuple: Box::new(unit), 1837 }; 1838 } 1839 _ => { 1840 return parse_error( 1841 ParseErrorType::InvalidTupleAccess, 1842 SrcSpan { start, end }, 1843 ); 1844 } 1845 } 1846 } 1847 1848 Some((name_start, Token::Name { name: label }, name_end)) => { 1849 self.parse_function_call_in_clause_guard(start)?; 1850 1851 unit = ClauseGuard::FieldAccess { 1852 label_location: SrcSpan { 1853 start: name_start, 1854 end: name_end, 1855 }, 1856 index: None, 1857 label, 1858 type_: (), 1859 container: Box::new(unit), 1860 }; 1861 } 1862 1863 Some((start, _, end)) => { 1864 return parse_error( 1865 ParseErrorType::IncorrectName, 1866 SrcSpan { start, end }, 1867 ); 1868 } 1869 1870 _ => return self.next_tok_unexpected(vec!["A positive integer".into()]), 1871 } 1872 } 1873 } 1874 1875 Some((start, Token::LeftBrace, _)) => { 1876 self.advance(); 1877 Ok(Some(self.parse_case_clause_guard_block(start)?)) 1878 } 1879 1880 t0 => { 1881 self.tok0 = t0; 1882 match self.parse_const_value()? { 1883 Some(const_val) => { 1884 // Constant 1885 Ok(Some(ClauseGuard::Constant(const_val))) 1886 } 1887 _ => Ok(None), 1888 } 1889 } 1890 } 1891 } 1892 1893 fn parse_case_clause_guard_block( 1894 &mut self, 1895 start: u32, 1896 ) -> Result<UntypedClauseGuard, ParseError> { 1897 let body = self.parse_clause_guard_inner()?; 1898 1899 let Some(body) = body else { 1900 let location = match self.next_tok() { 1901 Some((_, Token::RightBrace, end)) => SrcSpan { start, end }, 1902 Some((_, _, _)) | None => SrcSpan { 1903 start, 1904 end: start + 1, 1905 }, 1906 }; 1907 1908 return parse_error(ParseErrorType::EmptyGuardBlock, location); 1909 }; 1910 1911 let (_, end) = self.expect_one(&Token::RightBrace)?; 1912 Ok(ClauseGuard::Block { 1913 location: SrcSpan { start, end }, 1914 value: Box::new(body), 1915 }) 1916 } 1917 1918 fn parse_record_in_clause_guard( 1919 &mut self, 1920 module: &EcoString, 1921 module_location: SrcSpan, 1922 ) -> Result<Option<UntypedClauseGuard>, ParseError> { 1923 let (name, end) = match (self.tok0.take(), self.peek_tok1()) { 1924 (Some((_, Token::Dot, _)), Some(Token::UpName { .. })) => { 1925 self.advance(); // dot 1926 let Some((_, Token::UpName { name }, end)) = self.next_tok() else { 1927 return Ok(None); 1928 }; 1929 (name, end) 1930 } 1931 (tok0, _) => { 1932 self.tok0 = tok0; 1933 return Ok(None); 1934 } 1935 }; 1936 1937 match self.parse_const_record_finish( 1938 module_location.start, 1939 Some((module.clone(), module_location)), 1940 name, 1941 end, 1942 )? { 1943 Some(record) => Ok(Some(ClauseGuard::Constant(record))), 1944 _ => Ok(None), 1945 } 1946 } 1947 1948 // examples: 1949 // UpName( args ) 1950 fn expect_constructor_pattern( 1951 &mut self, 1952 module: Option<(u32, EcoString, u32)>, 1953 position: PatternPosition, 1954 ) -> Result<UntypedPattern, ParseError> { 1955 let (name_start, name, name_end) = self.expect_upname()?; 1956 let mut start = name_start; 1957 let (arguments, spread, end) = 1958 self.parse_constructor_pattern_arguments(name_end, position)?; 1959 if let Some((s, _, _)) = module { 1960 start = s; 1961 } 1962 Ok(Pattern::Constructor { 1963 location: SrcSpan { start, end }, 1964 name_location: SrcSpan::new(name_start, name_end), 1965 arguments, 1966 module: module.map(|(start, n, end)| (n, SrcSpan { start, end })), 1967 name, 1968 spread, 1969 constructor: Inferred::Unknown, 1970 type_: (), 1971 }) 1972 } 1973 1974 // examples: 1975 // ( args ) 1976 #[allow(clippy::type_complexity)] 1977 fn parse_constructor_pattern_arguments( 1978 &mut self, 1979 upname_end: u32, 1980 position: PatternPosition, 1981 ) -> Result<(Vec<CallArg<UntypedPattern>>, Option<SrcSpan>, u32), ParseError> { 1982 if self.maybe_one(&Token::LeftParen).is_some() { 1983 let (arguments, arguments_end_with_comma) = self.series_of_has_trailing_separator( 1984 &|this| this.parse_constructor_pattern_arg(position), 1985 Some(&Token::Comma), 1986 )?; 1987 1988 let spread = self 1989 .maybe_one(&Token::DotDot) 1990 .map(|(start, end)| SrcSpan { start, end }); 1991 1992 if let Some(spread_location) = spread { 1993 let _ = self.maybe_one(&Token::Comma); 1994 if !arguments.is_empty() && !arguments_end_with_comma { 1995 self.warnings 1996 .push(DeprecatedSyntaxWarning::DeprecatedRecordSpreadPattern { 1997 location: spread_location, 1998 }) 1999 } 2000 } 2001 let (_, end) = self.expect_one(&Token::RightParen)?; 2002 Ok((arguments, spread, end)) 2003 } else { 2004 Ok((vec![], None, upname_end)) 2005 } 2006 } 2007 2008 // examples: 2009 // a: <pattern> 2010 // a: 2011 // <pattern> 2012 fn parse_constructor_pattern_arg( 2013 &mut self, 2014 position: PatternPosition, 2015 ) -> Result<Option<CallArg<UntypedPattern>>, ParseError> { 2016 match (self.tok0.take(), self.tok1.take()) { 2017 // named arg 2018 (Some((start, Token::Name { name }, _)), Some((_, Token::Colon, end))) => { 2019 self.advance(); 2020 self.advance(); 2021 match self.parse_pattern(position)? { 2022 Some(value) => Ok(Some(CallArg { 2023 implicit: None, 2024 location: SrcSpan { 2025 start, 2026 end: value.location().end, 2027 }, 2028 label: Some(name), 2029 value, 2030 })), 2031 _ => { 2032 // Argument supplied with a label shorthand. 2033 Ok(Some(CallArg { 2034 implicit: None, 2035 location: SrcSpan { start, end }, 2036 label: Some(name.clone()), 2037 value: UntypedPattern::Variable { 2038 origin: VariableOrigin { 2039 syntax: VariableSyntax::LabelShorthand(name.clone()), 2040 declaration: position.to_declaration(), 2041 }, 2042 name, 2043 location: SrcSpan { start, end }, 2044 type_: (), 2045 }, 2046 })) 2047 } 2048 } 2049 } 2050 // unnamed arg 2051 (t0, t1) => { 2052 self.tok0 = t0; 2053 self.tok1 = t1; 2054 match self.parse_pattern(position)? { 2055 Some(value) => Ok(Some(CallArg { 2056 implicit: None, 2057 location: value.location(), 2058 label: None, 2059 value, 2060 })), 2061 _ => Ok(None), 2062 } 2063 } 2064 } 2065 } 2066 2067 // examples: 2068 // a: expr 2069 // a: 2070 fn parse_record_update_arg(&mut self) -> Result<Option<UntypedRecordUpdateArg>, ParseError> { 2071 match self.maybe_name() { 2072 Some((start, label, _)) => { 2073 let (_, end) = self.expect_one(&Token::Colon)?; 2074 let value = self.parse_expression()?; 2075 match value { 2076 Some(value) => Ok(Some(UntypedRecordUpdateArg { 2077 label, 2078 location: SrcSpan { 2079 start, 2080 end: value.location().end, 2081 }, 2082 value, 2083 })), 2084 _ => { 2085 // Argument supplied with a label shorthand. 2086 Ok(Some(UntypedRecordUpdateArg { 2087 label: label.clone(), 2088 location: SrcSpan { start, end }, 2089 value: UntypedExpr::Var { 2090 name: label, 2091 location: SrcSpan { start, end }, 2092 }, 2093 })) 2094 } 2095 } 2096 } 2097 _ => Ok(None), 2098 } 2099 } 2100 2101 // 2102 // Parse Functions 2103 // 2104 2105 // Starts after "fn" 2106 // 2107 // examples: 2108 // fn a(name: String) -> String { .. } 2109 // pub fn a(name name: String) -> String { .. } 2110 fn parse_function( 2111 &mut self, 2112 start: u32, 2113 public: bool, 2114 is_anon: bool, 2115 attributes: &mut Attributes, 2116 ) -> Result<Option<UntypedDefinition>, ParseError> { 2117 let documentation = if is_anon { 2118 None 2119 } else { 2120 self.take_documentation(start) 2121 }; 2122 let mut name = None; 2123 if !is_anon { 2124 let (name_start, n, name_end) = self.expect_name()?; 2125 name = Some(( 2126 SrcSpan { 2127 start: name_start, 2128 end: name_end, 2129 }, 2130 n, 2131 )); 2132 } 2133 if let Some((less_start, less_end)) = self.maybe_one(&Token::Less) { 2134 return Err(ParseError { 2135 error: ParseErrorType::FunctionDefinitionAngleGenerics, 2136 location: SrcSpan { 2137 start: less_start, 2138 end: less_end, 2139 }, 2140 }); 2141 } 2142 let _ = self 2143 .expect_one(&Token::LeftParen) 2144 .map_err(|e| self.add_anon_function_hint(e))?; 2145 let arguments = Parser::series_of( 2146 self, 2147 &|parser| Parser::parse_fn_param(parser, is_anon), 2148 Some(&Token::Comma), 2149 )?; 2150 let (_, rpar_e) = 2151 self.expect_one_following_series(&Token::RightParen, "a function parameter")?; 2152 let return_annotation = self.parse_type_annotation(&Token::RArrow)?; 2153 2154 let (body_start, body, end, end_position) = match self.maybe_one(&Token::LeftBrace) { 2155 Some((left_brace_start, _)) => { 2156 let some_body = self.parse_statement_seq()?; 2157 let (_, right_brace_end) = self.expect_one(&Token::RightBrace)?; 2158 let end = return_annotation 2159 .as_ref() 2160 .map(|l| l.location().end) 2161 .unwrap_or(rpar_e); 2162 let body = match some_body { 2163 None => vec![Statement::Expression(UntypedExpr::Todo { 2164 kind: TodoKind::EmptyFunction { 2165 function_location: SrcSpan { start, end }, 2166 }, 2167 location: SrcSpan { 2168 start: left_brace_start + 1, 2169 end: right_brace_end, 2170 }, 2171 message: None, 2172 })], 2173 Some((body, _)) => body.to_vec(), 2174 }; 2175 2176 (Some(left_brace_start), body, end, right_brace_end) 2177 } 2178 2179 None => (None, vec![], rpar_e, rpar_e), 2180 }; 2181 2182 Ok(Some(Definition::Function(Function { 2183 documentation, 2184 location: SrcSpan { start, end }, 2185 end_position, 2186 body_start, 2187 publicity: self.publicity(public, attributes.internal)?, 2188 name, 2189 arguments, 2190 body, 2191 return_type: (), 2192 return_annotation, 2193 deprecation: std::mem::take(&mut attributes.deprecated), 2194 external_erlang: attributes.external_erlang.take(), 2195 external_javascript: attributes.external_javascript.take(), 2196 implementations: Implementations { 2197 gleam: true, 2198 can_run_on_erlang: true, 2199 can_run_on_javascript: true, 2200 uses_erlang_externals: false, 2201 uses_javascript_externals: false, 2202 }, 2203 purity: Purity::Pure, 2204 }))) 2205 } 2206 2207 fn add_anon_function_hint(&self, mut err: ParseError) -> ParseError { 2208 if let ParseErrorType::UnexpectedToken { 2209 ref mut hint, 2210 token: Token::Name { .. }, 2211 .. 2212 } = err.error 2213 { 2214 *hint = Some("Only module-level functions can be named.".into()); 2215 } 2216 err 2217 } 2218 2219 fn publicity( 2220 &self, 2221 public: bool, 2222 internal: InternalAttribute, 2223 ) -> Result<Publicity, ParseError> { 2224 match (internal, public) { 2225 (InternalAttribute::Missing, true) => Ok(Publicity::Public), 2226 (InternalAttribute::Missing, false) => Ok(Publicity::Private), 2227 (InternalAttribute::Present(location), true) => Ok(Publicity::Internal { 2228 attribute_location: Some(location), 2229 }), 2230 (InternalAttribute::Present(location), false) => Err(ParseError { 2231 error: ParseErrorType::RedundantInternalAttribute, 2232 location, 2233 }), 2234 } 2235 } 2236 2237 // Parse a single function definition param 2238 // 2239 // examples: 2240 // _ 2241 // a 2242 // a a 2243 // a _ 2244 // a _:A 2245 // a a:A 2246 fn parse_fn_param(&mut self, is_anon: bool) -> Result<Option<UntypedArg>, ParseError> { 2247 let (start, names, mut end) = match (self.tok0.take(), self.tok1.take()) { 2248 // labeled discard 2249 ( 2250 Some((start, Token::Name { name: label }, tok0_end)), 2251 Some((name_start, Token::DiscardName { name }, end)), 2252 ) => { 2253 if is_anon { 2254 return parse_error( 2255 ParseErrorType::UnexpectedLabel, 2256 SrcSpan { 2257 start, 2258 end: tok0_end, 2259 }, 2260 ); 2261 } 2262 2263 self.advance(); 2264 self.advance(); 2265 ( 2266 start, 2267 ArgNames::LabelledDiscard { 2268 name, 2269 name_location: SrcSpan::new(name_start, end), 2270 label, 2271 label_location: SrcSpan::new(start, tok0_end), 2272 }, 2273 end, 2274 ) 2275 } 2276 // discard 2277 (Some((start, Token::DiscardName { name }, end)), t1) => { 2278 self.tok1 = t1; 2279 self.advance(); 2280 ( 2281 start, 2282 ArgNames::Discard { 2283 name, 2284 location: SrcSpan { start, end }, 2285 }, 2286 end, 2287 ) 2288 } 2289 // labeled name 2290 ( 2291 Some((start, Token::Name { name: label }, tok0_end)), 2292 Some((name_start, Token::Name { name }, end)), 2293 ) => { 2294 if is_anon { 2295 return parse_error( 2296 ParseErrorType::UnexpectedLabel, 2297 SrcSpan { 2298 start, 2299 end: tok0_end, 2300 }, 2301 ); 2302 } 2303 2304 self.advance(); 2305 self.advance(); 2306 ( 2307 start, 2308 ArgNames::NamedLabelled { 2309 name, 2310 name_location: SrcSpan::new(name_start, end), 2311 label, 2312 label_location: SrcSpan::new(start, tok0_end), 2313 }, 2314 end, 2315 ) 2316 } 2317 // name 2318 (Some((start, Token::Name { name }, end)), t1) => { 2319 self.tok1 = t1; 2320 self.advance(); 2321 ( 2322 start, 2323 ArgNames::Named { 2324 name, 2325 location: SrcSpan { start, end }, 2326 }, 2327 end, 2328 ) 2329 } 2330 (t0, t1) => { 2331 self.tok0 = t0; 2332 self.tok1 = t1; 2333 return Ok(None); 2334 } 2335 }; 2336 let annotation = match self.parse_type_annotation(&Token::Colon)? { 2337 Some(a) => { 2338 end = a.location().end; 2339 Some(a) 2340 } 2341 _ => None, 2342 }; 2343 Ok(Some(Arg { 2344 location: SrcSpan { start, end }, 2345 type_: (), 2346 names, 2347 annotation, 2348 })) 2349 } 2350 2351 // Parse function call arguments, no parens 2352 // 2353 // examples: 2354 // _ 2355 // expr, expr 2356 // a: _, expr 2357 // a: expr, _, b: _ 2358 fn parse_fn_arguments(&mut self) -> Result<Vec<ParserArg>, ParseError> { 2359 let arguments = Parser::series_of(self, &Parser::parse_fn_argument, Some(&Token::Comma))?; 2360 Ok(arguments) 2361 } 2362 2363 // Parse a single function call arg 2364 // 2365 // examples: 2366 // _ 2367 // expr 2368 // a: _ 2369 // a: expr 2370 fn parse_fn_argument(&mut self) -> Result<Option<ParserArg>, ParseError> { 2371 let label = match (self.tok0.take(), self.tok1.take()) { 2372 (Some((start, Token::Name { name }, _)), Some((_, Token::Colon, end))) => { 2373 self.advance(); 2374 self.advance(); 2375 Some((start, name, end)) 2376 } 2377 (t0, t1) => { 2378 self.tok0 = t0; 2379 self.tok1 = t1; 2380 None 2381 } 2382 }; 2383 2384 match self.parse_expression()? { 2385 Some(value) => { 2386 let arg = match label { 2387 Some((start, label, _)) => CallArg { 2388 implicit: None, 2389 label: Some(label), 2390 location: SrcSpan { 2391 start, 2392 end: value.location().end, 2393 }, 2394 value, 2395 }, 2396 _ => CallArg { 2397 implicit: None, 2398 label: None, 2399 location: value.location(), 2400 value, 2401 }, 2402 }; 2403 Ok(Some(ParserArg::Arg(Box::new(arg)))) 2404 } 2405 _ => { 2406 match self.maybe_discard_name() { 2407 Some((name_start, name, name_end)) => { 2408 let arg = match label { 2409 Some((label_start, label, _)) => ParserArg::Hole { 2410 label: Some(label), 2411 arg_location: SrcSpan { 2412 start: label_start, 2413 end: name_end, 2414 }, 2415 discard_location: SrcSpan { 2416 start: name_start, 2417 end: name_end, 2418 }, 2419 name, 2420 }, 2421 _ => ParserArg::Hole { 2422 label: None, 2423 arg_location: SrcSpan { 2424 start: name_start, 2425 end: name_end, 2426 }, 2427 discard_location: SrcSpan { 2428 start: name_start, 2429 end: name_end, 2430 }, 2431 name, 2432 }, 2433 }; 2434 2435 Ok(Some(arg)) 2436 } 2437 _ => { 2438 match label { 2439 Some((start, label, end)) => { 2440 // Argument supplied with a label shorthand. 2441 Ok(Some(ParserArg::Arg(Box::new(CallArg { 2442 implicit: None, 2443 label: Some(label.clone()), 2444 location: SrcSpan { start, end }, 2445 value: UntypedExpr::Var { 2446 name: label, 2447 location: SrcSpan { start, end }, 2448 }, 2449 })))) 2450 } 2451 _ => Ok(None), 2452 } 2453 } 2454 } 2455 } 2456 } 2457 } 2458 2459 // 2460 // Parse Custom Types 2461 // 2462 2463 // examples: 2464 // type A { A } 2465 // type A { A(String) } 2466 // type Box(inner_type) { Box(inner: inner_type) } 2467 // type NamedBox(inner_type) { Box(String, inner: inner_type) } 2468 fn parse_custom_type( 2469 &mut self, 2470 start: u32, 2471 public: bool, 2472 opaque: bool, 2473 attributes: &mut Attributes, 2474 ) -> Result<Option<UntypedDefinition>, ParseError> { 2475 let documentation = self.take_documentation(start); 2476 let (name_start, name, parameters, end, name_end) = self.expect_type_name()?; 2477 let name_location = SrcSpan::new(name_start, name_end); 2478 let (constructors, end_position) = if self.maybe_one(&Token::LeftBrace).is_some() { 2479 // Custom Type 2480 let constructors = Parser::series_of( 2481 self, 2482 &|p| { 2483 // The only attribute supported on constructors is @deprecated 2484 let mut attributes = Attributes::default(); 2485 let attr_loc = Parser::parse_attributes(p, &mut attributes)?; 2486 2487 if let Some(attr_span) = attr_loc { 2488 // Expecting all but the deprecated atterbutes to be default 2489 if attributes.external_erlang.is_some() 2490 || attributes.external_javascript.is_some() 2491 || attributes.target.is_some() 2492 || attributes.internal != InternalAttribute::Missing 2493 { 2494 return parse_error( 2495 ParseErrorType::UnknownAttributeRecordVariant, 2496 attr_span, 2497 ); 2498 } 2499 } 2500 2501 match Parser::maybe_upname(p) { 2502 Some((c_s, c_n, c_e)) => { 2503 let documentation = p.take_documentation(c_s); 2504 let (arguments, arguments_e) = 2505 Parser::parse_type_constructor_arguments(p)?; 2506 let end = arguments_e.max(c_e); 2507 Ok(Some(RecordConstructor { 2508 location: SrcSpan { start: c_s, end }, 2509 name_location: SrcSpan { 2510 start: c_s, 2511 end: c_e, 2512 }, 2513 name: c_n, 2514 arguments, 2515 documentation, 2516 deprecation: attributes.deprecated, 2517 })) 2518 } 2519 _ => Ok(None), 2520 } 2521 }, 2522 // No separator 2523 None, 2524 )?; 2525 let (_, close_end) = self.expect_custom_type_close(&name, public, opaque)?; 2526 (constructors, close_end) 2527 } else { 2528 match self.maybe_one(&Token::Equal) { 2529 Some((eq_s, eq_e)) => { 2530 // Type Alias 2531 if opaque { 2532 return parse_error( 2533 ParseErrorType::OpaqueTypeAlias, 2534 SrcSpan { start, end }, 2535 ); 2536 } 2537 2538 match self.parse_type()? { 2539 Some(t) => { 2540 let type_end = t.location().end; 2541 return Ok(Some(Definition::TypeAlias(TypeAlias { 2542 documentation, 2543 location: SrcSpan::new(start, type_end), 2544 publicity: self.publicity(public, attributes.internal)?, 2545 alias: name, 2546 name_location, 2547 parameters, 2548 type_ast: t, 2549 type_: (), 2550 deprecation: std::mem::take(&mut attributes.deprecated), 2551 }))); 2552 } 2553 _ => { 2554 return parse_error( 2555 ParseErrorType::ExpectedType, 2556 SrcSpan::new(eq_s, eq_e), 2557 ); 2558 } 2559 } 2560 } 2561 _ => (vec![], end), 2562 } 2563 }; 2564 2565 Ok(Some(Definition::CustomType(CustomType { 2566 documentation, 2567 location: SrcSpan { start, end }, 2568 end_position, 2569 publicity: self.publicity(public, attributes.internal)?, 2570 opaque, 2571 name, 2572 name_location, 2573 parameters, 2574 constructors, 2575 typed_parameters: vec![], 2576 deprecation: std::mem::take(&mut attributes.deprecated), 2577 external_erlang: std::mem::take(&mut attributes.external_erlang), 2578 external_javascript: std::mem::take(&mut attributes.external_javascript), 2579 }))) 2580 } 2581 2582 // examples: 2583 // A 2584 // A(one, two) 2585 fn expect_type_name( 2586 &mut self, 2587 ) -> Result<(u32, EcoString, Vec<SpannedString>, u32, u32), ParseError> { 2588 let (start, upname, end) = self.expect_upname()?; 2589 if let Some((par_s, _)) = self.maybe_one(&Token::LeftParen) { 2590 let arguments = 2591 Parser::series_of(self, &|p| Ok(Parser::maybe_name(p)), Some(&Token::Comma))?; 2592 let (_, par_e) = self.expect_one_following_series(&Token::RightParen, "a name")?; 2593 if arguments.is_empty() { 2594 return parse_error( 2595 ParseErrorType::TypeDefinitionNoArguments, 2596 SrcSpan::new(par_s, par_e), 2597 ); 2598 } 2599 let arguments2 = arguments 2600 .into_iter() 2601 .map(|(start, name, end)| (SrcSpan { start, end }, name)) 2602 .collect(); 2603 Ok((start, upname, arguments2, par_e, end)) 2604 } else if let Some((less_start, less_end)) = self.maybe_one(&Token::Less) { 2605 let mut arguments = Parser::series_of( 2606 self, 2607 &|p| 2608 // Permit either names (`a`) or upnames (`A`) in this error-handling mode, 2609 // as upnames are common in other languages. Convert to lowercase so the 2610 // example is correct whichever was used. 2611 Ok(Parser::maybe_name(p) 2612 .or_else(|| Parser::maybe_upname(p)) 2613 .map(|(_, name, _)| name.to_lowercase())), 2614 Some(&Token::Comma), 2615 )?; 2616 2617 // If no type arguments were parsed, fall back to a dummy type argument as an example, 2618 // because `Type()` would be invalid 2619 if arguments.is_empty() { 2620 arguments = vec!["value".into()]; 2621 } 2622 2623 Err(ParseError { 2624 error: ParseErrorType::TypeDefinitionAngleGenerics { 2625 name: upname, 2626 arguments, 2627 }, 2628 location: SrcSpan { 2629 start: less_start, 2630 end: less_end, 2631 }, 2632 }) 2633 } else { 2634 Ok((start, upname, vec![], end, end)) 2635 } 2636 } 2637 2638 // examples: 2639 // *no args* 2640 // () 2641 // (a, b) 2642 fn parse_type_constructor_arguments( 2643 &mut self, 2644 ) -> Result<(Vec<RecordConstructorArg<()>>, u32), ParseError> { 2645 if self.maybe_one(&Token::LeftParen).is_some() { 2646 let arguments = Parser::series_of( 2647 self, 2648 &|p| match (p.tok0.take(), p.tok1.take()) { 2649 ( 2650 Some((start, Token::Name { name }, name_end)), 2651 Some((_, Token::Colon, end)), 2652 ) => { 2653 let _ = Parser::next_tok(p); 2654 let _ = Parser::next_tok(p); 2655 let doc = p.take_documentation(start); 2656 match Parser::parse_type(p)? { 2657 Some(type_ast) => { 2658 let end = type_ast.location().end; 2659 Ok(Some(RecordConstructorArg { 2660 label: Some((SrcSpan::new(start, name_end), name)), 2661 ast: type_ast, 2662 location: SrcSpan { start, end }, 2663 type_: (), 2664 doc, 2665 })) 2666 } 2667 None => { 2668 parse_error(ParseErrorType::ExpectedType, SrcSpan { start, end }) 2669 } 2670 } 2671 } 2672 (t0, t1) => { 2673 p.tok0 = t0; 2674 p.tok1 = t1; 2675 match Parser::parse_type(p)? { 2676 Some(type_ast) => { 2677 let doc = match &p.tok0 { 2678 Some((start, _, _)) => p.take_documentation(*start), 2679 None => None, 2680 }; 2681 let type_location = type_ast.location(); 2682 Ok(Some(RecordConstructorArg { 2683 label: None, 2684 ast: type_ast, 2685 location: type_location, 2686 type_: (), 2687 doc, 2688 })) 2689 } 2690 None => Ok(None), 2691 } 2692 } 2693 }, 2694 Some(&Token::Comma), 2695 )?; 2696 let (_, end) = self 2697 .expect_one_following_series(&Token::RightParen, "a constructor argument name")?; 2698 Ok((arguments, end)) 2699 } else { 2700 Ok((vec![], 0)) 2701 } 2702 } 2703 2704 // 2705 // Parse Type Annotations 2706 // 2707 2708 // examples: 2709 // :a 2710 // :Int 2711 // :Result(a, _) 2712 // :Result(Result(a, e), #(_, String)) 2713 fn parse_type_annotation(&mut self, start_tok: &Token) -> Result<Option<TypeAst>, ParseError> { 2714 if let Some((start, end)) = self.maybe_one(start_tok) { 2715 match self.parse_type() { 2716 Ok(None) => parse_error(ParseErrorType::ExpectedType, SrcSpan { start, end }), 2717 other => other, 2718 } 2719 } else { 2720 Ok(None) 2721 } 2722 } 2723 2724 // Parse the type part of a type annotation, same as `parse_type_annotation` minus the ":" 2725 fn parse_type(&mut self) -> Result<Option<TypeAst>, ParseError> { 2726 match self.tok0.take() { 2727 // Type hole 2728 Some((start, Token::DiscardName { name }, end)) => { 2729 self.advance(); 2730 Ok(Some(TypeAst::Hole(TypeAstHole { 2731 location: SrcSpan { start, end }, 2732 name, 2733 }))) 2734 } 2735 2736 // Tuple 2737 Some((start, Token::Hash, _)) => { 2738 self.advance(); 2739 let _ = self.expect_one(&Token::LeftParen)?; 2740 let elements = self.parse_types()?; 2741 let (_, end) = self.expect_one(&Token::RightParen)?; 2742 Ok(Some(TypeAst::Tuple(TypeAstTuple { 2743 location: SrcSpan { start, end }, 2744 elements, 2745 }))) 2746 } 2747 2748 // Function 2749 Some((start, Token::Fn, _)) => { 2750 self.advance(); 2751 let _ = self.expect_one(&Token::LeftParen)?; 2752 let arguments = 2753 Parser::series_of(self, &|x| Parser::parse_type(x), Some(&Token::Comma))?; 2754 let _ = self.expect_one_following_series(&Token::RightParen, "a type")?; 2755 let (arr_s, arr_e) = self.expect_one(&Token::RArrow)?; 2756 let return_ = self.parse_type()?; 2757 match return_ { 2758 Some(return_) => Ok(Some(TypeAst::Fn(TypeAstFn { 2759 location: SrcSpan { 2760 start, 2761 end: return_.location().end, 2762 }, 2763 return_: Box::new(return_), 2764 arguments, 2765 }))), 2766 _ => parse_error( 2767 ParseErrorType::ExpectedType, 2768 SrcSpan { 2769 start: arr_s, 2770 end: arr_e, 2771 }, 2772 ), 2773 } 2774 } 2775 2776 // Constructor function 2777 Some((start, Token::UpName { name }, end)) => { 2778 self.advance(); 2779 self.parse_type_name_finish(start, start, None, name, end) 2780 } 2781 2782 // Constructor Module or type Variable 2783 Some((start, Token::Name { name: mod_name }, end)) => { 2784 self.advance(); 2785 if self.maybe_one(&Token::Dot).is_some() { 2786 let (name_start, upname, upname_e) = self.expect_upname()?; 2787 self.parse_type_name_finish( 2788 start, 2789 name_start, 2790 Some((mod_name, SrcSpan { start, end })), 2791 upname, 2792 upname_e, 2793 ) 2794 } else { 2795 Ok(Some(TypeAst::Var(TypeAstVar { 2796 location: SrcSpan { start, end }, 2797 name: mod_name, 2798 }))) 2799 } 2800 } 2801 2802 t0 => { 2803 self.tok0 = t0; 2804 Ok(None) 2805 } 2806 } 2807 } 2808 2809 // Parse the '( ... )' of a type name 2810 fn parse_type_name_finish( 2811 &mut self, 2812 start: u32, 2813 name_start: u32, 2814 module: Option<(EcoString, SrcSpan)>, 2815 name: EcoString, 2816 end: u32, 2817 ) -> Result<Option<TypeAst>, ParseError> { 2818 if let Some((par_s, _)) = self.maybe_one(&Token::LeftParen) { 2819 let arguments = self.parse_types()?; 2820 let (_, par_e) = self.expect_one(&Token::RightParen)?; 2821 Ok(Some(TypeAst::Constructor(TypeAstConstructor { 2822 location: SrcSpan { start, end: par_e }, 2823 name_location: SrcSpan { 2824 start: name_start, 2825 end, 2826 }, 2827 module, 2828 name, 2829 arguments, 2830 start_parentheses: Some(par_s), 2831 }))) 2832 } else if let Some((less_start, less_end)) = self.maybe_one(&Token::Less) { 2833 let arguments = self.parse_types()?; 2834 Err(ParseError { 2835 error: ParseErrorType::TypeUsageAngleGenerics { 2836 name, 2837 module: module.map(|(module_name, _)| module_name), 2838 arguments, 2839 }, 2840 location: SrcSpan { 2841 start: less_start, 2842 end: less_end, 2843 }, 2844 }) 2845 } else { 2846 Ok(Some(TypeAst::Constructor(TypeAstConstructor { 2847 location: SrcSpan { start, end }, 2848 name_location: SrcSpan { 2849 start: name_start, 2850 end, 2851 }, 2852 module, 2853 name, 2854 arguments: vec![], 2855 start_parentheses: None, 2856 }))) 2857 } 2858 } 2859 2860 // For parsing a comma separated "list" of types, for tuple, constructor, and function 2861 fn parse_types(&mut self) -> Result<Vec<TypeAst>, ParseError> { 2862 let elements = Parser::series_of(self, &|p| Parser::parse_type(p), Some(&Token::Comma))?; 2863 Ok(elements) 2864 } 2865 2866 // 2867 // Parse Imports 2868 // 2869 2870 // examples: 2871 // import a 2872 // import a/b 2873 // import a/b.{c} 2874 // import a/b.{c as d} as e 2875 fn parse_import(&mut self, import_start: u32) -> Result<Option<UntypedDefinition>, ParseError> { 2876 let mut start = 0; 2877 let mut end; 2878 let mut module = EcoString::new(); 2879 // Gather module names 2880 loop { 2881 let (s, name, e) = self.expect_name()?; 2882 if module.is_empty() { 2883 start = s; 2884 } else { 2885 module.push('/'); 2886 } 2887 module.push_str(&name); 2888 end = e; 2889 2890 // Useful error for : import a/.{b} 2891 if let Some((s, _)) = self.maybe_one(&Token::SlashDot) { 2892 return parse_error( 2893 ParseErrorType::ExpectedName, 2894 SrcSpan { 2895 start: s + 1, 2896 end: s + 1, 2897 }, 2898 ); 2899 } 2900 2901 // break if there's no trailing slash 2902 if self.maybe_one(&Token::Slash).is_none() { 2903 break; 2904 } 2905 } 2906 2907 let (_, documentation) = self.take_documentation(start).unzip(); 2908 2909 // Gather imports 2910 let mut unqualified_values = vec![]; 2911 let mut unqualified_types = vec![]; 2912 2913 if let Some((dot_start, dot_end)) = self.maybe_one(&Token::Dot) { 2914 if let Err(e) = self.expect_one(&Token::LeftBrace) { 2915 // If the module does contain a '/', then it's unlikely that the user 2916 // intended for the import to be pythonic, so skip this. 2917 if module.contains('/') { 2918 return Err(e); 2919 } 2920 2921 // Catch `import gleam.io` and provide a more helpful error... 2922 let ParseErrorType::UnexpectedToken { 2923 token: Token::Name { name } | Token::UpName { name }, 2924 .. 2925 } = &e.error 2926 else { 2927 return Err(e); 2928 }; 2929 2930 return Err(ParseError { 2931 error: ParseErrorType::IncorrectImportModuleSeparator { 2932 module, 2933 item: name.clone(), 2934 }, 2935 location: SrcSpan::new(dot_start, dot_end), 2936 }); 2937 }; 2938 2939 let parsed = self.parse_unqualified_imports()?; 2940 unqualified_types = parsed.types; 2941 unqualified_values = parsed.values; 2942 let (_, e) = self.expect_one(&Token::RightBrace)?; 2943 end = e; 2944 } 2945 2946 // Parse as_name 2947 let mut as_name = None; 2948 if let Some((as_start, _)) = self.maybe_one(&Token::As) { 2949 let (_, name, e) = self.expect_assign_name()?; 2950 2951 end = e; 2952 as_name = Some(( 2953 name, 2954 SrcSpan { 2955 start: as_start, 2956 end, 2957 }, 2958 )); 2959 } 2960 2961 Ok(Some(Definition::Import(Import { 2962 documentation, 2963 location: SrcSpan { 2964 start: import_start, 2965 end, 2966 }, 2967 unqualified_values, 2968 unqualified_types, 2969 module, 2970 as_name, 2971 package: (), 2972 }))) 2973 } 2974 2975 // [Name (as Name)? | UpName (as Name)? ](, [Name (as Name)? | UpName (as Name)?])*,? 2976 fn parse_unqualified_imports(&mut self) -> Result<ParsedUnqualifiedImports, ParseError> { 2977 let mut imports = ParsedUnqualifiedImports::default(); 2978 loop { 2979 // parse imports 2980 match self.tok0.take() { 2981 Some((start, Token::Name { name }, end)) => { 2982 self.advance(); 2983 let location = SrcSpan { start, end }; 2984 let mut import = UnqualifiedImport { 2985 name, 2986 location, 2987 imported_name_location: location, 2988 as_name: None, 2989 }; 2990 if self.maybe_one(&Token::As).is_some() { 2991 let (_, as_name, end) = self.expect_name()?; 2992 import.as_name = Some(as_name); 2993 import.location.end = end; 2994 } 2995 imports.values.push(import) 2996 } 2997 2998 Some((start, Token::UpName { name }, end)) => { 2999 self.advance(); 3000 let location = SrcSpan { start, end }; 3001 let mut import = UnqualifiedImport { 3002 name, 3003 location, 3004 imported_name_location: location, 3005 as_name: None, 3006 }; 3007 if self.maybe_one(&Token::As).is_some() { 3008 let (_, as_name, end) = self.expect_upname()?; 3009 import.as_name = Some(as_name); 3010 import.location.end = end; 3011 } 3012 imports.values.push(import) 3013 } 3014 3015 Some((start, Token::Type, _)) => { 3016 self.advance(); 3017 let (name_start, name, end) = self.expect_upname()?; 3018 let location = SrcSpan { start, end }; 3019 let mut import = UnqualifiedImport { 3020 name, 3021 location, 3022 imported_name_location: SrcSpan::new(name_start, end), 3023 as_name: None, 3024 }; 3025 if self.maybe_one(&Token::As).is_some() { 3026 let (_, as_name, end) = self.expect_upname()?; 3027 import.as_name = Some(as_name); 3028 import.location.end = end; 3029 } 3030 imports.types.push(import) 3031 } 3032 3033 t0 => { 3034 self.tok0 = t0; 3035 break; 3036 } 3037 } 3038 // parse comma 3039 match self.tok0 { 3040 Some((_, Token::Comma, _)) => { 3041 self.advance(); 3042 } 3043 _ => break, 3044 } 3045 } 3046 Ok(imports) 3047 } 3048 3049 // 3050 // Parse Constants 3051 // 3052 3053 // examples: 3054 // const a = 1 3055 // const a:Int = 1 3056 // pub const a:Int = 1 3057 fn parse_module_const( 3058 &mut self, 3059 start: u32, 3060 public: bool, 3061 attributes: &Attributes, 3062 ) -> Result<Option<UntypedDefinition>, ParseError> { 3063 let (name_start, name, name_end) = self.expect_name()?; 3064 let documentation = self.take_documentation(name_start); 3065 3066 let annotation = self.parse_type_annotation(&Token::Colon)?; 3067 3068 let (eq_s, eq_e) = self.expect_one(&Token::Equal)?; 3069 match self.parse_const_value()? { 3070 Some(value) => { 3071 Ok(Some(Definition::ModuleConstant(ModuleConstant { 3072 documentation, 3073 location: SrcSpan { 3074 start, 3075 3076 // End after the type annotation if it's there, otherwise after the name 3077 end: annotation 3078 .as_ref() 3079 .map(|annotation| annotation.location().end) 3080 .unwrap_or(0) 3081 .max(name_end), 3082 }, 3083 publicity: self.publicity(public, attributes.internal)?, 3084 name, 3085 name_location: SrcSpan::new(name_start, name_end), 3086 annotation, 3087 value: Box::new(value), 3088 type_: (), 3089 deprecation: attributes.deprecated.clone(), 3090 implementations: Implementations { 3091 gleam: true, 3092 can_run_on_erlang: true, 3093 can_run_on_javascript: true, 3094 uses_erlang_externals: false, 3095 uses_javascript_externals: false, 3096 }, 3097 }))) 3098 } 3099 _ => parse_error( 3100 ParseErrorType::NoValueAfterEqual, 3101 SrcSpan { 3102 start: eq_s, 3103 end: eq_e, 3104 }, 3105 ), 3106 } 3107 } 3108 3109 // examples: 3110 // 1 3111 // "hi" 3112 // True 3113 // [1,2,3] 3114 // foo <> "bar" 3115 fn parse_const_value(&mut self) -> Result<Option<UntypedConstant>, ParseError> { 3116 let constant_result = self.parse_const_value_unit(); 3117 match constant_result { 3118 Ok(Some(constant)) => self.parse_const_maybe_concatenation(constant), 3119 _ => constant_result, 3120 } 3121 } 3122 3123 fn parse_const_value_unit(&mut self) -> Result<Option<UntypedConstant>, ParseError> { 3124 match self.tok0.take() { 3125 Some((start, Token::String { value }, end)) => { 3126 self.advance(); 3127 Ok(Some(Constant::String { 3128 value, 3129 location: SrcSpan { start, end }, 3130 })) 3131 } 3132 3133 Some((start, Token::Float { value, float_value }, end)) => { 3134 self.advance(); 3135 Ok(Some(Constant::Float { 3136 value, 3137 location: SrcSpan { start, end }, 3138 float_value, 3139 })) 3140 } 3141 3142 Some((start, Token::Int { value, int_value }, end)) => { 3143 self.advance(); 3144 Ok(Some(Constant::Int { 3145 value, 3146 int_value, 3147 location: SrcSpan { start, end }, 3148 })) 3149 } 3150 3151 Some((start, Token::Hash, _)) => { 3152 self.advance(); 3153 let _ = self.expect_one(&Token::LeftParen)?; 3154 let elements = 3155 Parser::series_of(self, &Parser::parse_const_value, Some(&Token::Comma))?; 3156 let (_, end) = 3157 self.expect_one_following_series(&Token::RightParen, "a constant value")?; 3158 Ok(Some(Constant::Tuple { 3159 elements, 3160 location: SrcSpan { start, end }, 3161 })) 3162 } 3163 3164 Some((start, Token::LeftSquare, _)) => { 3165 self.advance(); 3166 let elements = 3167 Parser::series_of(self, &Parser::parse_const_value, Some(&Token::Comma))?; 3168 let (_, end) = 3169 self.expect_one_following_series(&Token::RightSquare, "a constant value")?; 3170 Ok(Some(Constant::List { 3171 elements, 3172 location: SrcSpan { start, end }, 3173 type_: (), 3174 })) 3175 } 3176 // BitArray 3177 Some((start, Token::LtLt, _)) => { 3178 self.advance(); 3179 let segments = Parser::series_of( 3180 self, 3181 &|s| { 3182 Parser::parse_bit_array_segment( 3183 s, 3184 &Parser::parse_const_value, 3185 &Parser::expect_const_int, 3186 &bit_array_const_int, 3187 ) 3188 }, 3189 Some(&Token::Comma), 3190 )?; 3191 let (_, end) = 3192 self.expect_one_following_series(&Token::GtGt, "a bit array segment")?; 3193 Ok(Some(Constant::BitArray { 3194 location: SrcSpan { start, end }, 3195 segments, 3196 })) 3197 } 3198 3199 Some((start, Token::UpName { name }, end)) => { 3200 self.advance(); 3201 self.parse_const_record_finish(start, None, name, end) 3202 } 3203 3204 Some((start, Token::Name { name }, module_end)) 3205 if self.peek_tok1() == Some(&Token::Dot) => 3206 { 3207 self.advance(); // name 3208 self.advance(); // dot 3209 3210 match self.tok0.take() { 3211 Some((_, Token::UpName { name: upname }, end)) => { 3212 self.advance(); // upname 3213 self.parse_const_record_finish( 3214 start, 3215 Some((name, SrcSpan::new(start, module_end))), 3216 upname, 3217 end, 3218 ) 3219 } 3220 Some((_, Token::Name { name: end_name }, end)) => { 3221 self.advance(); // name 3222 3223 match self.tok0 { 3224 Some((_, Token::LeftParen, _)) => parse_error( 3225 ParseErrorType::UnexpectedFunction, 3226 SrcSpan { 3227 start, 3228 end: end + 1, 3229 }, 3230 ), 3231 _ => Ok(Some(Constant::Var { 3232 location: SrcSpan { start, end }, 3233 module: Some((name, SrcSpan::new(start, module_end))), 3234 name: end_name, 3235 constructor: None, 3236 type_: (), 3237 })), 3238 } 3239 } 3240 Some((start, token, end)) => parse_error( 3241 ParseErrorType::UnexpectedToken { 3242 token, 3243 expected: vec!["UpName".into(), "Name".into()], 3244 hint: None, 3245 }, 3246 SrcSpan { start, end }, 3247 ), 3248 None => { 3249 parse_error(ParseErrorType::UnexpectedEof, SrcSpan { start: 0, end: 0 }) 3250 } 3251 } 3252 } 3253 3254 Some((start, Token::Name { name }, end)) => { 3255 self.advance(); // name 3256 3257 match self.tok0 { 3258 Some((_, Token::LeftParen, _)) => parse_error( 3259 ParseErrorType::UnexpectedFunction, 3260 SrcSpan { 3261 start, 3262 end: end + 1, 3263 }, 3264 ), 3265 _ => Ok(Some(Constant::Var { 3266 location: SrcSpan { start, end }, 3267 module: None, 3268 name, 3269 constructor: None, 3270 type_: (), 3271 })), 3272 } 3273 } 3274 3275 // Helpful error for fn 3276 Some((start, Token::Fn, end)) => { 3277 parse_error(ParseErrorType::NotConstType, SrcSpan { start, end }) 3278 } 3279 3280 t0 => { 3281 self.tok0 = t0; 3282 Ok(None) 3283 } 3284 } 3285 } 3286 3287 fn parse_const_maybe_concatenation( 3288 &mut self, 3289 left: UntypedConstant, 3290 ) -> Result<Option<UntypedConstant>, ParseError> { 3291 match self.tok0.take() { 3292 Some((op_start, Token::LtGt, op_end)) => { 3293 self.advance(); 3294 3295 match self.parse_const_value() { 3296 Ok(Some(right_constant_value)) => Ok(Some(Constant::StringConcatenation { 3297 location: SrcSpan { 3298 start: left.location().start, 3299 end: right_constant_value.location().end, 3300 }, 3301 left: Box::new(left), 3302 right: Box::new(right_constant_value), 3303 })), 3304 _ => parse_error( 3305 ParseErrorType::OpNakedRight, 3306 SrcSpan { 3307 start: op_start, 3308 end: op_end, 3309 }, 3310 ), 3311 } 3312 } 3313 t0 => { 3314 self.tok0 = t0; 3315 Ok(Some(left)) 3316 } 3317 } 3318 } 3319 3320 // Parse the '( .. )' of a const type constructor 3321 fn parse_const_record_finish( 3322 &mut self, 3323 start: u32, 3324 module: Option<(EcoString, SrcSpan)>, 3325 name: EcoString, 3326 end: u32, 3327 ) -> Result<Option<UntypedConstant>, ParseError> { 3328 match self.maybe_one(&Token::LeftParen) { 3329 Some((par_s, _)) => { 3330 let arguments = 3331 Parser::series_of(self, &Parser::parse_const_record_arg, Some(&Token::Comma))?; 3332 let (_, par_e) = self.expect_one_following_series( 3333 &Token::RightParen, 3334 "a constant record argument", 3335 )?; 3336 if arguments.is_empty() { 3337 return parse_error( 3338 ParseErrorType::ConstantRecordConstructorNoArguments, 3339 SrcSpan::new(par_s, par_e), 3340 ); 3341 } 3342 Ok(Some(Constant::Record { 3343 location: SrcSpan { start, end: par_e }, 3344 module, 3345 name, 3346 arguments, 3347 tag: (), 3348 type_: (), 3349 field_map: None, 3350 record_constructor: None, 3351 })) 3352 } 3353 _ => Ok(Some(Constant::Record { 3354 location: SrcSpan { start, end }, 3355 module, 3356 name, 3357 arguments: vec![], 3358 tag: (), 3359 type_: (), 3360 field_map: None, 3361 record_constructor: None, 3362 })), 3363 } 3364 } 3365 3366 // examples: 3367 // name: const 3368 // const 3369 // name: 3370 fn parse_const_record_arg(&mut self) -> Result<Option<CallArg<UntypedConstant>>, ParseError> { 3371 let label = match (self.tok0.take(), self.tok1.take()) { 3372 // Named arg 3373 (Some((start, Token::Name { name }, _)), Some((_, Token::Colon, end))) => { 3374 self.advance(); 3375 self.advance(); 3376 Some((start, name, end)) 3377 } 3378 3379 // Unnamed arg 3380 (t0, t1) => { 3381 self.tok0 = t0; 3382 self.tok1 = t1; 3383 None 3384 } 3385 }; 3386 3387 match self.parse_const_value()? { 3388 Some(value) => match label { 3389 Some((start, label, _)) => Ok(Some(CallArg { 3390 implicit: None, 3391 location: SrcSpan { 3392 start, 3393 end: value.location().end, 3394 }, 3395 value, 3396 label: Some(label), 3397 })), 3398 _ => Ok(Some(CallArg { 3399 implicit: None, 3400 location: value.location(), 3401 value, 3402 label: None, 3403 })), 3404 }, 3405 _ => { 3406 match label { 3407 Some((start, label, end)) => { 3408 // Argument supplied with a label shorthand. 3409 Ok(Some(CallArg { 3410 implicit: None, 3411 location: SrcSpan { start, end }, 3412 label: Some(label.clone()), 3413 value: UntypedConstant::Var { 3414 location: SrcSpan { start, end }, 3415 constructor: None, 3416 module: None, 3417 name: label, 3418 type_: (), 3419 }, 3420 })) 3421 } 3422 _ => Ok(None), 3423 } 3424 } 3425 } 3426 } 3427 3428 // 3429 // Bit String parsing 3430 // 3431 3432 // The structure is roughly the same for pattern, const, and expr 3433 // that's why these functions take functions 3434 // 3435 // pattern (: option)? 3436 fn parse_bit_array_segment<A>( 3437 &mut self, 3438 value_parser: &impl Fn(&mut Self) -> Result<Option<A>, ParseError>, 3439 arg_parser: &impl Fn(&mut Self) -> Result<A, ParseError>, 3440 to_int_segment: &impl Fn(EcoString, BigInt, u32, u32) -> A, 3441 ) -> Result<Option<BitArraySegment<A, ()>>, ParseError> 3442 where 3443 A: HasLocation + std::fmt::Debug, 3444 { 3445 match value_parser(self)? { 3446 Some(value) => { 3447 let options = if self.maybe_one(&Token::Colon).is_some() { 3448 Parser::series_of( 3449 self, 3450 &|s| Parser::parse_bit_array_option(s, &arg_parser, &to_int_segment), 3451 Some(&Token::Minus), 3452 )? 3453 } else { 3454 vec![] 3455 }; 3456 let end = options 3457 .last() 3458 .map(|o| o.location().end) 3459 .unwrap_or_else(|| value.location().end); 3460 Ok(Some(BitArraySegment { 3461 location: SrcSpan { 3462 start: value.location().start, 3463 end, 3464 }, 3465 value: Box::new(value), 3466 type_: (), 3467 options, 3468 })) 3469 } 3470 _ => Ok(None), 3471 } 3472 } 3473 3474 // examples: 3475 // 1 3476 // size(1) 3477 // size(five) 3478 // utf8 3479 fn parse_bit_array_option<A: std::fmt::Debug>( 3480 &mut self, 3481 arg_parser: &impl Fn(&mut Self) -> Result<A, ParseError>, 3482 to_int_segment: &impl Fn(EcoString, BigInt, u32, u32) -> A, 3483 ) -> Result<Option<BitArrayOption<A>>, ParseError> { 3484 match self.next_tok() { 3485 // named segment 3486 Some((start, Token::Name { name }, end)) => { 3487 if self.maybe_one(&Token::LeftParen).is_some() { 3488 // named function segment 3489 match name.as_str() { 3490 "unit" => match self.next_tok() { 3491 Some((int_s, Token::Int { value, .. }, int_e)) => { 3492 let (_, end) = self.expect_one(&Token::RightParen)?; 3493 let v = value.replace("_", ""); 3494 match u8::from_str(&v) { 3495 Ok(units) if units > 0 => Ok(Some(BitArrayOption::Unit { 3496 location: SrcSpan { start, end }, 3497 value: units, 3498 })), 3499 3500 _ => Err(ParseError { 3501 error: ParseErrorType::InvalidBitArrayUnit, 3502 location: SrcSpan { 3503 start: int_s, 3504 end: int_e, 3505 }, 3506 }), 3507 } 3508 } 3509 _ => self.next_tok_unexpected(vec!["positive integer".into()]), 3510 }, 3511 3512 "size" => { 3513 let value = arg_parser(self)?; 3514 let (_, end) = self.expect_one(&Token::RightParen)?; 3515 Ok(Some(BitArrayOption::Size { 3516 location: SrcSpan { start, end }, 3517 value: Box::new(value), 3518 short_form: false, 3519 })) 3520 } 3521 _ => parse_error( 3522 ParseErrorType::InvalidBitArraySegment, 3523 SrcSpan { start, end }, 3524 ), 3525 } 3526 } else { 3527 str_to_bit_array_option(&name, SrcSpan { start, end }) 3528 .ok_or(ParseError { 3529 error: ParseErrorType::InvalidBitArraySegment, 3530 location: SrcSpan { start, end }, 3531 }) 3532 .map(Some) 3533 } 3534 } 3535 // int segment 3536 Some((start, Token::Int { value, int_value }, end)) => Ok(Some(BitArrayOption::Size { 3537 location: SrcSpan { start, end }, 3538 value: Box::new(to_int_segment(value, int_value, start, end)), 3539 short_form: true, 3540 })), 3541 // invalid 3542 _ => self.next_tok_unexpected(vec![ 3543 "A valid bit array segment type".into(), 3544 "See: https://tour.gleam.run/data-types/bit-arrays/".into(), 3545 ]), 3546 } 3547 } 3548 3549 fn expect_bit_array_pattern_segment_arg(&mut self) -> Result<UntypedPattern, ParseError> { 3550 Ok(Pattern::BitArraySize(self.expect_bit_array_size()?)) 3551 } 3552 3553 fn expect_bit_array_size(&mut self) -> Result<BitArraySize<()>, ParseError> { 3554 let left = match self.next_tok() { 3555 Some((start, Token::Name { name }, end)) => BitArraySize::Variable { 3556 location: SrcSpan { start, end }, 3557 name, 3558 constructor: None, 3559 type_: (), 3560 }, 3561 Some((start, Token::Int { value, int_value }, end)) => BitArraySize::Int { 3562 location: SrcSpan { start, end }, 3563 value, 3564 int_value, 3565 }, 3566 Some((start, Token::LeftBrace, _)) => { 3567 let inner = self.expect_bit_array_size()?; 3568 let (_, end) = self.expect_one(&Token::RightBrace)?; 3569 3570 BitArraySize::Block { 3571 location: SrcSpan { start, end }, 3572 inner: Box::new(inner), 3573 } 3574 } 3575 _ => return self.next_tok_unexpected(vec!["A variable name or an integer".into()]), 3576 }; 3577 3578 let Some((start, token, end)) = self.tok0.take() else { 3579 return Ok(left); 3580 }; 3581 3582 match token { 3583 Token::Plus => { 3584 _ = self.next_tok(); 3585 let right = self.expect_bit_array_size()?; 3586 3587 Ok(self.bit_array_size_binary_operator(left, right, IntOperator::Add)) 3588 } 3589 Token::Minus => { 3590 _ = self.next_tok(); 3591 let right = self.expect_bit_array_size()?; 3592 3593 Ok(self.bit_array_size_binary_operator(left, right, IntOperator::Subtract)) 3594 } 3595 Token::Star => { 3596 _ = self.next_tok(); 3597 let right = self.expect_bit_array_size()?; 3598 3599 Ok( 3600 self.bit_array_size_high_precedence_operator( 3601 left, 3602 right, 3603 IntOperator::Multiply, 3604 ), 3605 ) 3606 } 3607 Token::Slash => { 3608 _ = self.next_tok(); 3609 let right = self.expect_bit_array_size()?; 3610 3611 Ok(self.bit_array_size_high_precedence_operator(left, right, IntOperator::Divide)) 3612 } 3613 Token::Percent => { 3614 _ = self.next_tok(); 3615 let right = self.expect_bit_array_size()?; 3616 3617 Ok(self.bit_array_size_high_precedence_operator( 3618 left, 3619 right, 3620 IntOperator::Remainder, 3621 )) 3622 } 3623 _ => { 3624 self.tok0 = Some((start, token, end)); 3625 Ok(left) 3626 } 3627 } 3628 } 3629 3630 fn bit_array_size_binary_operator( 3631 &self, 3632 left: BitArraySize<()>, 3633 right: BitArraySize<()>, 3634 operator: IntOperator, 3635 ) -> BitArraySize<()> { 3636 let start = left.location().start; 3637 let end = right.location().end; 3638 3639 BitArraySize::BinaryOperator { 3640 left: Box::new(left), 3641 right: Box::new(right), 3642 operator, 3643 location: SrcSpan { start, end }, 3644 } 3645 } 3646 3647 fn bit_array_size_high_precedence_operator( 3648 &self, 3649 left: BitArraySize<()>, 3650 right: BitArraySize<()>, 3651 operator: IntOperator, 3652 ) -> BitArraySize<()> { 3653 match right { 3654 BitArraySize::Int { .. } 3655 | BitArraySize::Variable { .. } 3656 | BitArraySize::Block { .. } => { 3657 self.bit_array_size_binary_operator(left, right, operator) 3658 } 3659 // This operator has the highest precedence of the possible operators 3660 // for bit array size patterns. So, `a * b + c` should be parsed as 3661 // `(a * b) + c`. If the right-hand side of this operator is another 3662 // operator, we rearrange it to ensure correct precedence. 3663 BitArraySize::BinaryOperator { 3664 operator: right_operator, 3665 left: middle, 3666 right, 3667 .. 3668 } => self.bit_array_size_binary_operator( 3669 self.bit_array_size_binary_operator(left, *middle, operator), 3670 *right, 3671 right_operator, 3672 ), 3673 } 3674 } 3675 3676 fn expect_const_int(&mut self) -> Result<UntypedConstant, ParseError> { 3677 match self.next_tok() { 3678 Some((start, Token::Int { value, int_value }, end)) => Ok(Constant::Int { 3679 location: SrcSpan { start, end }, 3680 value, 3681 int_value, 3682 }), 3683 _ => self.next_tok_unexpected(vec!["A variable name or an integer".into()]), 3684 } 3685 } 3686 3687 fn expect_expression(&mut self) -> Result<UntypedExpr, ParseError> { 3688 match self.parse_expression()? { 3689 Some(e) => Ok(e), 3690 _ => self.next_tok_unexpected(vec!["An expression".into()]), 3691 } 3692 } 3693 3694 fn expect_expression_unit( 3695 &mut self, 3696 context: ExpressionUnitContext, 3697 ) -> Result<UntypedExpr, ParseError> { 3698 if let Some(e) = self.parse_expression_unit(context)? { 3699 Ok(e) 3700 } else { 3701 self.next_tok_unexpected(vec!["An expression".into()]) 3702 } 3703 } 3704 3705 // 3706 // Parse Helpers 3707 // 3708 3709 /// Expect a particular token, advances the token stream 3710 fn expect_one(&mut self, wanted: &Token) -> Result<(u32, u32), ParseError> { 3711 match self.maybe_one(wanted) { 3712 Some((start, end)) => Ok((start, end)), 3713 None => self.next_tok_unexpected(vec![wanted.to_string().into()]), 3714 } 3715 } 3716 3717 // Expect a particular token after having parsed a series, advances the token stream 3718 // Used for giving a clearer error message in cases where the series item is what failed to parse 3719 fn expect_one_following_series( 3720 &mut self, 3721 wanted: &Token, 3722 series: &'static str, 3723 ) -> Result<(u32, u32), ParseError> { 3724 match self.maybe_one(wanted) { 3725 Some((start, end)) => Ok((start, end)), 3726 None => self.next_tok_unexpected(vec![wanted.to_string().into(), series.into()]), 3727 } 3728 } 3729 3730 /// Expect the end to a custom type definiton or handle an incorrect 3731 /// record constructor definition. 3732 /// 3733 /// Used for mapping to a more specific error type and message. 3734 fn expect_custom_type_close( 3735 &mut self, 3736 name: &EcoString, 3737 public: bool, 3738 opaque: bool, 3739 ) -> Result<(u32, u32), ParseError> { 3740 match self.maybe_one(&Token::RightBrace) { 3741 Some((start, end)) => Ok((start, end)), 3742 None => match self.next_tok() { 3743 None => parse_error(ParseErrorType::UnexpectedEof, SrcSpan { start: 0, end: 0 }), 3744 Some((start, token, end)) => { 3745 // If provided a Name, map to a more detailed error 3746 // message to nudge the user. 3747 // Else, handle as an unexpected token. 3748 let field = match token { 3749 Token::Name { name } => name, 3750 token => { 3751 let hint = match (&token, self.tok0.take()) { 3752 (&Token::Fn, _) | (&Token::Pub, Some((_, Token::Fn, _))) => { 3753 let text = 3754 "Gleam is not an object oriented programming language so 3755functions are declared separately from types."; 3756 Some(wrap(text).into()) 3757 } 3758 (_, _) => None, 3759 }; 3760 3761 return parse_error( 3762 ParseErrorType::UnexpectedToken { 3763 token, 3764 expected: vec![ 3765 Token::RightBrace.to_string().into(), 3766 "a record constructor".into(), 3767 ], 3768 hint, 3769 }, 3770 SrcSpan { start, end }, 3771 ); 3772 } 3773 }; 3774 let field_type = match self.parse_type_annotation(&Token::Colon) { 3775 Ok(Some(annotation)) => Some(Box::new(annotation)), 3776 _ => None, 3777 }; 3778 parse_error( 3779 ParseErrorType::ExpectedRecordConstructor { 3780 name: name.clone(), 3781 public, 3782 opaque, 3783 field, 3784 field_type, 3785 }, 3786 SrcSpan { start, end }, 3787 ) 3788 } 3789 }, 3790 } 3791 } 3792 3793 // Expect a Name else a token dependent helpful error 3794 fn expect_name(&mut self) -> Result<(u32, EcoString, u32), ParseError> { 3795 let (start, token, end) = self.expect_assign_name()?; 3796 match token { 3797 AssignName::Variable(name) => Ok((start, name, end)), 3798 AssignName::Discard(_) => { 3799 parse_error(ParseErrorType::IncorrectName, SrcSpan { start, end }) 3800 } 3801 } 3802 } 3803 3804 fn expect_assign_name(&mut self) -> Result<(u32, AssignName, u32), ParseError> { 3805 let t = self.next_tok(); 3806 match t { 3807 Some((start, tok, end)) => match tok { 3808 Token::Name { name } => Ok((start, AssignName::Variable(name), end)), 3809 Token::DiscardName { name, .. } => Ok((start, AssignName::Discard(name), end)), 3810 Token::UpName { .. } => { 3811 parse_error(ParseErrorType::IncorrectName, SrcSpan { start, end }) 3812 } 3813 _ if tok.is_reserved_word() => parse_error( 3814 ParseErrorType::UnexpectedReservedWord, 3815 SrcSpan { start, end }, 3816 ), 3817 _ => parse_error(ParseErrorType::ExpectedName, SrcSpan { start, end }), 3818 }, 3819 None => parse_error(ParseErrorType::UnexpectedEof, SrcSpan { start: 0, end: 0 }), 3820 } 3821 } 3822 3823 // Expect an UpName else a token dependent helpful error 3824 fn expect_upname(&mut self) -> Result<(u32, EcoString, u32), ParseError> { 3825 let t = self.next_tok(); 3826 match t { 3827 Some((start, tok, end)) => match tok { 3828 Token::Name { .. } => { 3829 parse_error(ParseErrorType::IncorrectUpName, SrcSpan { start, end }) 3830 } 3831 _ => match tok { 3832 Token::UpName { name } => Ok((start, name, end)), 3833 _ => match tok { 3834 Token::DiscardName { .. } => { 3835 parse_error(ParseErrorType::IncorrectUpName, SrcSpan { start, end }) 3836 } 3837 _ => parse_error(ParseErrorType::ExpectedUpName, SrcSpan { start, end }), 3838 }, 3839 }, 3840 }, 3841 None => parse_error(ParseErrorType::UnexpectedEof, SrcSpan { start: 0, end: 0 }), 3842 } 3843 } 3844 3845 // Expect a target name. e.g. `javascript` or `erlang`. 3846 // The location of the preceding left parenthesis is required 3847 // to give the correct error span in case the target name is missing. 3848 fn expect_target(&mut self, paren_location: SrcSpan) -> Result<Target, ParseError> { 3849 let (start, t, end) = match self.next_tok() { 3850 Some(t) => t, 3851 None => { 3852 return parse_error(ParseErrorType::UnexpectedEof, SrcSpan { start: 0, end: 0 }); 3853 } 3854 }; 3855 match t { 3856 Token::Name { name } => match name.as_str() { 3857 "javascript" => Ok(Target::JavaScript), 3858 "erlang" => Ok(Target::Erlang), 3859 "js" => { 3860 self.warnings 3861 .push(DeprecatedSyntaxWarning::DeprecatedTargetShorthand { 3862 location: SrcSpan::new(start, end), 3863 target: Target::JavaScript, 3864 }); 3865 Ok(Target::JavaScript) 3866 } 3867 "erl" => { 3868 self.warnings 3869 .push(DeprecatedSyntaxWarning::DeprecatedTargetShorthand { 3870 location: SrcSpan::new(start, end), 3871 target: Target::Erlang, 3872 }); 3873 Ok(Target::Erlang) 3874 } 3875 _ => parse_error(ParseErrorType::UnknownTarget, SrcSpan::new(start, end)), 3876 }, 3877 _ => parse_error(ParseErrorType::ExpectedTargetName, paren_location), 3878 } 3879 } 3880 3881 // Expect a String else error 3882 fn expect_string(&mut self) -> Result<(u32, EcoString, u32), ParseError> { 3883 match self.next_tok() { 3884 Some((start, Token::String { value }, end)) => Ok((start, value, end)), 3885 _ => self.next_tok_unexpected(vec!["a string".into()]), 3886 } 3887 } 3888 3889 fn peek_tok1(&mut self) -> Option<&Token> { 3890 self.tok1.as_ref().map(|(_, token, _)| token) 3891 } 3892 3893 // If the next token matches the requested, consume it and return (start, end) 3894 fn maybe_one(&mut self, tok: &Token) -> Option<(u32, u32)> { 3895 match self.tok0.take() { 3896 Some((s, t, e)) if t == *tok => { 3897 self.advance(); 3898 Some((s, e)) 3899 } 3900 3901 t0 => { 3902 self.tok0 = t0; 3903 None 3904 } 3905 } 3906 } 3907 3908 // Parse a series by repeating a parser, and possibly a separator 3909 fn series_of<A>( 3910 &mut self, 3911 parser: &impl Fn(&mut Self) -> Result<Option<A>, ParseError>, 3912 sep: Option<&Token>, 3913 ) -> Result<Vec<A>, ParseError> { 3914 let (res, _) = self.series_of_has_trailing_separator(parser, sep)?; 3915 Ok(res) 3916 } 3917 3918 /// Parse a series by repeating a parser, and a separator. Returns true if 3919 /// the series ends with the trailing separator. 3920 fn series_of_has_trailing_separator<A>( 3921 &mut self, 3922 parser: &impl Fn(&mut Self) -> Result<Option<A>, ParseError>, 3923 sep: Option<&Token>, 3924 ) -> Result<(Vec<A>, bool), ParseError> { 3925 let mut results = vec![]; 3926 let mut final_separator = None; 3927 while let Some(result) = parser(self)? { 3928 results.push(result); 3929 if let Some(sep) = sep { 3930 if let Some(separator) = self.maybe_one(sep) { 3931 final_separator = Some(separator); 3932 } else { 3933 final_separator = None; 3934 break; 3935 } 3936 3937 // Helpful error if extra separator 3938 if let Some((start, end)) = self.maybe_one(sep) { 3939 return parse_error(ParseErrorType::ExtraSeparator, SrcSpan { start, end }); 3940 } 3941 } 3942 } 3943 3944 // If the sequence ends with a trailing comma we want to keep track of 3945 // its position. 3946 if let (Some(Token::Comma), Some((_, end))) = (sep, final_separator) { 3947 self.extra.trailing_commas.push(end) 3948 }; 3949 3950 Ok((results, final_separator.is_some())) 3951 } 3952 3953 // If next token is a Name, consume it and return relevant info, otherwise, return none 3954 fn maybe_name(&mut self) -> Option<(u32, EcoString, u32)> { 3955 match self.tok0.take() { 3956 Some((s, Token::Name { name }, e)) => { 3957 self.advance(); 3958 Some((s, name, e)) 3959 } 3960 t0 => { 3961 self.tok0 = t0; 3962 None 3963 } 3964 } 3965 } 3966 3967 // if next token is an UpName, consume it and return relevant info, otherwise, return none 3968 fn maybe_upname(&mut self) -> Option<(u32, EcoString, u32)> { 3969 match self.tok0.take() { 3970 Some((s, Token::UpName { name }, e)) => { 3971 self.advance(); 3972 Some((s, name, e)) 3973 } 3974 t0 => { 3975 self.tok0 = t0; 3976 None 3977 } 3978 } 3979 } 3980 3981 // if next token is a DiscardName, consume it and return relevant info, otherwise, return none 3982 fn maybe_discard_name(&mut self) -> Option<(u32, EcoString, u32)> { 3983 match self.tok0.take() { 3984 Some((s, Token::DiscardName { name }, e)) => { 3985 self.advance(); 3986 Some((s, name, e)) 3987 } 3988 t0 => { 3989 self.tok0 = t0; 3990 None 3991 } 3992 } 3993 } 3994 3995 // Unexpected token error on the next token or EOF 3996 fn next_tok_unexpected<A>(&mut self, expected: Vec<EcoString>) -> Result<A, ParseError> { 3997 match self.next_tok() { 3998 None => parse_error(ParseErrorType::UnexpectedEof, SrcSpan { start: 0, end: 0 }), 3999 Some((start, token, end)) => parse_error( 4000 ParseErrorType::UnexpectedToken { 4001 token, 4002 expected, 4003 hint: None, 4004 }, 4005 SrcSpan { start, end }, 4006 ), 4007 } 4008 } 4009 4010 // Moves the token stream forward 4011 fn advance(&mut self) { 4012 let _ = self.next_tok(); 4013 } 4014 4015 // Moving the token stream forward 4016 // returns old tok0 4017 fn next_tok(&mut self) -> Option<Spanned> { 4018 let t = self.tok0.take(); 4019 let mut previous_newline = None; 4020 let mut nxt; 4021 loop { 4022 match self.tokens.next() { 4023 // gather and skip extra 4024 Some(Ok((start, Token::CommentNormal, end))) => { 4025 self.extra.comments.push(SrcSpan { start, end }); 4026 previous_newline = None; 4027 } 4028 Some(Ok((start, Token::CommentDoc { content }, end))) => { 4029 self.extra.doc_comments.push(SrcSpan::new(start, end)); 4030 self.doc_comments.push_back((start, content)); 4031 previous_newline = None; 4032 } 4033 Some(Ok((start, Token::CommentModule, end))) => { 4034 self.extra.module_comments.push(SrcSpan { start, end }); 4035 previous_newline = None; 4036 } 4037 Some(Ok((start, Token::NewLine, _))) => { 4038 self.extra.new_lines.push(start); 4039 // If the previous token is a newline as well that means we 4040 // have run into an empty line. 4041 if let Some(start) = previous_newline { 4042 // We increase the byte position so that newline's start 4043 // doesn't overlap with the previous token's end. 4044 self.extra.empty_lines.push(start + 1); 4045 } 4046 previous_newline = Some(start); 4047 } 4048 4049 // die on lex error 4050 Some(Err(err)) => { 4051 nxt = None; 4052 self.lex_errors.push(err); 4053 break; 4054 } 4055 4056 Some(Ok(tok)) => { 4057 nxt = Some(tok); 4058 break; 4059 } 4060 None => { 4061 nxt = None; 4062 break; 4063 } 4064 } 4065 } 4066 self.tok0 = self.tok1.take(); 4067 self.tok1 = nxt.take(); 4068 t 4069 } 4070 4071 fn take_documentation(&mut self, until: u32) -> Option<(u32, EcoString)> { 4072 let mut content = String::new(); 4073 let mut doc_start = u32::MAX; 4074 while let Some((start, line)) = self.doc_comments.front() { 4075 if *start < doc_start { 4076 doc_start = *start; 4077 } 4078 if *start >= until { 4079 break; 4080 } 4081 4082 if self.extra.has_comment_between(*start, until) { 4083 // We ignore doc comments that come before a regular comment. 4084 let location = SrcSpan::new(*start, start + line.len() as u32); 4085 _ = self.doc_comments.pop_front(); 4086 self.detached_doc_comments.push(location); 4087 continue; 4088 } 4089 4090 content.push_str(line); 4091 content.push('\n'); 4092 _ = self.doc_comments.pop_front(); 4093 } 4094 if content.is_empty() { 4095 None 4096 } else { 4097 Some((doc_start, content.into())) 4098 } 4099 } 4100 4101 fn parse_attributes( 4102 &mut self, 4103 attributes: &mut Attributes, 4104 ) -> Result<Option<SrcSpan>, ParseError> { 4105 let mut attributes_span = None; 4106 4107 while let Some((start, end)) = self.maybe_one(&Token::At) { 4108 if attributes_span.is_none() { 4109 attributes_span = Some(SrcSpan { start, end }); 4110 } 4111 4112 let end = self.parse_attribute(start, attributes)?; 4113 attributes_span = attributes_span.map(|span| SrcSpan { 4114 start: span.start, 4115 end, 4116 }); 4117 } 4118 4119 Ok(attributes_span) 4120 } 4121 4122 fn parse_attribute( 4123 &mut self, 4124 start: u32, 4125 attributes: &mut Attributes, 4126 ) -> Result<u32, ParseError> { 4127 // Parse the name of the attribute. 4128 4129 let (_, name, end) = self.expect_name()?; 4130 4131 let end = match name.as_str() { 4132 "external" => { 4133 let _ = self.expect_one(&Token::LeftParen)?; 4134 self.parse_external_attribute(start, end, attributes) 4135 } 4136 "target" => self.parse_target_attribute(start, end, attributes), 4137 "deprecated" => { 4138 let _ = self.expect_one(&Token::LeftParen)?; 4139 self.parse_deprecated_attribute(start, end, attributes) 4140 } 4141 "internal" => self.parse_internal_attribute(start, end, attributes), 4142 _ => parse_error(ParseErrorType::UnknownAttribute, SrcSpan { start, end }), 4143 }?; 4144 4145 Ok(end) 4146 } 4147 4148 fn parse_target_attribute( 4149 &mut self, 4150 start: u32, 4151 end: u32, 4152 attributes: &mut Attributes, 4153 ) -> Result<u32, ParseError> { 4154 let (paren_start, paren_end) = self.expect_one(&Token::LeftParen)?; 4155 let target = self.expect_target(SrcSpan::new(paren_start, paren_end))?; 4156 if attributes.target.is_some() { 4157 return parse_error(ParseErrorType::DuplicateAttribute, SrcSpan { start, end }); 4158 } 4159 let (_, end) = self.expect_one(&Token::RightParen)?; 4160 if attributes.target.is_some() { 4161 return parse_error(ParseErrorType::DuplicateAttribute, SrcSpan { start, end }); 4162 } 4163 attributes.target = Some(target); 4164 Ok(end) 4165 } 4166 4167 fn parse_external_attribute( 4168 &mut self, 4169 start: u32, 4170 end: u32, 4171 attributes: &mut Attributes, 4172 ) -> Result<u32, ParseError> { 4173 let (_, name, _) = self.expect_name()?; 4174 4175 let target = match name.as_str() { 4176 "erlang" => Target::Erlang, 4177 "javascript" => Target::JavaScript, 4178 _ => return parse_error(ParseErrorType::UnknownTarget, SrcSpan::new(start, end)), 4179 }; 4180 4181 let _ = self.expect_one(&Token::Comma)?; 4182 let (_, module, _) = self.expect_string()?; 4183 let _ = self.expect_one(&Token::Comma)?; 4184 let (_, function, _) = self.expect_string()?; 4185 let _ = self.maybe_one(&Token::Comma); 4186 let (_, end) = self.expect_one(&Token::RightParen)?; 4187 4188 if attributes.has_external_for(target) { 4189 return parse_error(ParseErrorType::DuplicateAttribute, SrcSpan { start, end }); 4190 } 4191 4192 attributes.set_external_for(target, Some((module, function, SrcSpan { start, end }))); 4193 Ok(end) 4194 } 4195 4196 fn parse_deprecated_attribute( 4197 &mut self, 4198 start: u32, 4199 end: u32, 4200 attributes: &mut Attributes, 4201 ) -> Result<u32, ParseError> { 4202 if attributes.deprecated.is_deprecated() { 4203 return parse_error(ParseErrorType::DuplicateAttribute, SrcSpan::new(start, end)); 4204 } 4205 let (_, message, _) = self.expect_string().map_err(|_| ParseError { 4206 error: ParseErrorType::ExpectedDeprecationMessage, 4207 location: SrcSpan { start, end }, 4208 })?; 4209 let (_, end) = self.expect_one(&Token::RightParen)?; 4210 attributes.deprecated = Deprecation::Deprecated { message }; 4211 Ok(end) 4212 } 4213 4214 fn parse_internal_attribute( 4215 &mut self, 4216 start: u32, 4217 end: u32, 4218 attributes: &mut Attributes, 4219 ) -> Result<u32, ParseError> { 4220 match attributes.internal { 4221 // If `internal` is present that means that we have already run into 4222 // another `@internal` annotation, so it results in a `DuplicateAttribute` 4223 // error. 4224 InternalAttribute::Present(_) => { 4225 parse_error(ParseErrorType::DuplicateAttribute, SrcSpan::new(start, end)) 4226 } 4227 InternalAttribute::Missing => { 4228 attributes.internal = InternalAttribute::Present(SrcSpan::new(start, end)); 4229 Ok(end) 4230 } 4231 } 4232 } 4233} 4234 4235fn concat_pattern_variable_left_hand_side_error<T>(start: u32, end: u32) -> Result<T, ParseError> { 4236 Err(ParseError { 4237 error: ParseErrorType::ConcatPatternVariableLeftHandSide, 4238 location: SrcSpan::new(start, end), 4239 }) 4240} 4241 4242// Operator Precedence Parsing 4243// 4244// Higher number means higher precedence. 4245// All operators are left associative. 4246 4247/// Simple-Precedence-Parser, handle seeing an operator or end 4248fn handle_op<A>( 4249 next_op: Option<(Spanned, u8)>, 4250 opstack: &mut Vec<(Spanned, u8)>, 4251 estack: &mut Vec<A>, 4252 do_reduce: &impl Fn(Spanned, &mut Vec<A>), 4253) -> Option<A> { 4254 let mut next_op = next_op; 4255 loop { 4256 match (opstack.pop(), next_op.take()) { 4257 (None, None) => match estack.pop() { 4258 Some(fin) => { 4259 if estack.is_empty() { 4260 return Some(fin); 4261 } else { 4262 panic!("Expression not fully reduced.") 4263 } 4264 } 4265 _ => { 4266 return None; 4267 } 4268 }, 4269 4270 (None, Some(op)) => { 4271 opstack.push(op); 4272 break; 4273 } 4274 4275 (Some((op, _)), None) => do_reduce(op, estack), 4276 4277 (Some((opl, pl)), Some((opr, pr))) => { 4278 match pl.cmp(&pr) { 4279 // all ops are left associative 4280 Ordering::Greater | Ordering::Equal => { 4281 do_reduce(opl, estack); 4282 next_op = Some((opr, pr)); 4283 } 4284 Ordering::Less => { 4285 opstack.push((opl, pl)); 4286 opstack.push((opr, pr)); 4287 break; 4288 } 4289 } 4290 } 4291 } 4292 } 4293 None 4294} 4295 4296fn precedence(t: &Token) -> Option<u8> { 4297 if t == &Token::Pipe { 4298 return Some(6); 4299 }; 4300 tok_to_binop(t).map(|op| op.precedence()) 4301} 4302 4303fn tok_to_binop(t: &Token) -> Option<BinOp> { 4304 match t { 4305 Token::VbarVbar => Some(BinOp::Or), 4306 Token::AmperAmper => Some(BinOp::And), 4307 Token::EqualEqual => Some(BinOp::Eq), 4308 Token::NotEqual => Some(BinOp::NotEq), 4309 Token::Less => Some(BinOp::LtInt), 4310 Token::LessEqual => Some(BinOp::LtEqInt), 4311 Token::Greater => Some(BinOp::GtInt), 4312 Token::GreaterEqual => Some(BinOp::GtEqInt), 4313 Token::LessDot => Some(BinOp::LtFloat), 4314 Token::LessEqualDot => Some(BinOp::LtEqFloat), 4315 Token::GreaterDot => Some(BinOp::GtFloat), 4316 Token::GreaterEqualDot => Some(BinOp::GtEqFloat), 4317 Token::Plus => Some(BinOp::AddInt), 4318 Token::Minus => Some(BinOp::SubInt), 4319 Token::PlusDot => Some(BinOp::AddFloat), 4320 Token::MinusDot => Some(BinOp::SubFloat), 4321 Token::Percent => Some(BinOp::RemainderInt), 4322 Token::Star => Some(BinOp::MultInt), 4323 Token::StarDot => Some(BinOp::MultFloat), 4324 Token::Slash => Some(BinOp::DivInt), 4325 Token::SlashDot => Some(BinOp::DivFloat), 4326 Token::LtGt => Some(BinOp::Concatenate), 4327 _ => None, 4328 } 4329} 4330/// Simple-Precedence-Parser, perform reduction for expression 4331fn do_reduce_expression(op: Spanned, estack: &mut Vec<UntypedExpr>) { 4332 match (estack.pop(), estack.pop()) { 4333 (Some(er), Some(el)) => { 4334 let new_e = expr_op_reduction(op, el, er); 4335 estack.push(new_e); 4336 } 4337 _ => panic!("Tried to reduce without 2 expressions"), 4338 } 4339} 4340 4341/// Simple-Precedence-Parser, perform reduction for clause guard 4342fn do_reduce_clause_guard(op: Spanned, estack: &mut Vec<UntypedClauseGuard>) { 4343 match (estack.pop(), estack.pop()) { 4344 (Some(er), Some(el)) => { 4345 let new_e = clause_guard_reduction(op, el, er); 4346 estack.push(new_e); 4347 } 4348 _ => panic!("Tried to reduce without 2 guards"), 4349 } 4350} 4351 4352fn expr_op_reduction( 4353 (token_start, token, token_end): Spanned, 4354 l: UntypedExpr, 4355 r: UntypedExpr, 4356) -> UntypedExpr { 4357 if token == Token::Pipe { 4358 let expressions = match l { 4359 UntypedExpr::PipeLine { mut expressions } => { 4360 expressions.push(r); 4361 expressions 4362 } 4363 _ => { 4364 vec1![l, r] 4365 } 4366 }; 4367 UntypedExpr::PipeLine { expressions } 4368 } else { 4369 match tok_to_binop(&token) { 4370 Some(bin_op) => UntypedExpr::BinOp { 4371 location: SrcSpan { 4372 start: l.location().start, 4373 end: r.location().end, 4374 }, 4375 name: bin_op, 4376 name_location: SrcSpan { 4377 start: token_start, 4378 end: token_end, 4379 }, 4380 left: Box::new(l), 4381 right: Box::new(r), 4382 }, 4383 _ => { 4384 panic!("Token could not be converted to binop.") 4385 } 4386 } 4387 } 4388} 4389 4390fn clause_guard_reduction( 4391 (_, token, _): Spanned, 4392 l: UntypedClauseGuard, 4393 r: UntypedClauseGuard, 4394) -> UntypedClauseGuard { 4395 let location = SrcSpan { 4396 start: l.location().start, 4397 end: r.location().end, 4398 }; 4399 let left = Box::new(l); 4400 let right = Box::new(r); 4401 match token { 4402 Token::VbarVbar => ClauseGuard::Or { 4403 location, 4404 left, 4405 right, 4406 }, 4407 4408 Token::AmperAmper => ClauseGuard::And { 4409 location, 4410 left, 4411 right, 4412 }, 4413 4414 Token::EqualEqual => ClauseGuard::Equals { 4415 location, 4416 left, 4417 right, 4418 }, 4419 4420 Token::NotEqual => ClauseGuard::NotEquals { 4421 location, 4422 left, 4423 right, 4424 }, 4425 4426 Token::Greater => ClauseGuard::GtInt { 4427 location, 4428 left, 4429 right, 4430 }, 4431 4432 Token::GreaterEqual => ClauseGuard::GtEqInt { 4433 location, 4434 left, 4435 right, 4436 }, 4437 4438 Token::Less => ClauseGuard::LtInt { 4439 location, 4440 left, 4441 right, 4442 }, 4443 4444 Token::LessEqual => ClauseGuard::LtEqInt { 4445 location, 4446 left, 4447 right, 4448 }, 4449 4450 Token::GreaterDot => ClauseGuard::GtFloat { 4451 location, 4452 left, 4453 right, 4454 }, 4455 4456 Token::GreaterEqualDot => ClauseGuard::GtEqFloat { 4457 location, 4458 left, 4459 right, 4460 }, 4461 4462 Token::LessDot => ClauseGuard::LtFloat { 4463 location, 4464 left, 4465 right, 4466 }, 4467 4468 Token::LessEqualDot => ClauseGuard::LtEqFloat { 4469 location, 4470 left, 4471 right, 4472 }, 4473 4474 Token::Plus => ClauseGuard::AddInt { 4475 location, 4476 left, 4477 right, 4478 }, 4479 4480 Token::PlusDot => ClauseGuard::AddFloat { 4481 location, 4482 left, 4483 right, 4484 }, 4485 4486 Token::Minus => ClauseGuard::SubInt { 4487 location, 4488 left, 4489 right, 4490 }, 4491 4492 Token::MinusDot => ClauseGuard::SubFloat { 4493 location, 4494 left, 4495 right, 4496 }, 4497 4498 Token::Star => ClauseGuard::MultInt { 4499 location, 4500 left, 4501 right, 4502 }, 4503 4504 Token::StarDot => ClauseGuard::MultFloat { 4505 location, 4506 left, 4507 right, 4508 }, 4509 4510 Token::Slash => ClauseGuard::DivInt { 4511 location, 4512 left, 4513 right, 4514 }, 4515 4516 Token::SlashDot => ClauseGuard::DivFloat { 4517 location, 4518 left, 4519 right, 4520 }, 4521 4522 Token::Percent => ClauseGuard::RemainderInt { 4523 location, 4524 left, 4525 right, 4526 }, 4527 4528 _ => panic!("Token could not be converted to Guard Op."), 4529 } 4530} 4531 4532// BitArray Parse Helpers 4533// 4534// BitArrays in patterns, guards, and expressions have a very similar structure 4535// but need specific types. These are helpers for that. There is probably a 4536// rustier way to do this :) 4537fn bit_array_size_int(value: EcoString, int_value: BigInt, start: u32, end: u32) -> UntypedPattern { 4538 Pattern::BitArraySize(BitArraySize::Int { 4539 location: SrcSpan { start, end }, 4540 value, 4541 int_value, 4542 }) 4543} 4544 4545fn bit_array_expr_int(value: EcoString, int_value: BigInt, start: u32, end: u32) -> UntypedExpr { 4546 UntypedExpr::Int { 4547 location: SrcSpan { start, end }, 4548 value, 4549 int_value, 4550 } 4551} 4552 4553fn bit_array_const_int( 4554 value: EcoString, 4555 int_value: BigInt, 4556 start: u32, 4557 end: u32, 4558) -> UntypedConstant { 4559 Constant::Int { 4560 location: SrcSpan { start, end }, 4561 value, 4562 int_value, 4563 } 4564} 4565 4566fn str_to_bit_array_option<A>(lit: &str, location: SrcSpan) -> Option<BitArrayOption<A>> { 4567 match lit { 4568 "bytes" => Some(BitArrayOption::Bytes { location }), 4569 "int" => Some(BitArrayOption::Int { location }), 4570 "float" => Some(BitArrayOption::Float { location }), 4571 "bits" => Some(BitArrayOption::Bits { location }), 4572 "utf8" => Some(BitArrayOption::Utf8 { location }), 4573 "utf16" => Some(BitArrayOption::Utf16 { location }), 4574 "utf32" => Some(BitArrayOption::Utf32 { location }), 4575 "utf8_codepoint" => Some(BitArrayOption::Utf8Codepoint { location }), 4576 "utf16_codepoint" => Some(BitArrayOption::Utf16Codepoint { location }), 4577 "utf32_codepoint" => Some(BitArrayOption::Utf32Codepoint { location }), 4578 "signed" => Some(BitArrayOption::Signed { location }), 4579 "unsigned" => Some(BitArrayOption::Unsigned { location }), 4580 "big" => Some(BitArrayOption::Big { location }), 4581 "little" => Some(BitArrayOption::Little { location }), 4582 "native" => Some(BitArrayOption::Native { location }), 4583 _ => None, 4584 } 4585} 4586 4587// 4588// Error Helpers 4589// 4590fn parse_error<T>(error: ParseErrorType, location: SrcSpan) -> Result<T, ParseError> { 4591 Err(ParseError { error, location }) 4592} 4593 4594// 4595// Misc Helpers 4596// 4597 4598// Parsing a function call into the appropriate structure 4599#[derive(Debug)] 4600pub enum ParserArg { 4601 Arg(Box<CallArg<UntypedExpr>>), 4602 Hole { 4603 name: EcoString, 4604 /// The whole span of the argument. 4605 arg_location: SrcSpan, 4606 /// Just the span of the ignore name. 4607 discard_location: SrcSpan, 4608 label: Option<EcoString>, 4609 }, 4610} 4611 4612pub fn make_call( 4613 fun: UntypedExpr, 4614 arguments: Vec<ParserArg>, 4615 start: u32, 4616 end: u32, 4617) -> Result<UntypedExpr, ParseError> { 4618 let mut hole_location = None; 4619 4620 let arguments = arguments 4621 .into_iter() 4622 .map(|argument| match argument { 4623 ParserArg::Arg(arg) => Ok(*arg), 4624 ParserArg::Hole { 4625 arg_location, 4626 discard_location, 4627 name, 4628 label, 4629 } => { 4630 if hole_location.is_some() { 4631 return parse_error(ParseErrorType::TooManyArgHoles, SrcSpan { start, end }); 4632 } 4633 4634 hole_location = Some(discard_location); 4635 if name != "_" { 4636 return parse_error( 4637 ParseErrorType::UnexpectedToken { 4638 token: Token::Name { name }, 4639 expected: vec!["An expression".into(), "An underscore".into()], 4640 hint: None, 4641 }, 4642 arg_location, 4643 ); 4644 } 4645 4646 Ok(CallArg { 4647 implicit: None, 4648 label, 4649 location: arg_location, 4650 value: UntypedExpr::Var { 4651 location: discard_location, 4652 name: CAPTURE_VARIABLE.into(), 4653 }, 4654 }) 4655 } 4656 }) 4657 .collect::<Result<_, _>>()?; 4658 4659 let call = UntypedExpr::Call { 4660 location: SrcSpan { start, end }, 4661 fun: Box::new(fun), 4662 arguments, 4663 }; 4664 4665 match hole_location { 4666 // A normal call 4667 None => Ok(call), 4668 4669 // An anon function using the capture syntax run(_, 1, 2) 4670 Some(hole_location) => Ok(UntypedExpr::Fn { 4671 location: call.location(), 4672 end_of_head_byte_index: call.location().end, 4673 kind: FunctionLiteralKind::Capture { 4674 hole: hole_location, 4675 }, 4676 arguments: vec![Arg { 4677 location: hole_location, 4678 annotation: None, 4679 names: ArgNames::Named { 4680 name: CAPTURE_VARIABLE.into(), 4681 location: hole_location, 4682 }, 4683 type_: (), 4684 }], 4685 body: vec1![Statement::Expression(call)], 4686 return_annotation: None, 4687 }), 4688 } 4689} 4690 4691#[derive(Debug, Default)] 4692struct ParsedUnqualifiedImports { 4693 types: Vec<UnqualifiedImport>, 4694 values: Vec<UnqualifiedImport>, 4695} 4696 4697/// Parses an Int value to a bigint. 4698/// 4699pub fn parse_int_value(value: &str) -> Option<BigInt> { 4700 let (radix, value) = if let Some(value) = value.strip_prefix("0x") { 4701 (16, value) 4702 } else if let Some(value) = value.strip_prefix("0o") { 4703 (8, value) 4704 } else if let Some(value) = value.strip_prefix("0b") { 4705 (2, value) 4706 } else { 4707 (10, value) 4708 }; 4709 4710 let value = value.trim_start_matches('_'); 4711 4712 BigInt::parse_bytes(value.as_bytes(), radix) 4713} 4714 4715#[derive(Debug, PartialEq, Clone, Copy)] 4716enum ExpressionUnitContext { 4717 FollowingPipe, 4718 Other, 4719} 4720 4721#[derive(Debug, Clone, Copy)] 4722pub enum PatternPosition { 4723 LetAssignment, 4724 CaseClause, 4725 UsePattern, 4726} 4727 4728impl PatternPosition { 4729 pub fn to_declaration(&self) -> VariableDeclaration { 4730 match self { 4731 PatternPosition::LetAssignment => VariableDeclaration::LetPattern, 4732 PatternPosition::CaseClause => VariableDeclaration::ClausePattern, 4733 PatternPosition::UsePattern => VariableDeclaration::UsePattern, 4734 } 4735 } 4736} 4737 4738/// A thin f64 wrapper that does not permit NaN. 4739/// This allows us to implement `Eq`, which require reflexivity. 4740/// 4741/// Used for gleam float literals, which cannot be NaN. 4742/// While there is no syntax for "infinity", float literals 4743/// may overflow into (possibly negative) infinity on the JS target. 4744#[derive(Clone, Copy, Debug, PartialEq)] 4745pub struct LiteralFloatValue(f64); 4746 4747impl LiteralFloatValue { 4748 pub const ONE: Self = LiteralFloatValue(1.0); 4749 pub const ZERO: Self = LiteralFloatValue(0.0); 4750 4751 /// Parse from a string, returning `None` if the string 4752 /// is not a valid f64 or the float is `NaN`` 4753 pub fn parse(value: &str) -> Option<Self> { 4754 value 4755 .replace("_", "") 4756 .parse::<f64>() 4757 .ok() 4758 .filter(|f| !f.is_nan()) 4759 .map(LiteralFloatValue) 4760 } 4761 4762 pub fn value(&self) -> f64 { 4763 self.0 4764 } 4765} 4766 4767impl Eq for LiteralFloatValue {} 4768 4769impl Ord for LiteralFloatValue { 4770 fn cmp(&self, other: &Self) -> Ordering { 4771 self.0 4772 .partial_cmp(&other.0) 4773 .expect("Only NaN comparisons should fail") 4774 } 4775} 4776 4777impl PartialOrd for LiteralFloatValue { 4778 fn partial_cmp(&self, other: &Self) -> Option<Ordering> { 4779 Some(self.cmp(other)) 4780 } 4781} 4782 4783impl Hash for LiteralFloatValue { 4784 fn hash<H: Hasher>(&self, state: &mut H) { 4785 self.0.to_bits().hash(state) 4786 } 4787} 4788 4789impl Serialize for LiteralFloatValue { 4790 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 4791 where 4792 S: serde::Serializer, 4793 { 4794 serializer.serialize_f64(self.0) 4795 } 4796} 4797 4798impl<'de> Deserialize<'de> for LiteralFloatValue { 4799 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 4800 where 4801 D: serde::Deserializer<'de>, 4802 { 4803 let value = f64::deserialize(deserializer)?; 4804 if value.is_nan() { 4805 Err(serde::de::Error::custom("NaN is not allowed")) 4806 } else { 4807 Ok(LiteralFloatValue(value)) 4808 } 4809 } 4810}