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