bend/imp/
parser.rs

1use crate::{
2  fun::{
3    parser::{is_num_char, make_ctr_type, make_fn_type, Indent, ParseResult, ParserCommons},
4    Adt, AdtCtr, CtrField, HvmDefinition, Name, Num, Op, Source, SourceKind, Type, STRINGS,
5  },
6  imp::{AssignPattern, Definition, Expr, InPlaceOp, MatchArm, Stmt},
7  maybe_grow,
8};
9use TSPL::Parser;
10
11pub struct ImpParser<'i> {
12  pub file: Name,
13  pub input: &'i str,
14  pub index: usize,
15  pub builtin: bool,
16}
17
18impl<'a> ImpParser<'a> {
19  pub fn new(file: Name, input: &'a str, builtin: bool) -> Self {
20    Self { file, input, index: 0, builtin }
21  }
22
23  pub fn parse_function_def(&mut self, indent: Indent) -> ParseResult<(Definition, Indent)> {
24    // def name(arg1: type1, arg2: type2, ...) -> type:
25    //   body
26    if indent != Indent::Val(0) {
27      let msg = "Indentation error. Functions defined with 'def' must be at the start of the line.";
28      let idx = *self.index();
29      return self.with_ctx(Err(msg), idx..idx + 1);
30    }
31    // TODO: checked vs unchecked functions
32    let (mut def, nxt_indent) = self.parse_def_aux(indent)?;
33    def.source.kind = if self.builtin { SourceKind::Builtin } else { SourceKind::User };
34    Ok((def, nxt_indent))
35  }
36
37  pub fn parse_type_def(&mut self, mut indent: Indent) -> ParseResult<(Adt, Indent)> {
38    if indent != Indent::Val(0) {
39      let msg = "Indentation error. Types defined with 'type' must be at the start of the line.";
40      let idx = *self.index();
41      return self.with_ctx(Err(msg), idx..idx + 1);
42    }
43    let ini_idx = *self.index();
44
45    self.parse_keyword("type")?;
46    self.skip_trivia_inline()?;
47
48    let type_name = self.parse_restricted_name("datatype")?;
49    self.skip_trivia_inline()?;
50
51    let type_vars = if self.try_consume_exactly("(") {
52      self.list_like(|p| p.parse_var_name(), "", ")", ",", true, 0)?
53    } else {
54      vec![]
55    };
56    self.skip_trivia_inline()?;
57
58    self.consume_exactly(":")?;
59    self.consume_new_line()?;
60    indent.enter_level();
61    self.consume_indent_exactly(indent)?;
62
63    let mut ctrs = Vec::new();
64    let mut nxt_indent = indent;
65    while nxt_indent == indent {
66      ctrs.push(self.parse_type_def_variant(&type_name, &type_vars)?);
67      if !self.is_eof() {
68        self.consume_new_line()?;
69      }
70      nxt_indent = self.consume_indent_at_most(indent)?;
71    }
72    indent.exit_level();
73
74    let ctrs = ctrs.into_iter().map(|ctr| (ctr.name.clone(), ctr)).collect();
75    let source = Source::from_file_span(&self.file, self.input, ini_idx..self.index, self.builtin);
76    let adt = Adt { name: type_name, vars: type_vars, ctrs, source };
77
78    Ok((adt, nxt_indent))
79  }
80
81  pub fn parse_object(&mut self, indent: Indent) -> ParseResult<(Adt, Indent)> {
82    // object Pair(a, b) { fst: a, snd: b }
83    if indent != Indent::Val(0) {
84      let msg = "Indentation error. Types defined with 'object' must be at the start of the line.";
85      let idx = *self.index();
86      return self.with_ctx(Err(msg), idx..idx + 1);
87    }
88    let ini_idx = *self.index();
89
90    self.parse_keyword("object")?;
91    self.skip_trivia_inline()?;
92
93    let name = self.parse_top_level_name()?;
94    self.skip_trivia_inline()?;
95
96    let type_vars = if self.starts_with("(") {
97      self.list_like(|p| p.parse_var_name(), "(", ")", ",", true, 0)?
98    } else {
99      vec![]
100    };
101    self.skip_trivia_inline()?;
102
103    let fields = if self.starts_with("{") {
104      self.list_like(|p| p.parse_variant_field(), "{", "}", ",", true, 0)?
105    } else {
106      vec![]
107    };
108    let field_types = fields.iter().map(|f| f.typ.clone()).collect::<Vec<_>>();
109
110    let end_idx = *self.index();
111    self.check_repeated_ctr_fields(&fields, &name, ini_idx..end_idx)?;
112
113    if !self.is_eof() {
114      self.consume_new_line()?;
115    }
116    let nxt_indent = self.advance_newlines()?;
117
118    let typ = make_ctr_type(name.clone(), &field_types, &type_vars);
119    let ctr = AdtCtr { name: name.clone(), typ, fields };
120
121    let ctrs = [(name.clone(), ctr)].into_iter().collect();
122    let source = Source::from_file_span(&self.file, self.input, ini_idx..end_idx, self.builtin);
123    let adt = Adt { name, vars: type_vars, ctrs, source };
124    Ok((adt, nxt_indent))
125  }
126
127  pub fn parse_hvm(&mut self) -> ParseResult<(HvmDefinition, Indent)> {
128    let ini_idx = *self.index();
129
130    self.parse_keyword("hvm")?;
131    self.skip_trivia_inline()?;
132
133    let name = self.parse_var_name()?;
134    self.skip_trivia_inline()?;
135
136    let typ = self.parse_return_type()?.unwrap_or(Type::Any);
137    let typ = make_fn_type(vec![], typ);
138    self.skip_trivia_inline()?;
139
140    self.consume_exactly(":")?;
141    self.consume_new_line()?;
142
143    // TODO: This will have the wrong index
144    let net_idx = *self.index();
145    let mut p = hvm::ast::CoreParser::new(&self.input[net_idx..]);
146    let body = p.parse_net()?;
147    *self.index() = net_idx + *p.index();
148
149    let source = Source::from_file_span(&self.file, self.input, ini_idx..self.index, self.builtin);
150    let def = HvmDefinition { name: name.clone(), typ, body, source };
151    let nxt_indent = self.advance_newlines()?;
152    Ok((def, nxt_indent))
153  }
154
155  fn parse_type_def_variant(&mut self, type_name: &Name, type_vars: &[Name]) -> ParseResult<AdtCtr> {
156    let ini_idx = *self.index();
157    let name = self.parse_top_level_name()?;
158    let name = Name::new(format!("{type_name}/{name}"));
159    self.skip_trivia_inline()?;
160
161    let fields = if self.try_consume_exactly("{") {
162      self.list_like(|p| p.parse_variant_field(), "", "}", ",", true, 0)?
163    } else {
164      vec![]
165    };
166    let field_types = fields.iter().map(|f| f.typ.clone()).collect::<Vec<_>>();
167    let end_idx = *self.index();
168    self.check_repeated_ctr_fields(&fields, &name, ini_idx..end_idx)?;
169
170    let typ = make_ctr_type(type_name.clone(), &field_types, type_vars);
171    Ok(AdtCtr { name, typ, fields })
172  }
173
174  fn parse_variant_field(&mut self) -> ParseResult<CtrField> {
175    let rec = self.try_consume_exactly("~");
176    self.skip_trivia_inline()?;
177
178    let nam = self.parse_var_name()?;
179    self.skip_trivia_inline()?;
180
181    let typ = if self.try_consume_exactly(":") { self.parse_type_expr()? } else { Type::Any };
182
183    Ok(CtrField { nam, typ, rec })
184  }
185
186  fn parse_primary_expr(&mut self, inline: bool) -> ParseResult<Expr> {
187    if inline {
188      self.skip_trivia_inline()?;
189    } else {
190      self.skip_trivia();
191    }
192    if self.try_parse_keyword("lambda") | self.try_consume_exactly("λ") {
193      fn parse_lam_var(p: &mut ImpParser) -> ParseResult<(Name, bool)> {
194        if p.starts_with("$") {
195          p.advance_one();
196          Ok((p.parse_var_name()?, true))
197        } else {
198          Ok((p.parse_var_name()?, false))
199        }
200      }
201      let names = self.list_like(|p| parse_lam_var(p), "", ":", ",", false, 1)?;
202      let bod = self.parse_expr(inline, false)?;
203      Ok(Expr::Lam { names, bod: Box::new(bod) })
204    } else if self.starts_with("(") {
205      self.advance_one();
206      let expr = self.parse_expr(inline, true)?;
207      self.consume(")")?;
208      Ok(expr)
209    } else if self.starts_with("{") {
210      // Map or Sup
211      self.parse_map_or_sup()
212    } else if self.starts_with("[") {
213      // List or Comprehension
214      self.parse_list_or_comprehension()
215    } else if self.starts_with("![") {
216      // Tree Node
217      self.parse_tree_node()
218    } else if self.starts_with("!") {
219      // Tree Leaf
220      self.parse_tree_leaf(inline)
221    } else if self.starts_with("`") {
222      // Symbol
223      Ok(Expr::Num { val: Num::U24(self.parse_quoted_symbol()?) })
224    } else if self.starts_with("\"") {
225      // String
226      Ok(Expr::Str { val: STRINGS.get(self.parse_quoted_string()?) })
227    } else if self.starts_with("'") {
228      // Char
229      Ok(Expr::Num { val: Num::U24(self.parse_quoted_char()? as u32 & 0x00ff_ffff) })
230    } else if self.starts_with("$") {
231      // Unscoped var
232      self.advance_one();
233      Ok(Expr::Chn { nam: self.parse_var_name()? })
234    } else if self.starts_with("*") {
235      // Era
236      self.advance_one();
237      Ok(Expr::Era)
238    } else if let Some(c) = self.peek_one() {
239      if is_num_char(c) {
240        // Number
241        Ok(Expr::Num { val: self.parse_number()? })
242      } else {
243        // Var
244        let nam = self.labelled(|p| p.parse_var_name(), "expression")?;
245        Ok(Expr::Var { nam })
246      }
247    } else {
248      self.expected("expression")?
249    }
250  }
251
252  fn call_or_postfix(&mut self, inline: bool) -> ParseResult<Expr> {
253    let ini_idx = *self.index();
254    let base = self.parse_primary_expr(inline)?;
255    if inline {
256      self.skip_trivia_inline()?;
257    } else {
258      self.skip_trivia();
259    }
260
261    // call
262    if self.starts_with("(") {
263      self.advance_one();
264      let mut args = Vec::new();
265      let mut kwargs = Vec::new();
266      let mut must_be_named = false;
267      while !self.starts_with(")") {
268        let ini_idx = *self.index();
269        let (bnd, arg) = self.parse_named_arg()?;
270        let end_idx = *self.index();
271        if let Some(bnd) = bnd {
272          must_be_named = true;
273          kwargs.push((bnd, arg));
274        } else if must_be_named {
275          let msg = "Positional arguments are not allowed to go after named arguments.".to_string();
276          return self.with_ctx(Err(msg), ini_idx..end_idx);
277        } else {
278          args.push(arg);
279        }
280        if self.starts_with(",") {
281          self.consume(",")?;
282        } else {
283          break;
284        }
285      }
286      self.consume(")")?;
287      if args.is_empty() && kwargs.is_empty() {
288        return Ok(base);
289      } else {
290        return Ok(Expr::Call { fun: Box::new(base), args, kwargs });
291      }
292    }
293
294    // map get
295    if self.starts_with("[") {
296      if let Expr::Var { nam } = base {
297        self.advance_one();
298        let key = self.parse_expr(inline, false)?;
299        self.consume("]")?;
300        return Ok(Expr::MapGet { nam, key: Box::new(key) });
301      } else {
302        let end_idx = *self.index();
303        return self.expected_spanned("Map variable name", ini_idx..end_idx);
304      }
305    }
306
307    // ctr
308    if self.starts_with("{") {
309      if let Expr::Var { nam } = base {
310        let kwargs = self.list_like(|p| p.data_kwarg(), "{", "}", ",", true, 0)?;
311        return Ok(Expr::Ctr { name: nam, args: Vec::new(), kwargs });
312      } else {
313        let end_idx = *self.index();
314        return self.expected_spanned("Constructor name", ini_idx..end_idx);
315      }
316    }
317
318    // no postfix
319    Ok(base)
320  }
321
322  fn parse_map_or_sup(&mut self) -> ParseResult<Expr> {
323    self.advance_one();
324    // Empty map
325    if self.try_consume("}") {
326      return Ok(Expr::Map { entries: vec![] });
327    }
328    let head = self.parse_expr(false, false)?;
329    self.skip_trivia();
330    if self.try_consume(",") {
331      self.parse_sup(head)
332    } else if self.try_consume(":") {
333      self.parse_map_init(head)
334    } else {
335      self.expected("',' or ':'")
336    }
337  }
338
339  fn parse_map_init(&mut self, head: Expr) -> ParseResult<Expr> {
340    let mut entries = Vec::new();
341    let val = self.parse_expr(false, false)?;
342    entries.push((head, val));
343    self.skip_trivia();
344    if !self.starts_with("}") {
345      self.consume(",")?;
346    }
347    let tail = self.list_like(|p| p.parse_map_entry(), "", "}", ",", true, 0)?;
348    entries.extend(tail);
349    Ok(Expr::Map { entries })
350  }
351
352  fn parse_sup(&mut self, head: Expr) -> ParseResult<Expr> {
353    let mut els = vec![head];
354    let tail = self.list_like(|p| p.parse_expr(false, false), "", "}", ",", true, 1)?;
355    els.extend(tail);
356    Ok(Expr::Sup { els })
357  }
358
359  fn parse_tree_node(&mut self) -> ParseResult<Expr> {
360    self.advance_one();
361    self.advance_one();
362    let left = self.parse_expr(false, false)?;
363    self.consume(",")?;
364    let right = self.parse_expr(false, false)?;
365    self.consume("]")?;
366    Ok(Expr::TreeNode { left: Box::new(left), right: Box::new(right) })
367  }
368
369  fn parse_tree_leaf(&mut self, inline: bool) -> ParseResult<Expr> {
370    self.advance_one();
371    let val = self.parse_expr(inline, false)?;
372    Ok(Expr::TreeLeaf { val: Box::new(val) })
373  }
374
375  fn data_kwarg(&mut self) -> ParseResult<(Name, Expr)> {
376    self.skip_trivia();
377    let nam = self.parse_var_name()?;
378    self.consume(":")?;
379    let expr = self.parse_expr(false, false)?;
380    Ok((nam, expr))
381  }
382
383  fn parse_map_entry(&mut self) -> ParseResult<(Expr, Expr)> {
384    let key = self.parse_expr(false, false)?;
385    self.consume(":")?;
386    let val = self.parse_expr(false, false)?;
387    Ok((key, val))
388  }
389
390  fn parse_list_or_comprehension(&mut self) -> ParseResult<Expr> {
391    self.consume_exactly("[")?;
392
393    // Empty list
394    self.skip_trivia();
395    if self.try_consume_exactly("]") {
396      return Ok(Expr::Lst { els: vec![] });
397    }
398
399    let head = self.parse_expr(false, false)?;
400    self.skip_trivia();
401    if self.try_parse_keyword("for") {
402      // Comprehension
403      self.skip_trivia();
404      let bind = self.parse_var_name()?;
405      self.skip_trivia();
406      self.parse_keyword("in")?;
407      let iter = self.parse_expr(false, false)?;
408      let mut cond = None;
409      self.skip_trivia();
410      if self.try_parse_keyword("if") {
411        cond = Some(Box::new(self.parse_expr(false, false)?));
412      }
413      self.consume("]")?;
414      Ok(Expr::LstMap { term: Box::new(head), bind, iter: Box::new(iter), cond })
415    } else {
416      // List
417      let mut head = vec![head];
418      self.skip_trivia();
419      if !self.starts_with("]") {
420        self.consume(",")?;
421      }
422      let tail = self.list_like(|p| p.parse_expr(false, false), "", "]", ",", true, 0)?;
423      head.extend(tail);
424      Ok(Expr::Lst { els: head })
425    }
426  }
427
428  /// "λ" (<name> ","?)+ ":" <expr>
429  /// | "open" <type> ":" <var>
430  /// | <infix>
431  fn parse_expr(&mut self, inline: bool, tup: bool) -> ParseResult<Expr> {
432    if inline {
433      self.skip_trivia_inline()?;
434    } else {
435      self.skip_trivia();
436    }
437
438    let base = self.parse_infix_expr(0, inline)?;
439    if !tup {
440      return Ok(base);
441    }
442    if inline {
443      self.skip_trivia_inline()?;
444    } else {
445      self.skip_trivia();
446    }
447    if self.starts_with(",") {
448      let mut els = vec![base];
449      loop {
450        if self.starts_with(",") {
451          self.advance_one();
452          els.push(self.parse_expr(inline, false)?);
453          if self.starts_with("\n") {
454            break;
455          }
456          if inline {
457            self.skip_trivia_inline()?;
458          } else {
459            self.skip_trivia();
460          }
461        } else {
462          break;
463        }
464      }
465      Ok(Expr::Tup { els })
466    } else {
467      Ok(base)
468    }
469  }
470
471  /// Named argument of a function call.
472  fn parse_named_arg(&mut self) -> ParseResult<(Option<Name>, Expr)> {
473    let arg = self.parse_expr(false, false)?;
474    if self.try_consume("=") {
475      if let Expr::Var { nam } = arg {
476        let bind = Some(nam);
477        let arg = self.parse_expr(false, false)?;
478        Ok((bind, arg))
479      } else {
480        let msg = "Unexpected '=' in unnamed argument.".to_string();
481        let idx = *self.index();
482        self.with_ctx(Err(msg), idx..idx + 1)
483      }
484    } else {
485      Ok((None, arg))
486    }
487  }
488
489  /// Infix expression.
490  /// <simple> (<infix_op> <infix>)?
491  fn parse_infix_expr(&mut self, prec: usize, inline: bool) -> ParseResult<Expr> {
492    maybe_grow(|| {
493      if inline {
494        self.skip_trivia_inline()?;
495      } else {
496        self.skip_trivia();
497      }
498      if prec > Op::max_precedence() {
499        return self.call_or_postfix(inline);
500      }
501      let mut lhs = self.parse_infix_expr(prec + 1, inline)?;
502      if inline {
503        self.skip_trivia_inline()?;
504      } else {
505        self.skip_trivia();
506      }
507      while let Some(op) = self.peek_oper() {
508        if op.precedence() == prec {
509          self.try_parse_oper().unwrap();
510          let rhs = self.parse_infix_expr(prec + 1, inline)?;
511          lhs = Expr::Opr { op, lhs: Box::new(lhs), rhs: Box::new(rhs) };
512          self.skip_trivia_inline()?;
513        } else {
514          break;
515        }
516      }
517      Ok(lhs)
518    })
519  }
520
521  fn consume_indent_at_most(&mut self, expected: Indent) -> ParseResult<Indent> {
522    let got = self.advance_newlines()?;
523    match (expected, got) {
524      (_, Indent::Eof) => Ok(Indent::Eof),
525      (Indent::Val(expected), Indent::Val(got)) if got <= expected => Ok(Indent::Val(got)),
526      (expected, got) => self.expected_indent(expected, got),
527    }
528  }
529
530  fn consume_indent_exactly(&mut self, expected: Indent) -> ParseResult<()> {
531    let got = self.advance_newlines()?;
532    match (expected, got) {
533      (Indent::Eof, Indent::Eof) => Ok(()),
534      (Indent::Val(expected), Indent::Val(got)) if got == expected => Ok(()),
535      (expected, got) => self.expected_indent(expected, got),
536    }
537  }
538
539  /// Parses a statement and returns the indentation of the next statement.
540  fn parse_statement(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
541    maybe_grow(|| {
542      if self.starts_with_keyword("return") {
543        self.parse_return()
544      } else if self.starts_with_keyword("def") {
545        self.parse_local_def(indent)
546      } else if self.starts_with_keyword("if") {
547        self.parse_if(indent)
548      } else if self.starts_with_keyword("match") {
549        self.parse_match(indent)
550      } else if self.starts_with_keyword("switch") {
551        self.parse_switch(indent)
552      } else if self.starts_with_keyword("fold") {
553        self.parse_fold(indent)
554      } else if self.starts_with_keyword("bend") {
555        self.parse_bend(indent)
556      } else if self.starts_with_keyword("with") {
557        self.parse_with(indent)
558      } else if self.starts_with_keyword("open") {
559        self.parse_open(indent)
560      } else if self.starts_with_keyword("use") {
561        self.parse_use(indent)
562      } else {
563        self.parse_assign(indent)
564      }
565    })
566  }
567
568  /// Assignments, monadic bind operations and in-place operations.
569  /// <assign_pattern> "=" <expr> ";"?
570  /// | <assign_pattern> "<-" <expr> ";"?
571  ///
572  fn parse_assign(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
573    let ini_idx = *self.index();
574    let pat = self.parse_assign_pattern()?;
575    let end_idx = *self.index();
576    self.skip_trivia_inline()?;
577
578    // Assignment
579    if self.starts_with("=") {
580      self.advance_one();
581      let val = self.parse_expr(true, true)?;
582      self.skip_trivia_inline()?;
583      self.try_consume_exactly(";");
584      if !self.is_eof() {
585        self.consume_new_line()?;
586      }
587      let nxt_indent = self.advance_newlines()?;
588      if nxt_indent == *indent {
589        let (nxt, nxt_indent) = self.parse_statement(indent)?;
590        let stmt = Stmt::Assign { pat, val: Box::new(val), nxt: Some(Box::new(nxt)) };
591        return Ok((stmt, nxt_indent));
592      } else {
593        let stmt = Stmt::Assign { pat, val: Box::new(val), nxt: None };
594        return Ok((stmt, nxt_indent));
595      }
596    }
597    // Ask
598    if self.starts_with("<-") {
599      self.consume("<-")?;
600      let val = self.parse_expr(true, true)?;
601      self.skip_trivia_inline()?;
602      self.try_consume_exactly(";");
603      let nxt_indent = self.advance_newlines()?;
604      if nxt_indent == *indent {
605        let (nxt, nxt_indent) = self.parse_statement(indent)?;
606        let stmt = Stmt::Ask { pat, val: Box::new(val), nxt: Some(Box::new(nxt)) };
607        return Ok((stmt, nxt_indent));
608      } else {
609        let stmt = Stmt::Ask { pat, val: Box::new(val), nxt: None };
610        return Ok((stmt, nxt_indent));
611      }
612    }
613    // In-place
614
615    match &pat {
616      AssignPattern::Var(..) => {}
617      AssignPattern::MapSet(..) => {}
618      _ => self.expected_spanned("Var or Map accessor", ini_idx..end_idx)?,
619    }
620    if let Some(op) = self.parse_in_place_op()? {
621      let val = self.parse_expr(true, false)?;
622      self.skip_trivia_inline()?;
623      self.try_consume_exactly(";");
624      self.consume_indent_exactly(*indent)?;
625      let (nxt, nxt_indent) = self.parse_statement(indent)?;
626      let stmt = Stmt::InPlace { op, pat: Box::new(pat), val: Box::new(val), nxt: Box::new(nxt) };
627      return Ok((stmt, nxt_indent));
628    }
629
630    self.expected_spanned("statement", ini_idx..end_idx)
631  }
632
633  fn parse_in_place_op(&mut self) -> ParseResult<Option<InPlaceOp>> {
634    self.skip_trivia_inline()?;
635    let op = if self.starts_with("+=") {
636      self.consume("+=")?;
637      Some(InPlaceOp::Add)
638    } else if self.starts_with("-=") {
639      self.consume("-=")?;
640      Some(InPlaceOp::Sub)
641    } else if self.starts_with("*=") {
642      self.consume("*=")?;
643      Some(InPlaceOp::Mul)
644    } else if self.starts_with("/=") {
645      self.consume("/=")?;
646      Some(InPlaceOp::Div)
647    } else if self.starts_with("&=") {
648      self.consume("&=")?;
649      Some(InPlaceOp::And)
650    } else if self.starts_with("|=") {
651      self.consume("|=")?;
652      Some(InPlaceOp::Or)
653    } else if self.starts_with("^=") {
654      self.consume("^=")?;
655      Some(InPlaceOp::Xor)
656    } else if self.starts_with("@=") {
657      self.consume("@=")?;
658      Some(InPlaceOp::Map)
659    } else {
660      None
661    };
662    Ok(op)
663  }
664
665  fn parse_return(&mut self) -> ParseResult<(Stmt, Indent)> {
666    self.parse_keyword("return")?;
667
668    let term = self.parse_expr(true, true)?;
669    self.skip_trivia_inline()?;
670
671    self.try_consume_exactly(";");
672    if !self.is_eof() {
673      self.consume_new_line()?;
674    }
675    let indent = self.advance_newlines()?;
676
677    Ok((Stmt::Return { term: Box::new(term) }, indent))
678  }
679
680  fn parse_if(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
681    self.parse_keyword("if")?;
682    self.skip_trivia_inline()?;
683
684    let cond = self.parse_expr(true, true)?;
685    self.skip_trivia_inline()?;
686    self.consume_exactly(":")?;
687    indent.enter_level();
688
689    self.consume_indent_exactly(*indent)?;
690    let (then, nxt_indent) = self.parse_statement(indent)?;
691    indent.exit_level();
692
693    if nxt_indent != *indent {
694      return self
695        .expected_indent(*indent, nxt_indent)
696        .or(self.expected_spanned("'else' or 'elif'", self.index..self.index + 1));
697    }
698    let mut elifs = Vec::new();
699    while self.try_parse_keyword("elif") {
700      let cond = self.parse_expr(true, false)?;
701      self.skip_trivia_inline()?;
702      self.consume_exactly(":")?;
703      indent.enter_level();
704      self.consume_indent_exactly(*indent)?;
705      let (then, nxt_indent) = self.parse_statement(indent)?;
706      indent.exit_level();
707
708      if nxt_indent != *indent {
709        return self
710          .expected_indent(*indent, nxt_indent)
711          .or(self.expected_spanned("'else' or 'elif'", self.index..self.index + 1));
712      }
713      elifs.push((cond, then));
714    }
715    self.parse_keyword("else")?;
716    self.skip_trivia_inline()?;
717    self.consume_exactly(":")?;
718    indent.enter_level();
719
720    self.consume_indent_exactly(*indent)?;
721    let (otherwise, nxt_indent) = self.parse_statement(indent)?;
722    let otherwise = elifs.into_iter().rfold(otherwise, |acc, (cond, then)| Stmt::If {
723      cond: Box::new(cond),
724      then: Box::new(then),
725      otherwise: Box::new(acc),
726      nxt: None,
727    });
728
729    indent.exit_level();
730    if nxt_indent == *indent {
731      let (nxt, nxt_indent) = self.parse_statement(indent)?;
732      let stmt = Stmt::If {
733        cond: Box::new(cond),
734        then: Box::new(then),
735        otherwise: Box::new(otherwise),
736        nxt: Some(Box::new(nxt)),
737      };
738      Ok((stmt, nxt_indent))
739    } else {
740      let stmt =
741        Stmt::If { cond: Box::new(cond), then: Box::new(then), otherwise: Box::new(otherwise), nxt: None };
742      Ok((stmt, nxt_indent))
743    }
744  }
745
746  fn parse_match(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
747    self.parse_keyword("match")?;
748    self.skip_trivia_inline()?;
749
750    let (bnd, arg) = self.parse_match_arg()?;
751    self.skip_trivia_inline()?;
752
753    let (with_bnd, with_arg) = self.parse_with_clause()?;
754    self.consume_new_line()?;
755    indent.enter_level();
756
757    self.consume_indent_exactly(*indent).or(self.expected_spanned("'case'", self.index..self.index + 1))?;
758    let (case, mut nxt_indent) = self.parse_match_case(indent)?;
759    let mut arms = vec![case];
760    while nxt_indent == *indent {
761      let (case, nxt_indent_) = self.parse_match_case(indent)?;
762      nxt_indent = nxt_indent_;
763      arms.push(case);
764    }
765    indent.exit_level();
766    if nxt_indent == *indent {
767      let (nxt, nxt_indent) = self.parse_statement(indent)?;
768      let stmt = Stmt::Match { arg: Box::new(arg), bnd, with_bnd, with_arg, arms, nxt: Some(Box::new(nxt)) };
769      Ok((stmt, nxt_indent))
770    } else {
771      let stmt = Stmt::Match { arg: Box::new(arg), bnd, with_bnd, with_arg, arms, nxt: None };
772      Ok((stmt, nxt_indent))
773    }
774  }
775
776  fn parse_match_arg(&mut self) -> ParseResult<(Option<Name>, Expr)> {
777    let ini_idx = *self.index();
778    let arg = self.parse_expr(true, false)?;
779    let end_idx = *self.index();
780
781    self.skip_trivia_inline()?;
782    match (arg, self.starts_with("=")) {
783      (Expr::Var { nam }, true) => {
784        self.advance_one();
785        Ok((Some(nam), self.parse_expr(true, false)?))
786      }
787      (_, true) => self.expected_spanned("argument name", ini_idx..end_idx),
788      (Expr::Var { nam }, false) => Ok((Some(nam.clone()), Expr::Var { nam })),
789      (arg, false) => Ok((Some(Name::new("%arg")), arg)),
790    }
791  }
792
793  fn parse_with_clause(&mut self) -> ParseResult<(Vec<Option<Name>>, Vec<Expr>)> {
794    self.skip_trivia_inline()?;
795    let res = if self.try_parse_keyword("with") {
796      self.list_like(|p| p.parse_with_arg(), "", ":", ",", true, 1)?.into_iter().unzip()
797    } else {
798      self.consume_exactly(":")?;
799      (vec![], vec![])
800    };
801    Ok(res)
802  }
803
804  fn parse_with_arg(&mut self) -> ParseResult<(Option<Name>, Expr)> {
805    let bind = self.parse_var_name()?;
806    self.skip_trivia_inline()?;
807    if self.try_consume("=") {
808      let arg = self.parse_expr(false, false)?;
809      Ok((Some(bind), arg))
810    } else {
811      Ok((Some(bind.clone()), Expr::Var { nam: bind }))
812    }
813  }
814
815  fn parse_match_case(&mut self, indent: &mut Indent) -> ParseResult<(MatchArm, Indent)> {
816    self.parse_keyword("case")?;
817    self.skip_trivia_inline()?;
818    let pat = if self.try_consume_exactly("_") {
819      None
820    } else {
821      let nam = self.labelled(|p| p.parse_var_name(), "name or '_'")?;
822      Some(nam)
823    };
824    self.skip_trivia_inline()?;
825    self.consume_exactly(":")?;
826    self.consume_new_line()?;
827    indent.enter_level();
828
829    self.consume_indent_exactly(*indent)?;
830    let (body, nxt_indent) = self.parse_statement(indent)?;
831    indent.exit_level();
832
833    let stmt = MatchArm { lft: pat, rgt: body };
834    Ok((stmt, nxt_indent))
835  }
836
837  fn parse_switch(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
838    self.parse_keyword("switch")?;
839    self.skip_trivia_inline()?;
840
841    let (bnd, arg) = self.parse_match_arg()?;
842    self.skip_trivia_inline()?;
843
844    let (with_bnd, with_arg) = self.parse_with_clause()?;
845    indent.enter_level();
846
847    self.consume_indent_exactly(*indent)?;
848    let ini_idx = *self.index();
849    let (fst_case, fst_stmt, mut nxt_indent) = self.parse_switch_case(indent)?;
850    let end_idx = *self.index();
851    if fst_case != Some(0) {
852      return self.expected_spanned("case 0", ini_idx..end_idx);
853    }
854    let mut arms = vec![fst_stmt];
855    let mut should_continue = fst_case == Some(0);
856    let mut expected_num = 1;
857    while should_continue {
858      if nxt_indent != *indent {
859        return self
860          .expected_indent(*indent, nxt_indent)
861          .or(self.expected_spanned("'case'", self.index..self.index + 1));
862      }
863      let (case, stmt, nxt_indent_) = self.parse_switch_case(indent)?;
864      nxt_indent = nxt_indent_;
865      if let Some(case) = case {
866        if case != expected_num {
867          return self.expected(&format!("case {}", expected_num));
868        }
869        should_continue = true;
870        arms.push(stmt);
871        expected_num += 1;
872      } else {
873        should_continue = false;
874        arms.push(stmt);
875      }
876    }
877    indent.exit_level();
878    if nxt_indent == *indent {
879      let (nxt, nxt_indent) = self.parse_statement(indent)?;
880      let stmt = Stmt::Switch { arg: Box::new(arg), bnd, with_bnd, with_arg, arms, nxt: Some(Box::new(nxt)) };
881      Ok((stmt, nxt_indent))
882    } else {
883      let stmt = Stmt::Switch { arg: Box::new(arg), bnd, with_bnd, with_arg, arms, nxt: None };
884      Ok((stmt, nxt_indent))
885    }
886  }
887
888  fn parse_switch_case(&mut self, indent: &mut Indent) -> ParseResult<(Option<u32>, Stmt, Indent)> {
889    self.parse_keyword("case")?;
890    self.skip_trivia_inline()?;
891    let case = if let Some(c) = self.peek_one() {
892      match c {
893        '_' => {
894          self.advance_one();
895          None
896        }
897        c if c.is_ascii_digit() => Some(self.parse_u32()?),
898        _ => return self.expected("number or '_'"),
899      }
900    } else {
901      return self.expected("number or '_'")?;
902    };
903
904    self.skip_trivia_inline()?;
905    self.consume_exactly(":")?;
906    self.consume_new_line()?;
907    indent.enter_level();
908    self.consume_indent_exactly(*indent)?;
909    let (stmt, nxt_indent) = self.parse_statement(indent)?;
910    indent.exit_level();
911    Ok((case, stmt, nxt_indent))
912  }
913
914  /// "fold" <bind> ("=" <arg>)? ":"
915  ///   "case" <ctr> ":"
916  ///     <case>
917  ///   ...
918  fn parse_fold(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
919    self.parse_keyword("fold")?;
920    self.skip_trivia_inline()?;
921
922    // Actually identical to match, except the return
923    let (bind, arg) = self.parse_match_arg()?;
924    self.skip_trivia_inline()?;
925
926    let (with_bnd, with_arg) = self.parse_with_clause()?;
927    self.consume_new_line()?;
928    indent.enter_level();
929
930    self.consume_indent_exactly(*indent).or(self.expected_spanned("'case'", self.index..self.index + 1))?;
931    let (case, mut nxt_indent) = self.parse_match_case(indent)?;
932    let mut arms = vec![case];
933    while nxt_indent == *indent {
934      let (case, nxt_indent_) = self.parse_match_case(indent)?;
935      nxt_indent = nxt_indent_;
936      arms.push(case);
937    }
938    indent.exit_level();
939    if nxt_indent == *indent {
940      let (nxt, nxt_indent) = self.parse_statement(indent)?;
941      let stmt =
942        Stmt::Fold { arg: Box::new(arg), bnd: bind, arms, with_bnd, with_arg, nxt: Some(Box::new(nxt)) };
943      Ok((stmt, nxt_indent))
944    } else {
945      let stmt = Stmt::Fold { arg: Box::new(arg), bnd: bind, arms, with_bnd, with_arg, nxt: None };
946      Ok((stmt, nxt_indent))
947    }
948  }
949
950  /// "bend" (<bind> "=" <init> ","?)* ":"
951  ///   "when" <cond> ":"
952  ///     <step>
953  ///   "else" ":"
954  ///     <base>
955  fn parse_bend(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
956    self.parse_keyword("bend")?;
957    self.skip_trivia_inline()?;
958
959    let args = self.list_like(|p| p.parse_match_arg(), "", ":", ",", true, 1)?;
960    let (bind, init) = args.into_iter().unzip();
961    self.consume_new_line()?;
962    indent.enter_level();
963
964    self.consume_indent_exactly(*indent).or(self.expected_spanned("'when'", self.index..self.index + 1))?;
965    self.parse_keyword("when")?;
966    self.skip_trivia_inline()?;
967
968    let cond = self.parse_expr(true, true)?;
969    self.skip_trivia_inline()?;
970
971    self.consume_exactly(":")?;
972    self.consume_new_line()?;
973    indent.enter_level();
974
975    self.consume_indent_exactly(*indent)?;
976    let (step, nxt_indent) = self.parse_statement(indent)?;
977    indent.exit_level();
978
979    if nxt_indent != *indent {
980      return self
981        .expected_indent(*indent, nxt_indent)
982        .or(self.expected_spanned("'else'", self.index..self.index + 1));
983    }
984    self.parse_keyword("else")?;
985    self.skip_trivia_inline()?;
986    self.consume_exactly(":")?;
987    self.consume_new_line()?;
988    indent.enter_level();
989
990    self.consume_indent_exactly(*indent)?;
991    let (base, nxt_indent) = self.parse_statement(indent)?;
992    indent.exit_level();
993
994    indent.exit_level();
995    if nxt_indent == *indent {
996      let (nxt, nxt_indent) = self.parse_statement(indent)?;
997      let stmt = Stmt::Bend {
998        bnd: bind,
999        arg: init,
1000        cond: Box::new(cond),
1001        step: Box::new(step),
1002        base: Box::new(base),
1003        nxt: Some(Box::new(nxt)),
1004      };
1005      Ok((stmt, nxt_indent))
1006    } else {
1007      let stmt = Stmt::Bend {
1008        bnd: bind,
1009        arg: init,
1010        cond: Box::new(cond),
1011        step: Box::new(step),
1012        base: Box::new(base),
1013        nxt: None,
1014      };
1015      Ok((stmt, nxt_indent))
1016    }
1017  }
1018
1019  /// "with" <typ> ":"
1020  ///   <bod>
1021  /// <nxt>?
1022  fn parse_with(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
1023    self.parse_keyword("with")?;
1024    self.skip_trivia_inline()?;
1025
1026    let typ = self.parse_var_name()?;
1027    self.skip_trivia_inline()?;
1028
1029    self.consume_exactly(":")?;
1030    self.consume_new_line()?;
1031    indent.enter_level();
1032
1033    self.consume_indent_exactly(*indent)?;
1034    let (bod, nxt_indent) = self.parse_statement(indent)?;
1035    indent.exit_level();
1036
1037    if nxt_indent == *indent {
1038      let (nxt, nxt_indent) = self.parse_statement(indent)?;
1039      let stmt = Stmt::With { typ, bod: Box::new(bod), nxt: Some(Box::new(nxt)) };
1040      Ok((stmt, nxt_indent))
1041    } else {
1042      let stmt = Stmt::With { typ, bod: Box::new(bod), nxt: None };
1043      Ok((stmt, nxt_indent))
1044    }
1045  }
1046
1047  /// <pat1>
1048  /// | <nam> "[" <expr> "]"
1049  /// | <pat1> ("," <pat1>)*
1050  fn parse_assign_pattern(&mut self) -> ParseResult<AssignPattern> {
1051    let head_ini = *self.index();
1052    let head = self.parse_primary_assign_pattern()?;
1053    let head_end = *self.index();
1054    self.skip_trivia_inline()?;
1055    if self.starts_with("[") {
1056      // TODO: allow patterns like `x[a][b]`
1057      self.advance_one();
1058      let key = self.parse_expr(false, false)?;
1059      self.consume("]")?;
1060      if let AssignPattern::Var(var) = head {
1061        Ok(AssignPattern::MapSet(var, key))
1062      } else {
1063        self.with_ctx(Err("Expected a variable pattern"), head_ini..head_end)
1064      }
1065    } else if self.starts_with(",") {
1066      let mut els = vec![head];
1067      while self.try_consume(",") {
1068        self.skip_trivia_inline()?;
1069        els.push(self.parse_primary_assign_pattern()?);
1070      }
1071      Ok(AssignPattern::Tup(els))
1072    } else {
1073      Ok(head)
1074    }
1075  }
1076
1077  /// "*"
1078  /// | "{"<pat1> ("," <pat1>)+ "}"
1079  /// | "$" <nam>
1080  /// | "(" <pat0> ")"
1081  /// | <nam>
1082  fn parse_primary_assign_pattern(&mut self) -> ParseResult<AssignPattern> {
1083    if self.starts_with("*") {
1084      self.advance_one();
1085      Ok(AssignPattern::Eraser)
1086    } else if self.starts_with("{") {
1087      let binds = self.list_like(|p| p.parse_primary_assign_pattern(), "{", "}", ",", true, 2)?;
1088      Ok(AssignPattern::Sup(binds))
1089    } else if self.starts_with("$") {
1090      self.advance_one();
1091      self.skip_trivia_inline()?;
1092      let nam = self.parse_var_name()?;
1093      Ok(AssignPattern::Chn(nam))
1094    } else if self.starts_with("(") {
1095      self.advance_one();
1096      let assign = self.parse_assign_pattern()?;
1097      self.consume(")")?;
1098      Ok(assign)
1099    } else {
1100      Ok(AssignPattern::Var(self.parse_var_name()?))
1101    }
1102  }
1103
1104  /// "open" {typ} ":" {var} ";"? {nxt}
1105  fn parse_open(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
1106    self.parse_keyword("open")?;
1107    self.skip_trivia_inline()?;
1108
1109    let typ = self.labelled(|p| p.parse_var_name(), "type name")?;
1110    self.skip_trivia_inline()?;
1111
1112    self.consume_exactly(":")?;
1113    self.skip_trivia_inline()?;
1114
1115    let var = self.labelled(|p| p.parse_var_name(), "variable name")?;
1116    self.skip_trivia_inline()?;
1117
1118    self.try_consume_exactly(";");
1119    self.consume_new_line()?;
1120    self.consume_indent_exactly(*indent)?;
1121
1122    let (nxt, nxt_indent) = self.parse_statement(indent)?;
1123
1124    let stmt = Stmt::Open { typ, var, nxt: Box::new(nxt) };
1125    Ok((stmt, nxt_indent))
1126  }
1127
1128  fn parse_use(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
1129    self.parse_keyword("use")?;
1130    self.skip_trivia_inline()?;
1131
1132    let nam = self.parse_var_name()?;
1133    self.skip_trivia_inline()?;
1134
1135    self.consume_exactly("=")?;
1136    self.skip_trivia_inline()?;
1137
1138    let bod = self.parse_expr(true, true)?;
1139    self.skip_trivia_inline()?;
1140
1141    self.try_consume_exactly(";");
1142    self.consume_new_line()?;
1143    self.consume_indent_exactly(*indent)?;
1144
1145    let (nxt, nxt_indent) = self.parse_statement(indent)?;
1146
1147    let stmt = Stmt::Use { nam, val: Box::new(bod), nxt: Box::new(nxt) };
1148    Ok((stmt, nxt_indent))
1149  }
1150
1151  fn parse_local_def(&mut self, indent: &mut Indent) -> ParseResult<(Stmt, Indent)> {
1152    // TODO: checked vs unchecked functions
1153    let (mut def, mut nxt_indent) = self.parse_def_aux(*indent)?;
1154    def.source.kind = if self.builtin { SourceKind::Builtin } else { SourceKind::Generated };
1155    let (nxt, nxt_indent) = self.parse_statement(&mut nxt_indent)?;
1156    let stmt = Stmt::LocalDef { def: Box::new(def), nxt: Box::new(nxt) };
1157    Ok((stmt, nxt_indent))
1158  }
1159
1160  /// Parses a type expression, returning the type and the type variables.
1161  fn parse_type_expr(&mut self) -> ParseResult<Type> {
1162    // TODO: We should probably not have it all be inline or not inline.
1163    // For example, in tuple types or constructors, we could have line breaks.
1164    maybe_grow(|| {
1165      self.skip_trivia_inline()?;
1166      let ini_idx = *self.index();
1167      let lft = if self.try_parse_keyword("Any") {
1168        Type::Any
1169      } else if self.try_parse_keyword("None") {
1170        Type::None
1171      } else if self.try_parse_keyword("_") {
1172        Type::Hole
1173      } else if self.try_parse_keyword("u24") {
1174        Type::U24
1175      } else if self.try_parse_keyword("i24") {
1176        Type::I24
1177      } else if self.try_parse_keyword("f24") {
1178        Type::F24
1179      } else if self.try_consume_exactly("(") {
1180        // Tuple or parenthesized expression
1181        self.skip_trivia();
1182        let head = self.parse_type_expr()?;
1183        self.skip_trivia();
1184        if self.try_consume_exactly(")") {
1185          // Parens
1186          head
1187        } else if self.starts_with(",") {
1188          // Tuple
1189          let mut types = vec![head];
1190          loop {
1191            self.consume_exactly(",")?;
1192            types.push(self.parse_type_expr()?);
1193            if self.try_consume_exactly(")") {
1194              break;
1195            }
1196            if !self.starts_with(",") {
1197              return self.expected("',' or ')'");
1198            }
1199          }
1200          Type::Tup(types)
1201        } else {
1202          let end_idx = *self.index();
1203          return self.expected_spanned("tuple type or parenthesized type", ini_idx..end_idx);
1204        }
1205      } else {
1206        // Variable or Constructor
1207        // TODO: This will show "expected Name" instead of "expected type"
1208        let name = self.parse_var_name()?;
1209        self.skip_trivia_inline()?;
1210        if self.try_consume_exactly("(") {
1211          // Constructor with arguments
1212          // name "(" (type ("," type)* ","?)? ")"
1213
1214          let args = self.list_like(|p| p.parse_type_expr(), "", ")", ",", true, 0)?;
1215          Type::Ctr(name, args)
1216        } else {
1217          // Variable
1218          Type::Var(name)
1219        }
1220      };
1221
1222      // Handle arrow types
1223      self.skip_trivia_inline()?;
1224      if self.try_consume_exactly("->") {
1225        let rgt = self.parse_type_expr()?;
1226        Ok(Type::Arr(Box::new(lft), Box::new(rgt)))
1227      } else {
1228        Ok(lft)
1229      }
1230    })
1231  }
1232
1233  fn parse_def_aux(&mut self, mut indent: Indent) -> ParseResult<(Definition, Indent)> {
1234    let ini_idx = *self.index();
1235    self.parse_keyword("def")?;
1236    self.skip_trivia_inline()?;
1237
1238    let check = if self.try_parse_keyword("unchecked") {
1239      (false, true)
1240    } else if self.try_parse_keyword("checked") {
1241      (true, false)
1242    } else {
1243      (false, false)
1244    };
1245    self.skip_trivia_inline()?;
1246
1247    let name = self.parse_top_level_name()?;
1248    self.skip_trivia_inline()?;
1249
1250    let args = if self.try_consume_exactly("(") {
1251      self.list_like(|p| p.parse_def_arg(), "", ")", ",", true, 0)?
1252    } else {
1253      vec![]
1254    };
1255    self.skip_trivia_inline()?;
1256    let (args, arg_types): (Vec<_>, Vec<_>) = args.into_iter().unzip();
1257
1258    let ret_type = self.parse_return_type()?;
1259    self.skip_trivia_inline()?;
1260
1261    self.consume_exactly(":")?;
1262    self.consume_new_line()?;
1263    indent.enter_level();
1264    self.consume_indent_exactly(indent)?;
1265
1266    let (body, nxt_indent) = self.parse_statement(&mut indent)?;
1267    indent.exit_level();
1268
1269    // If any annotation, check by default, otherwise unchecked by default
1270    let check = if check.0 {
1271      true
1272    } else if check.1 {
1273      false
1274    } else {
1275      ret_type.is_some() || arg_types.iter().any(|t| t.is_some())
1276    };
1277    let arg_types = arg_types.into_iter().map(|t| t.unwrap_or(Type::Any)).collect::<Vec<_>>();
1278    let typ = make_fn_type(arg_types, ret_type.unwrap_or(Type::Any));
1279
1280    // Note: The source kind gets replaced later (generated if a local def, user otherwise)
1281    let source = Source::from_file_span(&self.file, self.input, ini_idx..self.index, self.builtin);
1282    let def = Definition { name, args, typ, check, body, source };
1283    Ok((def, nxt_indent))
1284  }
1285
1286  fn parse_def_arg(&mut self) -> ParseResult<(Name, Option<Type>)> {
1287    let name = self.parse_var_name()?;
1288    self.skip_trivia_inline()?;
1289    if self.try_consume_exactly(":") {
1290      let typ = self.parse_type_expr()?;
1291      Ok((name, Some(typ)))
1292    } else {
1293      Ok((name, None))
1294    }
1295  }
1296
1297  fn parse_return_type(&mut self) -> ParseResult<Option<Type>> {
1298    if self.try_consume_exactly("->") {
1299      Ok(Some(self.parse_type_expr()?))
1300    } else {
1301      Ok(None)
1302    }
1303  }
1304
1305  fn expected_indent<T>(&mut self, expected: Indent, got: Indent) -> ParseResult<T> {
1306    match (expected, got) {
1307      (Indent::Eof, Indent::Eof) => unreachable!(),
1308      (Indent::Eof, Indent::Val(got)) => {
1309        let msg = format!("Indentation error. Expected end-of-input, got {} spaces.", got);
1310        let idx = *self.index();
1311        self.with_ctx(Err(msg), idx..idx + 1)
1312      }
1313      (Indent::Val(expected), Indent::Eof) => {
1314        let msg = format!("Indentation error. Expected {} spaces, got end-of-input.", expected);
1315        let idx = *self.index();
1316        self.with_ctx(Err(msg), idx..idx + 1)
1317      }
1318      (Indent::Val(expected), Indent::Val(got)) => {
1319        if got != expected {
1320          let msg = format!("Indentation error. Expected {} spaces, got {}.", expected, got);
1321          let idx = *self.index();
1322          self.with_ctx(Err(msg), idx..idx + 1)
1323        } else {
1324          unreachable!()
1325        }
1326      }
1327    }
1328  }
1329}
1330
1331impl<'a> ParserCommons<'a> for ImpParser<'a> {}
1332
1333impl<'a> Parser<'a> for ImpParser<'a> {
1334  fn input(&mut self) -> &'a str {
1335    self.input
1336  }
1337
1338  fn index(&mut self) -> &mut usize {
1339    &mut self.index
1340  }
1341
1342  /// Generates an error message for parsing failures, including the highlighted context.
1343  ///
1344  /// Override to have our own error message.
1345  fn expected<T>(&mut self, exp: &str) -> ParseResult<T> {
1346    let ini_idx = *self.index();
1347    let end_idx = *self.index() + 1;
1348    self.expected_spanned(exp, ini_idx..end_idx)
1349  }
1350
1351  /// Consumes an instance of the given string, erroring if it is not found.
1352  ///
1353  /// Override to have our own error message.
1354  fn consume(&mut self, text: &str) -> ParseResult<()> {
1355    self.skip_trivia();
1356    if self.input().get(*self.index()..).unwrap_or_default().starts_with(text) {
1357      *self.index() += text.len();
1358      Ok(())
1359    } else {
1360      self.expected(format!("'{text}'").as_str())
1361    }
1362  }
1363
1364  fn skip_trivia(&mut self) {
1365    while let Some(c) = self.peek_one() {
1366      if c.is_ascii_whitespace() {
1367        self.advance_one();
1368        continue;
1369      }
1370      if c == '#' {
1371        while let Some(c) = self.peek_one() {
1372          if c != '\n' {
1373            self.advance_one();
1374          } else {
1375            break;
1376          }
1377        }
1378        self.advance_one(); // Skip the newline character as well
1379        continue;
1380      }
1381      break;
1382    }
1383  }
1384}
1385
1386impl Op {
1387  fn precedence(&self) -> usize {
1388    match self {
1389      Op::OR => 0,
1390      Op::XOR => 1,
1391      Op::AND => 2,
1392      Op::EQ => 3,
1393      Op::NEQ => 3,
1394      Op::LT => 4,
1395      Op::GT => 4,
1396      Op::LE => 4,
1397      Op::GE => 4,
1398      Op::SHL => 5,
1399      Op::SHR => 5,
1400      Op::ADD => 6,
1401      Op::SUB => 6,
1402      Op::MUL => 7,
1403      Op::DIV => 7,
1404      Op::REM => 7,
1405      Op::POW => 8,
1406    }
1407  }
1408
1409  fn max_precedence() -> usize {
1410    8
1411  }
1412}