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