Skip to main content

voltaic_parser/
parser.rs

1use crate::ParseError;
2
3use crate::block::check_callback_tails;
4
5use crate::block::condition;
6
7use crate::block::control_flow;
8
9use crate::block::ladder_condition;
10
11use crate::block::stmt;
12
13use crate::datatype::data_decl;
14
15use crate::datatype::derive_template;
16
17use crate::datatype::errors_decl;
18
19use crate::datatype::generalise;
20
21use crate::expr::parse_expr;
22
23use crate::expr::parse_spine;
24
25use crate::item::const_decl;
26
27use crate::item::declares_an_operator;
28
29use crate::item::extern_block;
30
31use crate::item::import_decl;
32
33use crate::item::module_decl;
34
35use crate::item::operator_decl;
36
37use crate::item::pattern_synonym;
38
39use crate::item::test_decl;
40
41use crate::item::type_alias;
42
43use crate::item::visibility;
44
45use crate::pattern::pattern_alt;
46
47use crate::pattern::patterns;
48
49use crate::signature::SignatureHead;
50
51use crate::signature::TypeStop;
52
53use crate::signature::capture_type;
54
55use crate::signature::clause;
56
57use crate::signature::signature_from;
58
59use crate::signature::signature_only;
60
61use crate::signature::signature_unsigned;
62
63use crate::support::MAX_NESTING;
64
65use crate::support::nesting_depth;
66
67use crate::token::inline_rust;
68
69use crate::type_class::class_decl;
70
71use crate::type_class::constraints;
72
73use crate::type_class::given_clause;
74
75use crate::type_class::instance_decl;
76
77use crate::where_clause::where_predicates;
78
79use voltaic_ast::Binding;
80
81use voltaic_ast::Block;
82
83use voltaic_ast::Expr;
84
85use voltaic_ast::Fixity;
86
87use voltaic_ast::FnDecl;
88
89use voltaic_ast::Guard;
90
91use voltaic_ast::Ident;
92
93use voltaic_ast::Item;
94
95use voltaic_ast::Program;
96
97use voltaic_ast::Stmt;
98
99use voltaic_ast::TypeExpr;
100
101use voltaic_ast::Visibility;
102
103use voltaic_diag::Code;
104
105use voltaic_lexer::Keyword;
106
107use voltaic_lexer::Span;
108
109use voltaic_lexer::Token;
110
111use voltaic_lexer::TokenKind;
112
113use voltaic_lexer::Trivia;
114
115pub fn parse(toks: &[Token], src_len: usize) -> Result<Program, Vec<ParseError>> {
116  let deepest = nesting_depth(toks);
117  if deepest > MAX_NESTING {
118    let message = format!(
119      "this input nests brackets {} deep, and the limit is {}: deeper than that overflows the parser's stack",
120      deepest, MAX_NESTING
121    );
122    return Err(vec![ParseError {
123      code: Code::NestingTooDeep,
124      message,
125      span: (0, 0),
126      help: None,
127    }]);
128  }
129  Parser::new(toks).run(src_len)
130}
131
132pub(crate) struct Parser<'a> {
133  toks: &'a [Token],
134  pos: usize,
135  pub(crate) r#errors: Vec<ParseError>,
136  class_heads: std::collections::BTreeMap<(String, String), SignatureHead>,
137  pub(crate) fixities: std::collections::BTreeMap<String, (Fixity, u8, String)>,
138}
139
140impl<'a> Parser<'a> {
141  pub(crate) fn new(toks: &'a [Token]) -> Self {
142    Parser {
143      toks,
144      pos: 0,
145      r#errors: Vec::new(),
146      class_heads: std::collections::BTreeMap::new(),
147      fixities: std::collections::BTreeMap::new(),
148    }
149  }
150  pub(crate) fn run(mut self, src_len: usize) -> Result<Program, Vec<ParseError>> {
151    let items = self.program();
152    if self.r#errors.is_empty() {
153      let probe = Program {
154        items: items.clone(),
155        span: (0, src_len),
156        trailing: Vec::new(),
157      };
158      self.r#errors.extend(check_callback_tails(&probe));
159    }
160    if self.r#errors.is_empty() {
161      let trailing = self.eof_trivia();
162      return Ok(Program {
163        items,
164        span: (0, src_len),
165        trailing,
166      });
167    }
168    Err(self.r#errors)
169  }
170  fn program(&mut self) -> Vec<Item> {
171    let mut items = Vec::new();
172    self.skip_separators();
173    while !self.at_eof() {
174      match self.item() {
175        Ok(found) => items.push(found),
176        Err(e) => {
177          self.r#errors.push(e);
178          self.recover_to_item()
179        }
180      };
181      self.skip_separators();
182    }
183    items
184  }
185  pub(crate) fn items_until_dedent(&mut self) -> Result<Vec<Item>, ParseError> {
186    let mut items = Vec::new();
187    loop {
188      self.skip_separators();
189      if self.check(&TokenKind::Dedent) || self.at_eof() {
190        break;
191      }
192      match self.item() {
193        Ok(found) => items.push(found),
194        Err(e) => {
195          self.r#errors.push(e);
196          self.recover_to_item()
197        }
198      };
199    }
200    self.expect(&TokenKind::Dedent, "expected the module body to end")?;
201    Ok(items)
202  }
203  pub(crate) fn item(&mut self) -> Result<Item, ParseError> {
204    let leading = self.peek_leading();
205    let start = self.peek_span().0;
206    let marker = visibility(self)?;
207    if self.check(&TokenKind::Kw(Keyword::Data))
208      || self.check(&TokenKind::Kw(Keyword::Newtype))
209      || self.check(&TokenKind::Kw(Keyword::Union))
210    {
211      let decl = data_decl(self, leading, start, marker)?;
212      self.newline_with_trailing("expected a line break after the declaration")?;
213      return Ok(Item::Data(decl));
214    }
215    if self.check(&TokenKind::Kw(Keyword::Type)) {
216      let alias = type_alias(self, leading, start, marker)?;
217      self.newline_with_trailing("expected a line break after the alias")?;
218      return Ok(Item::Type(alias));
219    }
220    if self.check(&TokenKind::Kw(Keyword::Const)) || self.check(&TokenKind::Kw(Keyword::Static)) {
221      let decl = const_decl(self, leading, start, marker)?;
222      self.newline_with_trailing("expected a line break after the binding")?;
223      return Ok(Item::Const(decl));
224    }
225    if self.check(&TokenKind::Kw(Keyword::Import)) {
226      let decl = import_decl(self, leading, start, marker)?;
227      self.newline_with_trailing("expected a line break after the import")?;
228      return Ok(Item::Import(decl));
229    }
230    if self.check(&TokenKind::Kw(Keyword::Module)) {
231      let decl = module_decl(self, leading, start, marker)?;
232      self.newline_with_trailing("expected a line break after the module")?;
233      return Ok(Item::Module(decl));
234    }
235    if self.check(&TokenKind::Kw(Keyword::Test)) {
236      let decl = test_decl(self, leading, start)?;
237      self.newline_with_trailing("expected a line break after the test")?;
238      return Ok(Item::Test(decl));
239    }
240    if self.check(&TokenKind::Kw(Keyword::Rust)) {
241      let block = inline_rust(self, leading, start)?;
242      self.newline_with_trailing("expected a line break after the inline Rust")?;
243      return Ok(Item::InlineRust(block));
244    }
245    let word_is_pattern = match &self.peek().kind {
246      TokenKind::Ident(text) => text == "pattern",
247      _ => false,
248    };
249    let names_a_constructor = self.peek_at(1).is_some_and(|t| match &t.kind {
250      TokenKind::Ident(next) => next.chars().next().is_some_and(char::is_uppercase),
251      _ => false,
252    });
253    if word_is_pattern && names_a_constructor {
254      let decl = pattern_synonym(self, leading, start)?;
255      return Ok(Item::PatternSynonym(decl));
256    }
257    if declares_an_operator(self) {
258      let decl = operator_decl(self, leading, start)?;
259      return Ok(Item::OperatorDecl(decl));
260    }
261    if self.check(&TokenKind::Kw(Keyword::Deriving)) {
262      let decl = derive_template(self, leading, start)?;
263      self.newline_with_trailing("expected a line break after the deriving template")?;
264      return Ok(Item::DeriveTemplate(decl));
265    }
266    if self.check(&TokenKind::Kw(Keyword::Extern)) {
267      let block = extern_block(self, leading, start)?;
268      return Ok(Item::Extern(block));
269    }
270    if self.check(&TokenKind::Kw(Keyword::Errors)) {
271      let decl = errors_decl(self, leading, start, marker)?;
272      self.newline_with_trailing("expected a line break after the declaration")?;
273      return Ok(Item::Errors(decl));
274    }
275    if self.check(&TokenKind::Kw(Keyword::Class)) {
276      let decl = class_decl(self, leading, start, marker)?;
277      self.newline_with_trailing("expected a line break after the class")?;
278      return Ok(Item::Class(decl));
279    }
280    if self.check(&TokenKind::Kw(Keyword::Instance)) {
281      let decl = instance_decl(self, leading, start)?;
282      self.newline_with_trailing("expected a line break after the instance")?;
283      return Ok(Item::Instance(decl));
284    }
285    let mut decl = self.function(&[])?;
286    decl.leading = leading;
287    decl.visibility = marker;
288    decl.span = (start, decl.span.1);
289    Ok(Item::Fn(decl))
290  }
291  pub(crate) fn function(&mut self, reserved: &[String]) -> Result<FnDecl, ParseError> {
292    let leading = self.peek_leading();
293    let start = self.peek_span().0;
294    if !self.signed() {
295      let name = self.peeked_name("expected a name to begin a declaration")?;
296      return self.unsigned_equations(name, leading, start, reserved, false);
297    }
298    let name = self.ident("expected a name to begin a declaration")?;
299    let head = self.signature_head(&name)?;
300    let decl = self.equations(name.clone(), leading, start, &head, reserved, true)?;
301    if decl.clauses.is_empty() {
302      let message = format!(
303        "`{}` has a signature and no equations; write its body, or delete the signature and let it be inferred",
304        name.text
305      );
306      return Err(ParseError::r#with(Code::EmptyBody, message, name.span));
307    }
308    Ok(decl)
309  }
310  pub(crate) fn where_function(&mut self) -> Result<FnDecl, ParseError> {
311    let leading = self.peek_leading();
312    let start = self.peek_span().0;
313    if !self.signed() {
314      let name = self.peeked_name("expected a name to begin a declaration")?;
315      return self.unsigned_equations(name, leading, start, &[], true);
316    }
317    let name = self.ident("expected a name to begin a declaration")?;
318    let head = self.signature_head(&name)?;
319    self.equations(name, leading, start, &head, &[], true)
320  }
321  pub(crate) fn signed(&self) -> bool {
322    match &self.peek().kind {
323      TokenKind::Ident(_) => self.peek_at(1).is_some_and(|t| t.kind == TokenKind::Colon),
324      _ => true,
325    }
326  }
327  pub(crate) fn peeked_name(&self, message: &str) -> Result<Ident, ParseError> {
328    match &self.peek().kind {
329      TokenKind::Ident(text) => Ok(Ident {
330        text: text.clone(),
331        span: self.peek_span(),
332      }),
333      _ => Err(ParseError::r#with(
334        Code::ExpectedName,
335        message.to_string(),
336        self.peek_span(),
337      )),
338    }
339  }
340  pub(crate) fn signature_head(&mut self, name: &Ident) -> Result<SignatureHead, ParseError> {
341    let binds_on_this_line = self.check(&TokenKind::Eq)
342      && self
343        .peek_at(1)
344        .is_some_and(|t| t.kind != TokenKind::Newline);
345    if binds_on_this_line {
346      let message = format!(
347        "a module-scope binding needs `const` or `static` and a type: `const {} : T = …`. Rust forbids `let` at module scope, and doc 03 §13.4 corrects doc 01 §4.3 accordingly",
348        name.text
349      );
350      return Err(ParseError::r#with(
351        Code::ModuleScopeBinding,
352        message,
353        name.span,
354      ));
355    }
356    self.expect(
357      &TokenKind::Colon,
358      "expected `:` after the name, to begin the signature",
359    )?;
360    let binder = given_clause(self)?;
361    let bounds = if binder.is_some() {
362      Vec::new()
363    } else {
364      constraints(self)?
365    };
366    let is_const = self.eat_keyword(Keyword::Const);
367    let is_async = self.eat_keyword(Keyword::Async);
368    let is_unsafe = self.eat_keyword(Keyword::Unsafe);
369    let spine = parse_spine(self)?;
370    let predicates = where_predicates(self)?;
371    self.newline_with_trailing("expected a line break after the signature")?;
372    Ok(SignatureHead {
373      types: spine,
374      bounds,
375      r#given: binder,
376      predicates,
377      is_const,
378      is_async,
379      is_unsafe,
380    })
381  }
382  pub(crate) fn record_head(&mut self, class_name: &str, member: &str, head: &SignatureHead) {
383    let key = (class_name.to_string(), member.to_string());
384    self.class_heads.insert(key, head.clone());
385    ();
386  }
387  pub(crate) fn borrowed_head(&self, class_name: &str, member: &str) -> Option<SignatureHead> {
388    let key = (class_name.to_string(), member.to_string());
389    self.class_heads.get(&key).cloned()
390  }
391  pub(crate) fn equations(
392    &mut self,
393    name: Ident,
394    leading: Vec<Trivia>,
395    start: usize,
396    head: &SignatureHead,
397    reserved: &[String],
398    ends_on_a_new_name: bool,
399  ) -> Result<FnDecl, ParseError> {
400    let spine = &head.types;
401    let bounds = &head.bounds;
402    let mut clauses = Vec::new();
403    let mut sig = None;
404    loop {
405      let is_equation = match &self.peek().kind {
406        TokenKind::Ident(_) => !self.peek_at(1).is_some_and(|t| t.kind == TokenKind::Colon),
407        _ => false,
408      };
409      if !is_equation {
410        break;
411      }
412      if declares_an_operator(self) {
413        break;
414      }
415      let same_name = match &self.peek().kind {
416        TokenKind::Ident(text) if text == &name.text => true,
417        _ => false,
418      };
419      if ends_on_a_new_name && !same_name {
420        break;
421      }
422      let again = self.ident("expected the equation to repeat the name")?;
423      if again.text != name.text {
424        let message = format!(
425          "this equation defines `{}`, but the signature above it is for `{}`",
426          again.text, name.text
427        );
428        return Err(ParseError::r#with(Code::ExpectedName, message, again.span));
429      }
430      let row = patterns(self)?;
431      let built = signature_from(spine, &row, (again.span.0, self.prev_span().1))?;
432      let returns_unit = built.returns_unit();
433      if sig.is_none() {
434        sig = Some(built);
435      }
436      clauses.push(clause(row, &name, returns_unit, self)?);
437      self.skip_separators();
438    }
439    let mut settled =
440      sig.unwrap_or_else(|| signature_only(spine, (name.span.0, self.prev_span().1)));
441    settled.r#given = head.r#given.clone();
442    settled.predicates = head.predicates.clone();
443    generalise(&mut settled, bounds, reserved);
444    settled.is_const = head.is_const;
445    settled.is_async = head.is_async;
446    settled.is_unsafe = head.is_unsafe;
447    let end = self.prev_span().1;
448    let trailing = clauses.last().and_then(|c| c.trailing.clone());
449    Ok(FnDecl {
450      name,
451      sig: settled,
452      clauses,
453      visibility: Visibility::Private,
454      span: (start, end),
455      leading,
456      trailing,
457    })
458  }
459  pub(crate) fn unsigned_equations(
460    &mut self,
461    name: Ident,
462    leading: Vec<Trivia>,
463    start: usize,
464    reserved: &[String],
465    ends_on_a_new_name: bool,
466  ) -> Result<FnDecl, ParseError> {
467    if self.check(&TokenKind::Eq)
468      && self
469        .peek_at(1)
470        .is_some_and(|t| t.kind != TokenKind::Newline)
471    {
472      let message = format!(
473        "a module-scope binding needs `const` or `static` and a type: `const {} : T = …`. Rust forbids `let` at module scope, and doc 03 §13.4 corrects doc 01 §4.3 accordingly",
474        name.text
475      );
476      return Err(ParseError::r#with(
477        Code::ModuleScopeBinding,
478        message,
479        name.span,
480      ));
481    }
482    let mut clauses = Vec::new();
483    let mut sig = None;
484    loop {
485      let is_equation = match &self.peek().kind {
486        TokenKind::Ident(_) => !self.peek_at(1).is_some_and(|t| t.kind == TokenKind::Colon),
487        _ => false,
488      };
489      if !is_equation {
490        break;
491      }
492      if declares_an_operator(self) {
493        break;
494      }
495      let same_name = match &self.peek().kind {
496        TokenKind::Ident(text) if text == &name.text => true,
497        _ => false,
498      };
499      if !same_name && (ends_on_a_new_name || !clauses.is_empty()) {
500        break;
501      }
502      let again = self.ident("expected the equation to repeat the name")?;
503      if again.text != name.text {
504        let message = format!(
505          "this equation defines `{}`, but the one above it defines `{}`",
506          again.text, name.text
507        );
508        return Err(ParseError::r#with(Code::ExpectedName, message, again.span));
509      }
510      let row = patterns(self)?;
511      if self.check(&TokenKind::Eq)
512        && self
513          .peek_at(1)
514          .is_some_and(|t| t.kind != TokenKind::Newline)
515        && row.is_empty()
516      {
517        let message = format!(
518          "a module-scope binding needs `const` or `static` and a type: `const {} : T = …`. Rust forbids `let` at module scope, and doc 03 §13.4 corrects doc 01 §4.3 accordingly",
519          name.text
520        );
521        return Err(ParseError::r#with(
522          Code::ModuleScopeBinding,
523          message,
524          again.span,
525        ));
526      }
527      let built = signature_unsigned(&row, (again.span.0, self.prev_span().1));
528      if sig.is_none() {
529        sig = Some(built);
530      }
531      clauses.push(clause(row, &name, false, self)?);
532      self.skip_separators();
533    }
534    let mut settled =
535      sig.unwrap_or_else(|| signature_unsigned(&[], (name.span.0, self.prev_span().1)));
536    generalise(&mut settled, &[], reserved);
537    let end = self.prev_span().1;
538    let trailing = clauses.last().and_then(|c| c.trailing.clone());
539    Ok(FnDecl {
540      name,
541      sig: settled,
542      clauses,
543      visibility: Visibility::Private,
544      span: (start, end),
545      leading,
546      trailing,
547    })
548  }
549  pub(crate) fn statements(&mut self) -> Result<Block, ParseError> {
550    let start = self.peek_span().0;
551    let mut stmts = Vec::new();
552    loop {
553      self.skip_separators();
554      if self.check(&TokenKind::Dedent) || self.at_eof() {
555        break;
556      }
557      match stmt(self) {
558        Ok(found) => stmts.push(found),
559        Err(e) => {
560          self.r#errors.push(e);
561          self.recover_to_stmt()
562        }
563      };
564    }
565    let end = self.prev_span().1;
566    self.expect(&TokenKind::Dedent, "expected the body to end")?;
567    if stmts.is_empty() && self.r#errors.is_empty() {
568      return Err(ParseError::r#with(
569        Code::EmptyBody,
570        "a declaration body must contain at least one statement",
571        (start, start),
572      ));
573    }
574    Ok(Block {
575      stmts,
576      span: (start, end),
577    })
578  }
579  pub(crate) fn indented_block(&mut self, code: Code, message: &str) -> Result<Block, ParseError> {
580    self.expect_with(code, &TokenKind::Indent, message)?;
581    self.statements()
582  }
583  pub(crate) fn statement_block(&mut self, message: &str) -> Result<Block, ParseError> {
584    self.newline_with_trailing("expected a line break before the body")?;
585    self.indented_block(Code::EmptyBody, message)
586  }
587  pub(crate) fn at_statement_end(&self) -> bool {
588    self.check(&TokenKind::Newline) || self.check(&TokenKind::Dedent) || self.at_eof()
589  }
590  pub(crate) fn if_statement(&mut self) -> Result<Expr, ParseError> {
591    let open = self.peek_span().0;
592    self.expect(&TokenKind::Kw(Keyword::If), "expected `if`")?;
593    let cond = condition(self)?;
594    let then_block = self.statement_block("expected an indented `if` body")?;
595    self.skip_separators();
596    if !self.check(&TokenKind::Kw(Keyword::Else)) {
597      return Ok(Expr::If {
598        condition: cond,
599        then_block,
600        r#otherwise: None,
601        span: (open, self.prev_span().1),
602      });
603    }
604    self.advance();
605    if self.check(&TokenKind::Kw(Keyword::If)) {
606      let start = self.peek_span().0;
607      let nested = self.if_statement()?;
608      let end = self.prev_span().1;
609      let only = Stmt {
610        expr: nested,
611        span: (start, end),
612        leading: Vec::new(),
613        trailing: None,
614      };
615      let chained = Block {
616        stmts: vec![only],
617        span: (start, end),
618      };
619      return Ok(Expr::If {
620        condition: cond,
621        then_block,
622        r#otherwise: Some(chained),
623        span: (open, end),
624      });
625    }
626    let fallback = self.statement_block("expected an indented `else` body")?;
627    Ok(Expr::If {
628      condition: cond,
629      then_block,
630      r#otherwise: Some(fallback),
631      span: (open, self.prev_span().1),
632    })
633  }
634  pub(crate) fn inline_body(&mut self) -> Result<Block, ParseError> {
635    let start = self.peek_span().0;
636    let value = parse_expr(self, 0)?;
637    let end = self.prev_span().1;
638    let only = Stmt {
639      expr: value,
640      span: (start, end),
641      leading: Vec::new(),
642      trailing: None,
643    };
644    Ok(Block {
645      stmts: vec![only],
646      span: (start, end),
647    })
648  }
649  pub(crate) fn opens_a_guard_list(&self) -> bool {
650    self.check(&TokenKind::Newline)
651      && self.peek_at(1).is_some_and(|t| t.kind == TokenKind::Indent)
652      && self.peek_at(2).is_some_and(|t| t.kind == TokenKind::Or)
653  }
654  pub(crate) fn guards(&mut self) -> Result<Vec<Guard>, ParseError> {
655    let mut rows = Vec::new();
656    loop {
657      self.skip_separators();
658      if !self.check(&TokenKind::Or) {
659        break;
660      }
661      let start = self.peek_span().0;
662      self.advance();
663      if self.names_the_retired_catch_all() {
664        let message = "`otherwise` is no longer the catch-all arm of a guard ladder".to_string();
665        return Err(ParseError::with_help(
666          Code::RetiredSpelling,
667          message,
668          "write `_`, which is the same wildcard a `case` arm and a parameter pattern use. Row 99 wave 2 deleted the keyword: one spelling for one meaning",
669          self.peek_span(),
670        ));
671      }
672      let cond = if self.is_wildcard() {
673        self.advance();
674        None
675      } else {
676        Some(ladder_condition(self)?)
677      };
678      self.expect(&TokenKind::Eq, "expected `=` after a guard's condition")?;
679      let body = self.inline_body()?;
680      self.newline_with_trailing("expected a line break after a guard's body")?;
681      rows.push(Guard {
682        condition: cond,
683        body,
684        span: (start, self.prev_span().1),
685      });
686    }
687    debug_assert!(
688      !rows.is_empty(),
689      "`opens_a_guard_list` guarantees a first `|`"
690    );
691    Ok(rows)
692  }
693  pub(crate) fn is_wildcard(&self) -> bool {
694    match &self.peek().kind {
695      TokenKind::Ident(text) if text == "_" => true,
696      _ => false,
697    }
698  }
699  pub(crate) fn names_the_retired_catch_all(&self) -> bool {
700    if !self.peek_at(1).is_some_and(|t| t.kind == TokenKind::Eq) {
701      return false;
702    }
703    match &self.peek().kind {
704      TokenKind::Ident(text) if text == "otherwise" => true,
705      _ => false,
706    }
707  }
708  pub(crate) fn try_draw(&mut self) -> Result<Option<Expr>, ParseError> {
709    if !self.check(&TokenKind::Kw(Keyword::With)) {
710      return Ok(None);
711    }
712    let start = self.peek_span().0;
713    self.advance();
714    let name = self.ident("expected a name after `with`")?;
715    self.expect(
716      &TokenKind::Eq,
717      "expected `=` after a `with` binder — doc 30 §3.3",
718    )?;
719    let value = Box::new(parse_expr(self, 0)?);
720    Ok(Some(Expr::Draw {
721      name,
722      value,
723      span: (start, self.prev_span().1),
724    }))
725  }
726  pub(crate) fn try_binding(&mut self) -> Result<Option<Binding>, ParseError> {
727    let is_mut = self.check(&TokenKind::Kw(Keyword::Mut));
728    if !is_mut && !self.looks_like_a_binding() {
729      return Ok(None);
730    }
731    let start = self.peek_span().0;
732    if is_mut {
733      self.advance();
734    }
735    let bound = pattern_alt(self)?;
736    let ty = if self.check(&TokenKind::Colon) {
737      self.advance();
738      Some(self.type_expr("expected a type after `:`")?)
739    } else {
740      None
741    };
742    self.expect(&TokenKind::Eq, "expected `=` in a binding")?;
743    let value = self.value_or_ladder()?;
744    let fallback = self.else_tail()?;
745    Ok(Some(Binding {
746      pattern: bound,
747      ty,
748      value,
749      is_mut,
750      r#otherwise: fallback,
751      span: (start, self.prev_span().1),
752    }))
753  }
754  pub(crate) fn else_tail(&mut self) -> Result<Option<Block>, ParseError> {
755    if !self.check(&TokenKind::Kw(Keyword::Else)) {
756      return Ok(None);
757    }
758    self.advance();
759    if self.check(&TokenKind::Newline) {
760      return self
761        .statement_block("expected an indented `else` body after the binding")
762        .map(Some);
763    }
764    let start = self.peek_span().0;
765    if self.check(&TokenKind::Kw(Keyword::Return)) {
766      self.advance();
767      let value = if self.at_statement_end() {
768        None
769      } else {
770        Some(Box::new(parse_expr(self, 0)?))
771      };
772      return Ok(Some(self.one_statement(
773        Expr::Return {
774          value,
775          span: (start, self.prev_span().1),
776        },
777        start,
778      )));
779    }
780    if let Some(diverging) = control_flow(self)? {
781      return Ok(Some(self.one_statement(diverging, start)));
782    }
783    self.inline_body().map(Some)
784  }
785  fn one_statement(&self, expr: Expr, start: usize) -> Block {
786    let end = self.prev_span().1;
787    let only = Stmt {
788      expr,
789      span: (start, end),
790      leading: Vec::new(),
791      trailing: None,
792    };
793    Block {
794      stmts: vec![only],
795      span: (start, end),
796    }
797  }
798  pub(crate) fn value_or_ladder(&mut self) -> Result<Expr, ParseError> {
799    if !self.opens_a_guard_list() {
800      return parse_expr(self, 0);
801    }
802    let start = self.peek_span().0;
803    self.advance();
804    self.advance();
805    let rows = self.guards()?;
806    self.expect(&TokenKind::Dedent, "expected the ladder to end")?;
807    Ok(Expr::Ladder {
808      rows,
809      span: (start, self.prev_span().1),
810    })
811  }
812  fn looks_like_a_binding(&self) -> bool {
813    match &self.peek().kind {
814      TokenKind::Ident(_) => {
815        let opener = if let Some(next) = self.peek_at(1) {
816          match next.kind {
817            TokenKind::Eq | TokenKind::Colon | TokenKind::LBrace => true,
818            _ => false,
819          }
820        } else {
821          false
822        };
823        (opener || self.reaches_an_else_tail()) && self.reaches_a_binding_eq()
824      }
825      TokenKind::LParen | TokenKind::LBracket => self.reaches_a_binding_eq(),
826      _ => false,
827    }
828  }
829  pub(crate) fn reaches_an_else_tail(&self) -> bool {
830    let mut depth: i32 = 0;
831    let mut i = 0;
832    let mut past_eq = false;
833    while let Some(tok) = self.peek_at(i) {
834      match &tok.kind {
835        TokenKind::Eq if depth == 0 => {
836          past_eq = true;
837        }
838        TokenKind::Kw(Keyword::Else) if depth == 0 && past_eq => {
839          return true;
840        }
841        TokenKind::LParen | TokenKind::LBracket | TokenKind::LBrace => depth += 1,
842        TokenKind::RParen | TokenKind::RBracket | TokenKind::RBrace => {
843          depth -= 1;
844          if depth < 0 {
845            return false;
846          }
847        }
848        TokenKind::Newline | TokenKind::Indent | TokenKind::Dedent | TokenKind::Eof => {
849          return false;
850        }
851        _ => (),
852      };
853      i += 1;
854    }
855    false
856  }
857  pub(crate) fn reaches_a_binding_eq(&self) -> bool {
858    let mut depth: i32 = 0;
859    let mut i = 0;
860    while let Some(tok) = self.peek_at(i) {
861      match &tok.kind {
862        TokenKind::Eq if depth == 0 => {
863          return true;
864        }
865        TokenKind::LParen | TokenKind::LBracket | TokenKind::LBrace => depth += 1,
866        TokenKind::RParen | TokenKind::RBracket | TokenKind::RBrace => {
867          depth -= 1;
868          if depth < 0 {
869            return false;
870          }
871        }
872        TokenKind::Newline | TokenKind::Indent | TokenKind::Dedent | TokenKind::Eof => {
873          return false;
874        }
875        _ => (),
876      };
877      i += 1;
878    }
879    false
880  }
881  pub(crate) fn type_expr(&mut self, message: &str) -> Result<TypeExpr, ParseError> {
882    capture_type(self, message, TypeStop::Greedy)
883  }
884
885  pub(crate) fn peek(&self) -> &'a Token {
886    self.toks.get(self.pos).unwrap_or_else(|| {
887      self
888        .toks
889        .last()
890        .expect("the token stream always contains at least Eof")
891    })
892  }
893  pub(crate) fn peek_at(&self, n: usize) -> Option<&'a Token> {
894    self.toks.get(self.pos + n)
895  }
896  pub(crate) fn peek_span(&self) -> Span {
897    self.peek().span
898  }
899  pub(crate) fn peek_leading(&self) -> Vec<Trivia> {
900    self.peek().leading.clone()
901  }
902  pub(crate) fn prev_span(&self) -> Span {
903    if self.pos == 0 {
904      return (0, 0);
905    }
906    self.toks[self.pos - 1].span
907  }
908  pub(crate) fn at_eof(&self) -> bool {
909    match self.peek().kind {
910      TokenKind::Eof => true,
911      _ => false,
912    }
913  }
914  pub(crate) fn check(&self, kind: &TokenKind) -> bool {
915    &self.peek().kind == kind
916  }
917  pub(crate) fn advance(&mut self) {
918    if !self.at_eof() {
919      self.pos += 1;
920    }
921    ();
922  }
923  pub(crate) fn expect(&mut self, kind: &TokenKind, message: &str) -> Result<(), ParseError> {
924    self.expect_with(Code::ExpectedToken, kind, message)
925  }
926  pub(crate) fn expect_with(
927    &mut self,
928    code: Code,
929    kind: &TokenKind,
930    message: &str,
931  ) -> Result<(), ParseError> {
932    if self.check(kind) {
933      self.advance();
934      return Ok(());
935    }
936    Err(ParseError::r#with(code, message, self.peek_span()))
937  }
938  pub(crate) fn eat_keyword(&mut self, kw: Keyword) -> bool {
939    if self.check(&TokenKind::Kw(kw)) {
940      self.advance();
941      return true;
942    }
943    false
944  }
945  pub(crate) fn position(&self) -> usize {
946    self.pos
947  }
948  pub(crate) fn rewind(&mut self, mark: usize) {
949    self.pos = mark;
950    ();
951  }
952  pub(crate) fn try_ident(&mut self) -> Option<Ident> {
953    if let TokenKind::Ident(text) = &self.peek().kind {
954      let found = Ident {
955        text: text.clone(),
956        span: self.peek_span(),
957      };
958      self.advance();
959      return Some(found);
960    }
961    None
962  }
963  pub(crate) fn ident(&mut self, message: &str) -> Result<Ident, ParseError> {
964    if let TokenKind::Ident(text) = &self.peek().kind {
965      let found = Ident {
966        text: text.clone(),
967        span: self.peek_span(),
968      };
969      self.advance();
970      return Ok(found);
971    }
972    Err(ParseError::r#with(
973      Code::ExpectedName,
974      message,
975      self.peek_span(),
976    ))
977  }
978  pub(crate) fn newline_with_trailing(
979    &mut self,
980    message: &str,
981  ) -> Result<Option<Trivia>, ParseError> {
982    if self.check(&TokenKind::Newline) {
983      let trailing = self.peek().trailing.clone();
984      self.advance();
985      return Ok(trailing);
986    }
987    if self.at_eof() || self.check(&TokenKind::Dedent) || self.just_dedented() {
988      return Ok(None);
989    }
990    Err(ParseError::expected(message, self.peek_span()))
991  }
992  pub(crate) fn just_dedented(&self) -> bool {
993    self
994      .pos
995      .checked_sub(1)
996      .and_then(|i| self.toks.get(i))
997      .is_some_and(|t| t.kind == TokenKind::Dedent)
998  }
999  pub(crate) fn skip_separators(&mut self) {
1000    while self.check(&TokenKind::Newline) {
1001      self.advance();
1002    }
1003    ();
1004  }
1005  pub(crate) fn skip_layout(&mut self) {
1006    while self.check(&TokenKind::Newline)
1007      || self.check(&TokenKind::Indent)
1008      || self.check(&TokenKind::Dedent)
1009    {
1010      self.advance();
1011    }
1012    ();
1013  }
1014  fn eof_trivia(&self) -> Vec<Trivia> {
1015    let Some(last) = self.toks.last() else {
1016      return Vec::new();
1017    };
1018    let ends = match last.kind {
1019      TokenKind::Eof => true,
1020      _ => false,
1021    };
1022    if !ends {
1023      return Vec::new();
1024    }
1025    last.leading.clone()
1026  }
1027  fn recover_to_item(&mut self) {
1028    let mut depth: usize = 0;
1029    let mut running = true;
1030    while running {
1031      match &self.peek().kind {
1032        TokenKind::Eof => running = false,
1033        TokenKind::Indent => {
1034          depth += 1;
1035          self.advance()
1036        }
1037        TokenKind::Dedent => {
1038          depth = depth.saturating_sub(1);
1039          self.advance()
1040        }
1041        TokenKind::Ident(_) if depth == 0 => running = false,
1042        _ => self.advance(),
1043      };
1044    }
1045    ();
1046  }
1047  fn recover_to_stmt(&mut self) {
1048    let mut depth: usize = 0;
1049    let mut running = true;
1050    while running {
1051      match &self.peek().kind {
1052        TokenKind::Eof => running = false,
1053        TokenKind::Newline if depth == 0 => {
1054          self.advance();
1055          running = false;
1056        }
1057        TokenKind::Dedent if depth == 0 => running = false,
1058        TokenKind::Indent => {
1059          depth += 1;
1060          self.advance()
1061        }
1062        TokenKind::Dedent => {
1063          depth = depth.saturating_sub(1);
1064          self.advance()
1065        }
1066        _ => self.advance(),
1067      };
1068    }
1069    ();
1070  }
1071}