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