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