bend/fun/
parser.rs

1use crate::{
2  fun::{
3    display::DisplayFn, Adt, AdtCtr, Adts, Constructors, CtrField, FanKind, HvmDefinition, HvmDefinitions,
4    MatchRule, Name, Num, Op, Pattern, Rule, Source, SourceKind, Tag, Term, Type, STRINGS,
5  },
6  imp::parser::ImpParser,
7  imports::{Import, ImportCtx, ImportType},
8  maybe_grow,
9};
10use highlight_error::highlight_error;
11use indexmap::IndexMap;
12use itertools::Itertools;
13use std::ops::Range;
14use TSPL::{ParseError, Parser};
15
16type FunDefinition = super::Definition;
17type ImpDefinition = crate::imp::Definition;
18
19/// Intermediate representation of a program.
20#[derive(Debug, Clone, Default)]
21pub struct ParseBook {
22  /// The `functional` function definitions.
23  pub fun_defs: IndexMap<Name, FunDefinition>,
24
25  /// The `imperative` function definitions.
26  pub imp_defs: IndexMap<Name, ImpDefinition>,
27
28  /// HVM native function definitions.
29  pub hvm_defs: HvmDefinitions,
30
31  /// The algebraic datatypes defined by the program
32  pub adts: Adts,
33
34  /// To which type does each constructor belong to.
35  pub ctrs: Constructors,
36
37  /// Imported packages to be loaded in the program
38  pub import_ctx: ImportCtx,
39
40  /// File path that the book was loaded from.
41  pub source: Name,
42}
43
44impl ParseBook {
45  pub fn contains_def(&self, name: &Name) -> bool {
46    self.fun_defs.contains_key(name) || self.imp_defs.contains_key(name) || self.hvm_defs.contains_key(name)
47  }
48
49  pub fn contains_builtin_def(&self, name: &Name) -> Option<bool> {
50    self
51      .fun_defs
52      .get(name)
53      .map(|d| d.is_builtin())
54      .or_else(|| self.imp_defs.get(name).map(|d| d.source.is_builtin()))
55      .or_else(|| self.hvm_defs.get(name).map(|d| d.source.is_builtin()))
56  }
57}
58
59pub type ParseResult<T> = std::result::Result<T, ParseError>;
60
61pub struct FunParser<'i> {
62  file: Name,
63  input: &'i str,
64  index: usize,
65  builtin: bool,
66}
67
68impl<'a> FunParser<'a> {
69  pub fn new(file: Name, input: &'a str, builtin: bool) -> Self {
70    Self { file, input, index: 0, builtin }
71  }
72
73  /* AST parsing functions */
74
75  pub fn parse_book(&mut self, default_book: ParseBook) -> ParseResult<ParseBook> {
76    let mut book = default_book;
77    let mut indent = self.advance_newlines()?;
78    while !self.is_eof() {
79      // Record type definition
80      if self.starts_with_keyword("object") {
81        let ini_idx = *self.index();
82        let mut prs = ImpParser {
83          file: self.file.clone(),
84          input: self.input,
85          index: *self.index(),
86          builtin: self.builtin,
87        };
88        let (adt, nxt_indent) = prs.parse_object(indent)?;
89        self.index = prs.index;
90        let end_idx = *self.index();
91        self.add_type_def(adt, &mut book, ini_idx..end_idx)?;
92        indent = nxt_indent;
93        continue;
94      }
95
96      // Imp function definition
97      if self.starts_with_keyword("def") {
98        let ini_idx = *self.index();
99        let mut prs =
100          ImpParser { file: self.file.clone(), input: self.input, index: ini_idx, builtin: self.builtin };
101        let (def, nxt_indent) = prs.parse_function_def(indent)?;
102        self.index = prs.index;
103        let end_idx = *self.index();
104        self.add_imp_def(def, &mut book, ini_idx..end_idx)?;
105        indent = nxt_indent;
106        continue;
107      }
108
109      // Fun/Imp type definition
110      if self.starts_with_keyword("type") {
111        fn starts_with_imp_type(p: &mut FunParser) -> ParseResult<()> {
112          p.parse_keyword("type")?;
113          p.skip_trivia_inline()?;
114          p.parse_top_level_name()?;
115          p.skip_trivia_inline()?;
116          if p.starts_with(":") || p.starts_with("(") {
117            Ok(())
118          } else {
119            Err(ParseError::new((0, 0), ""))
120          }
121        }
122
123        let ini_idx = *self.index();
124        let is_imp = starts_with_imp_type(self).is_ok();
125        self.index = ini_idx;
126        if is_imp {
127          // Imp type definition
128          let mut prs = ImpParser {
129            file: self.file.clone(),
130            input: self.input,
131            index: *self.index(),
132            builtin: self.builtin,
133          };
134          let (adt, nxt_indent) = prs.parse_type_def(indent)?;
135          self.index = prs.index;
136          let end_idx = *self.index();
137          self.add_type_def(adt, &mut book, ini_idx..end_idx)?;
138          indent = nxt_indent;
139          continue;
140        } else {
141          // Fun type definition
142          let adt = self.parse_type_def()?;
143          let end_idx = *self.index();
144          self.add_type_def(adt, &mut book, ini_idx..end_idx)?;
145          indent = self.advance_newlines()?;
146          continue;
147        }
148      }
149
150      // HVM native function definition
151      if self.starts_with_keyword("hvm") {
152        let ini_idx = self.index;
153        let mut prs =
154          ImpParser { file: self.file.clone(), input: self.input, index: self.index, builtin: self.builtin };
155        let (def, nxt_indent) = prs.parse_hvm()?;
156        *self.index() = prs.index;
157        let end_idx = *self.index();
158        self.add_hvm(def, &mut book, ini_idx..end_idx)?;
159        indent = nxt_indent;
160        continue;
161      }
162
163      // Import declaration
164      if self.starts_with_keyword("from") {
165        let import = self.parse_from_import()?;
166        book.import_ctx.add_import(import);
167        indent = self.advance_newlines()?;
168        continue;
169      }
170
171      if self.starts_with_keyword("import") {
172        let imports = self.parse_import()?;
173        for imp in imports {
174          book.import_ctx.add_import(imp);
175        }
176        indent = self.advance_newlines()?;
177        continue;
178      }
179
180      // Fun function definition
181      let ini_idx = *self.index();
182      let def = self.parse_fun_def()?;
183      let end_idx = *self.index();
184
185      self.add_fun_def(def, &mut book, ini_idx..end_idx)?;
186      indent = self.advance_newlines()?;
187    }
188
189    Ok(book)
190  }
191
192  fn parse_type_def(&mut self) -> ParseResult<Adt> {
193    // type (name var1 ... varN) = ctr (| ctr)*
194    let ini_idx = self.index;
195    self.parse_keyword("type")?;
196    self.skip_trivia();
197
198    let name;
199    let vars;
200    if self.try_consume("(") {
201      // parens around name and vars
202      self.skip_trivia();
203      name = self.parse_restricted_name("Datatype")?;
204      vars = self
205        .labelled(|p| p.list_like(|p| p.parse_var_name(), "", ")", "", false, 0), "Type variable or ')'")?;
206      self.consume("=")?;
207    } else {
208      // no parens
209      name = self.parse_restricted_name("Datatype")?;
210      vars = self
211        .labelled(|p| p.list_like(|p| p.parse_var_name(), "", "=", "", false, 0), "Type variable or '='")?;
212    }
213
214    let mut ctrs = vec![self.parse_type_ctr(&name, &vars)?];
215    while self.try_consume("|") {
216      ctrs.push(self.parse_type_ctr(&name, &vars)?);
217    }
218    let ctrs = ctrs.into_iter().map(|ctr| (ctr.name.clone(), ctr)).collect::<IndexMap<_, _>>();
219
220    let end_idx = *self.index();
221    let source = Source::from_file_span(&self.file, self.input, ini_idx..end_idx, self.builtin);
222    let adt = Adt { name, vars, ctrs, source };
223    Ok(adt)
224  }
225
226  fn parse_type_ctr(&mut self, type_name: &Name, type_vars: &[Name]) -> ParseResult<AdtCtr> {
227    // '(' name (( '~'? field) | ('~'? '('field (':' type)? ')') )* ')'
228    // name
229    self.skip_trivia();
230    let ini_idx = *self.index();
231    if self.try_consume("(") {
232      // name and optionally fields
233
234      self.skip_trivia();
235      let ctr_name = self.parse_top_level_name()?;
236      let ctr_name = Name::new(format!("{type_name}/{ctr_name}"));
237
238      let fields = self.list_like(|p| p.parse_type_ctr_field(), "", ")", "", false, 0)?;
239      let field_types = fields.iter().map(|f| f.typ.clone()).collect::<Vec<_>>();
240      let end_idx = *self.index();
241      self.check_repeated_ctr_fields(&fields, &ctr_name, ini_idx..end_idx)?;
242
243      let typ = make_ctr_type(type_name.clone(), &field_types, type_vars);
244      let ctr = AdtCtr { name: ctr_name, typ, fields };
245      Ok(ctr)
246    } else {
247      // just name
248      let name = self.parse_restricted_name("Datatype constructor")?;
249      let name = Name::new(format!("{type_name}/{name}"));
250      let typ = make_ctr_type(type_name.clone(), &[], type_vars);
251      let ctr = AdtCtr { name, typ, fields: vec![] };
252      Ok(ctr)
253    }
254  }
255
256  fn parse_type_ctr_field(&mut self) -> ParseResult<CtrField> {
257    let rec = self.try_consume("~");
258
259    let nam;
260    let typ;
261    if self.try_consume("(") {
262      nam = self.parse_var_name()?;
263      if self.try_consume(":") {
264        typ = self.parse_type_term()?;
265      } else {
266        typ = Type::Any;
267      }
268      self.consume(")")?;
269    } else {
270      nam = self.parse_var_name()?;
271      typ = Type::Any;
272    }
273    Ok(CtrField { nam, typ, rec })
274  }
275
276  fn parse_fun_def(&mut self) -> ParseResult<FunDefinition> {
277    let ini_idx = *self.index();
278
279    // Try to parse signature
280    if let Ok((name, args, check, typ)) = self.parse_def_sig() {
281      if self.try_consume("=") {
282        // Single rule with signature
283        let body = self.parse_term()?;
284        let pats = args.into_iter().map(|nam| Pattern::Var(Some(nam))).collect();
285        let rules = vec![Rule { pats, body }];
286        let end_idx = *self.index();
287        let source = Source::from_file_span(&self.file, self.input, ini_idx..end_idx, self.builtin);
288        let def = FunDefinition { name, typ, check, rules, source };
289        Ok(def)
290      } else {
291        // Multiple rules with signature
292        let mut rules = vec![];
293        let (_, rule) = self.parse_rule()?;
294        rules.push(rule);
295        while self.starts_with_rule(&name) {
296          let (_, rule) = self.parse_rule()?;
297          rules.push(rule);
298        }
299        let end_idx = *self.index();
300        let source = Source::from_file_span(&self.file, self.input, ini_idx..end_idx, self.builtin);
301        let def = FunDefinition { name, typ, check, rules, source };
302        Ok(def)
303      }
304    } else {
305      // Was not a signature, backtrack and read the name from the first rule
306      self.index = ini_idx;
307      // No signature, don't check by default
308      let check = self.parse_checked(false);
309      let mut rules = vec![];
310      let (name, rule) = self.parse_rule()?;
311      rules.push(rule);
312      while self.starts_with_rule(&name) {
313        let (_, rule) = self.parse_rule()?;
314        rules.push(rule);
315      }
316      let end_idx = *self.index();
317      let source = Source::from_file_span(&self.file, self.input, ini_idx..end_idx, self.builtin);
318      let def = FunDefinition { name, typ: Type::Any, check, rules, source };
319      Ok(def)
320    }
321  }
322
323  /// Parses a function definition signature.
324  /// Returns the name, name of the arguments and the type of the function.
325  fn parse_def_sig(&mut self) -> ParseResult<(Name, Vec<Name>, bool, Type)> {
326    // '(' name ((arg | '(' arg (':' type)? ')'))* ')' ':' type
327    //     name ((arg | '(' arg (':' type)? ')'))*     ':' type
328    // Signature, check by default
329    let check = self.parse_checked(true);
330    let (name, args, typ) = if self.try_consume("(") {
331      let name = self.parse_top_level_name()?;
332      let args = self.list_like(|p| p.parse_def_sig_arg(), "", ")", "", false, 0)?;
333      self.consume(":")?;
334      let typ = self.parse_type_term()?;
335      (name, args, typ)
336    } else {
337      let name = self.parse_top_level_name()?;
338      let args = self.list_like(|p| p.parse_def_sig_arg(), "", ":", "", false, 0)?;
339      let typ = self.parse_type_term()?;
340      (name, args, typ)
341    };
342    let (args, arg_types): (Vec<_>, Vec<_>) = args.into_iter().unzip();
343    let typ = make_fn_type(arg_types, typ);
344    Ok((name, args, check, typ))
345  }
346
347  fn parse_def_sig_arg(&mut self) -> ParseResult<(Name, Type)> {
348    // name
349    // '(' name ')'
350    // '(' name ':' type ')'
351    if self.try_consume("(") {
352      let name = self.parse_var_name()?;
353      let typ = if self.try_consume(":") { self.parse_type_term()? } else { Type::Any };
354      self.consume(")")?;
355      Ok((name, typ))
356    } else {
357      let name = self.parse_var_name()?;
358      Ok((name, Type::Any))
359    }
360  }
361
362  fn parse_checked(&mut self, default: bool) -> bool {
363    if self.try_parse_keyword("checked") {
364      true
365    } else if self.try_parse_keyword("unchecked") {
366      false
367    } else {
368      default
369    }
370  }
371
372  fn parse_from_import(&mut self) -> ParseResult<Import> {
373    // from path import package
374    // from path import (a, b)
375    // from path import *
376    self.parse_keyword("from")?;
377    self.skip_trivia_inline()?;
378
379    let path = self.parse_restricted_name("Path")?;
380    self.skip_trivia_inline()?;
381
382    self.consume("import")?;
383    self.skip_trivia_inline()?;
384
385    let relative = path.starts_with("./") | path.starts_with("../");
386
387    if self.try_consume("*") {
388      return Ok(Import::new(path, ImportType::Glob, relative));
389    }
390
391    if self.try_consume("(") {
392      let sub = self.list_like(|p| p.parse_name_maybe_alias("Name"), "", ")", ",", false, 1)?;
393      return Ok(Import::new(path, ImportType::List(sub), relative));
394    }
395
396    let (import, alias) = self.parse_name_maybe_alias("Import")?;
397    Ok(Import::new(path, ImportType::Single(import, alias), relative))
398  }
399
400  fn parse_import(&mut self) -> ParseResult<Vec<Import>> {
401    // import path
402    // import (path/a, path/b)
403    self.parse_keyword("import")?;
404    self.skip_trivia_inline()?;
405
406    let new_import = |import: Name, alias: Option<Name>, relative: bool| -> Import {
407      let (path, import) = match import.rsplit_once('/') {
408        Some((start, end)) => (Name::new(start), Name::new(end)),
409        None => (Name::default(), import),
410      };
411
412      Import::new(path, ImportType::Single(import, alias), relative)
413    };
414
415    if self.try_consume("(") {
416      let list = self.list_like(|p| p.parse_import_name("Name"), "", ")", ",", false, 1)?;
417      let imports = list.into_iter().map(|(a, b, c)| new_import(a, b, c)).collect_vec();
418      return Ok(imports);
419    }
420
421    let (import, alias, relative) = self.parse_import_name("Import")?;
422    let import = new_import(import, alias, relative);
423    Ok(vec![import])
424  }
425
426  fn parse_rule_lhs(&mut self) -> ParseResult<(Name, Vec<Pattern>)> {
427    if self.try_consume_exactly("(") {
428      self.skip_trivia();
429      let name = self.parse_restricted_name("Function")?;
430      let pats = self.list_like(|p| p.parse_pattern(false), "", ")", "", false, 0)?;
431      Ok((name, pats))
432    } else {
433      // Rule without parens
434      // Here we use a different label for the error because this is
435      // the last alternative case for top-level definitions.
436      let name = self.labelled(|p| p.parse_top_level_name(), "top-level definition")?;
437      let mut pats = vec![];
438      self.skip_trivia();
439      while !self.starts_with("=") {
440        pats.push(self.parse_pattern(false)?);
441        self.skip_trivia();
442      }
443      Ok((name, pats))
444    }
445  }
446
447  fn parse_rule(&mut self) -> ParseResult<(Name, Rule)> {
448    self.skip_trivia();
449    let (name, pats) = self.parse_rule_lhs()?;
450
451    self.consume("=")?;
452
453    let body = self.parse_term()?;
454
455    let rule = Rule { pats, body };
456    Ok((name, rule))
457  }
458
459  fn starts_with_rule(&mut self, expected_name: &Name) -> bool {
460    let ini_idx = *self.index();
461    self.skip_trivia();
462    let res = self.parse_rule_lhs();
463    if !self.try_consume("=") {
464      self.index = ini_idx;
465      return false;
466    }
467    self.index = ini_idx;
468    if let Ok((name, _)) = res {
469      if &name == expected_name {
470        // Found rule with the expected name
471        true
472      } else {
473        // Found rule with a different name
474        false
475      }
476    } else {
477      // Not a rule
478      false
479    }
480  }
481
482  fn parse_pattern(&mut self, simple: bool) -> ParseResult<Pattern> {
483    maybe_grow(|| {
484      let (tag, unexpected_tag) = self.parse_tag()?;
485      self.skip_trivia();
486
487      // Ctr or Tup
488      if self.starts_with("(") {
489        self.advance_one();
490        let head_ini_idx = *self.index();
491        let head = self.parse_pattern(simple)?;
492        let head_end_idx = *self.index();
493
494        // Tup
495        self.skip_trivia();
496        if self.starts_with(",") || simple {
497          self.consume(",")?;
498          let mut els = self.list_like(|p| p.parse_pattern(simple), "", ")", ",", true, 1)?;
499          els.insert(0, head);
500          return Ok(Pattern::Fan(FanKind::Tup, tag.unwrap_or(Tag::Static), els));
501        }
502
503        // Ctr
504        unexpected_tag(self)?;
505        let Pattern::Var(Some(name)) = head else {
506          return self.expected_spanned("constructor name", head_ini_idx..head_end_idx);
507        };
508        let els = self.list_like(|p| p.parse_pattern(simple), "", ")", "", false, 0)?;
509        return Ok(Pattern::Ctr(name, els));
510      }
511
512      // Dup
513      if self.starts_with("{") {
514        let els = self.list_like(|p| p.parse_pattern(simple), "{", "}", ",", false, 0)?;
515        return Ok(Pattern::Fan(FanKind::Dup, tag.unwrap_or(Tag::Auto), els));
516      }
517
518      // List
519      if self.starts_with("[") && !simple {
520        unexpected_tag(self)?;
521        let els = self.list_like(|p| p.parse_pattern(simple), "[", "]", ",", false, 0)?;
522        return Ok(Pattern::Lst(els));
523      }
524
525      // String
526      if self.starts_with("\"") && !simple {
527        unexpected_tag(self)?;
528        let str = self.parse_quoted_string()?;
529        return Ok(Pattern::Str(STRINGS.get(str)));
530      }
531
532      // Char
533      if self.starts_with("'") {
534        unexpected_tag(self)?;
535        let char = self.parse_quoted_char()?;
536        return Ok(Pattern::Num(char as u32));
537      }
538
539      // Number
540      if self.peek_one().is_some_and(|c| c.is_ascii_digit()) {
541        unexpected_tag(self)?;
542        let num = self.parse_u32()?;
543        return Ok(Pattern::Num(num));
544      }
545
546      // Channel
547      if self.starts_with("$") {
548        unexpected_tag(self)?;
549        self.advance_one();
550        self.skip_trivia();
551        let name = self.parse_var_name()?;
552        return Ok(Pattern::Chn(name));
553      }
554
555      // Var
556      if self.starts_with("*")
557        || self
558          .peek_one()
559          .is_some_and(|c| c.is_ascii_alphanumeric() || c == '_' || c == '.' || c == '-' || c == '/')
560      {
561        unexpected_tag(self)?;
562        let nam = self.parse_name_or_era()?;
563        return Ok(Pattern::Var(nam));
564      }
565
566      let ini_idx = *self.index();
567      while !(self.is_eof() || self.starts_with("=")) {
568        self.advance_one();
569      }
570      let cur_idx = *self.index();
571
572      self.expected_spanned("pattern or '='", ini_idx..cur_idx)
573    })
574  }
575
576  pub fn parse_term(&mut self) -> ParseResult<Term> {
577    maybe_grow(|| {
578      let (tag, unexpected_tag) = self.parse_tag()?;
579      self.skip_trivia();
580
581      // Lambda, unscoped lambda
582      if self.starts_with("λ") || self.starts_with("@") {
583        self.advance_one();
584        let tag = tag.unwrap_or(Tag::Static);
585        let pat = self.parse_pattern(true)?;
586        let bod = self.parse_term()?;
587        return Ok(Term::Lam { tag, pat: Box::new(pat), bod: Box::new(bod) });
588      }
589
590      // App, Tup, Num Op
591      if self.starts_with("(") {
592        self.advance_one();
593        self.skip_trivia();
594
595        // Opr but maybe something else
596        // ( +/-n ,    -> Tup with Int/Float
597        // ( +/-n )    -> Int/Float
598        // ( +/-n term -> App with Int/Float
599        // ( * ,       -> Tup with Era
600        // ( * )       -> Era
601        // ( opr       -> Num Op
602        if let Some(opr) = self.try_parse_oper() {
603          if (opr == Op::ADD || opr == Op::SUB) && self.peek_one().is_some_and(|c| "0123456789".contains(c)) {
604            unexpected_tag(self)?;
605            *self.index() -= 1;
606            let num = self.parse_number()?;
607            let head = Term::Num { val: num };
608            self.skip_trivia();
609
610            if self.starts_with(",") {
611              self.consume_exactly(",")?;
612              let tail = self.list_like(|p| p.parse_term(), "", ")", ",", true, 1)?;
613              let els = [head].into_iter().chain(tail).collect();
614              return Ok(Term::Fan { fan: FanKind::Tup, tag: tag.unwrap_or(Tag::Static), els });
615            }
616
617            if self.starts_with(")") {
618              self.consume_exactly(")")?;
619              return Ok(head);
620            }
621
622            let els = self.list_like(|p| p.parse_term(), "", ")", "", false, 0)?;
623            let term = els.into_iter().fold(head, |fun, arg| Term::App {
624              tag: tag.clone().unwrap_or(Tag::Static),
625              fun: Box::new(fun),
626              arg: Box::new(arg),
627            });
628            return Ok(term);
629          }
630
631          self.skip_trivia();
632
633          if opr == Op::MUL && self.starts_with(",") {
634            self.consume_exactly(",")?;
635            let tail = self.list_like(|p| p.parse_term(), "", ")", ",", true, 1)?;
636            let els = [Term::Era].into_iter().chain(tail).collect();
637            return Ok(Term::Fan { fan: FanKind::Tup, tag: tag.unwrap_or(Tag::Static), els });
638          }
639
640          if opr == Op::MUL && self.starts_with(")") {
641            self.consume_exactly(")")?;
642            return Ok(Term::Era);
643          }
644
645          // Opr
646          unexpected_tag(self)?;
647          let fst = self.parse_term()?;
648          let snd = self.parse_term()?;
649          self.consume(")")?;
650          return Ok(Term::Oper { opr, fst: Box::new(fst), snd: Box::new(snd) });
651        }
652
653        // Tup or App
654        let head = self.parse_term()?;
655
656        // Tup
657        self.skip_trivia();
658        if self.starts_with(",") {
659          let mut els = vec![head];
660          while self.try_consume(",") {
661            els.push(self.parse_term()?);
662          }
663          self.consume(")")?;
664          return Ok(Term::Fan { fan: FanKind::Tup, tag: tag.unwrap_or(Tag::Static), els });
665        }
666
667        // App
668        let els = self.list_like(|p| p.parse_term(), "", ")", "", false, 0)?;
669        let term = els.into_iter().fold(head, |fun, arg| Term::App {
670          tag: tag.clone().unwrap_or(Tag::Static),
671          fun: Box::new(fun),
672          arg: Box::new(arg),
673        });
674        return Ok(term);
675      }
676
677      // List
678      if self.starts_with("[") {
679        unexpected_tag(self)?;
680        let els = self.list_like(|p| p.parse_term(), "[", "]", ",", false, 0)?;
681        return Ok(Term::List { els });
682      }
683
684      // Tree Node
685      if self.starts_with("![") {
686        self.advance_one();
687        self.advance_one();
688        unexpected_tag(self)?;
689        let lft = self.parse_term()?;
690        self.try_consume(",");
691        let rgt = self.parse_term()?;
692        self.labelled(|p| p.consume("]"), "Only two children in a Tree/Node")?;
693        return Ok(Term::call(Term::r#ref("Tree/Node"), [lft, rgt]));
694      }
695
696      // Tree Leaf
697      if self.starts_with("!") {
698        self.advance_one();
699        unexpected_tag(self)?;
700        let val = self.parse_term()?;
701        return Ok(Term::app(Term::r#ref("Tree/Leaf"), val));
702      }
703
704      // Sup
705      if self.starts_with("{") {
706        let els = self.list_like(|p| p.parse_term(), "{", "}", ",", false, 2)?;
707        return Ok(Term::Fan { fan: FanKind::Dup, tag: tag.unwrap_or(Tag::Auto), els });
708      }
709
710      // Unscoped var
711      if self.starts_with("$") {
712        self.advance_one();
713        unexpected_tag(self)?;
714        self.skip_trivia();
715        let nam = self.parse_var_name()?;
716        return Ok(Term::Link { nam });
717      }
718
719      // Era
720      if self.starts_with("*") {
721        self.advance_one();
722        unexpected_tag(self)?;
723        return Ok(Term::Era);
724      }
725
726      // Nat
727      if self.starts_with("#") {
728        self.advance_one();
729        unexpected_tag(self)?;
730        let val = self.parse_u32()?;
731        return Ok(Term::Nat { val });
732      }
733
734      // String
735      if self.starts_with("\"") {
736        unexpected_tag(self)?;
737        let str = self.parse_quoted_string()?;
738        return Ok(Term::Str { val: STRINGS.get(str) });
739      }
740
741      // Char
742      if self.starts_with("'") {
743        unexpected_tag(self)?;
744        let char = self.parse_quoted_char()?;
745        return Ok(Term::Num { val: Num::U24(char as u32 & 0x00ff_ffff) });
746      }
747
748      // Symbol
749      if self.starts_with("`") {
750        unexpected_tag(self)?;
751        let val = self.parse_quoted_symbol()?;
752        return Ok(Term::Num { val: Num::U24(val) });
753      }
754
755      // Native Number
756      if self.peek_one().is_some_and(is_num_char) {
757        unexpected_tag(self)?;
758        let num = self.parse_number()?;
759        return Ok(Term::Num { val: num });
760      }
761
762      // Use
763      if self.try_parse_keyword("use") {
764        unexpected_tag(self)?;
765        self.skip_trivia();
766        let nam = self.parse_var_name()?;
767        self.consume("=")?;
768        let val = self.parse_term()?;
769        self.try_consume(";");
770        let nxt = self.parse_term()?;
771        return Ok(Term::Use { nam: Some(nam), val: Box::new(val), nxt: Box::new(nxt) });
772      }
773
774      // Let
775      if self.try_parse_keyword("let") {
776        unexpected_tag(self)?;
777        let pat = self.parse_pattern(true)?;
778        self.consume("=")?;
779        let val = self.parse_term()?;
780        self.try_consume(";");
781        let nxt = self.parse_term()?;
782        return Ok(Term::Let { pat: Box::new(pat), val: Box::new(val), nxt: Box::new(nxt) });
783      }
784
785      // Ask (monadic operation)
786      if self.try_parse_keyword("ask") {
787        unexpected_tag(self)?;
788        let pat = self.parse_pattern(true)?;
789        self.consume("=")?;
790        let val = self.parse_term()?;
791        self.try_consume(";");
792        let nxt = self.parse_term()?;
793        return Ok(Term::Ask { pat: Box::new(pat), val: Box::new(val), nxt: Box::new(nxt) });
794      }
795
796      // Def
797      if self.try_parse_keyword("def") {
798        self.skip_trivia();
799        let mut def = self.parse_fun_def()?;
800        def.source.kind = SourceKind::Generated;
801        let nxt = self.parse_term()?;
802        return Ok(Term::Def { def, nxt: Box::new(nxt) });
803      }
804
805      // If
806      if self.try_parse_keyword("if") {
807        let mut chain = Vec::new();
808        let cnd = self.parse_term()?;
809        self.consume("{")?;
810        let thn = self.parse_term()?;
811        self.consume("}")?;
812
813        chain.push((cnd, thn));
814
815        self.skip_trivia_inline()?;
816        while self.try_parse_keyword("elif") {
817          let cnd = self.parse_term()?;
818          self.consume("{")?;
819          let thn = self.parse_term()?;
820          self.consume("}")?;
821          self.skip_trivia_inline()?;
822          chain.push((cnd, thn));
823        }
824
825        self.consume("else")?;
826        self.consume("{")?;
827        let els = self.parse_term()?;
828        self.consume("}")?;
829        let els = chain.into_iter().rfold(els, |acc, (cnd, thn)| Term::Swt {
830          bnd: Some(Name::new("%cond")),
831          arg: Box::new(cnd),
832          with_bnd: Vec::new(),
833          with_arg: Vec::new(),
834          pred: Some(Name::new("%cond-1")),
835          arms: vec![acc, thn],
836        });
837        return Ok(els);
838      }
839
840      // Match
841      if self.try_parse_keyword("match") {
842        unexpected_tag(self)?;
843        let (bnd, arg) = self.parse_match_arg()?;
844        let (with_bnd, with_arg) = self.parse_with_clause()?;
845        let arms = self.list_like(|p| p.parse_match_arm(), "", "}", ";", false, 1)?;
846        return Ok(Term::Mat { arg: Box::new(arg), bnd, with_bnd, with_arg, arms });
847      }
848
849      // Switch
850      if self.try_parse_keyword("switch") {
851        unexpected_tag(self)?;
852        let (bnd, arg) = self.parse_match_arg()?;
853        let (with_bnd, with_arg) = self.parse_with_clause()?;
854
855        self.try_consume("|");
856        self.consume("0")?;
857        self.consume(":")?;
858        let zero = self.parse_term()?;
859        self.try_consume(";");
860
861        let mut arms = vec![zero];
862        let mut expected_num = 1;
863        loop {
864          self.try_consume("|");
865          // case _
866          if self.try_consume("_") {
867            self.consume(":")?;
868            arms.push(self.parse_term()?);
869            self.try_consume(";");
870            self.consume("}")?;
871            break;
872          }
873          // case num
874          let val = self.parse_u32()?;
875          if val != expected_num {
876            return self.expected(&format!("'{}'", &expected_num.to_string()));
877          }
878          expected_num += 1;
879          self.consume(":")?;
880          arms.push(self.parse_term()?);
881          self.try_consume(";");
882        }
883        let pred = Some(Name::new(format!("{}-{}", bnd.as_ref().unwrap(), arms.len() - 1)));
884        return Ok(Term::Swt { arg: Box::new(arg), bnd, with_bnd, with_arg, pred, arms });
885      }
886
887      // With (monadic block)
888      if self.try_parse_keyword("with") {
889        unexpected_tag(self)?;
890        let typ = self.parse_name()?;
891        self.consume("{")?;
892        let bod = self.parse_term()?;
893        self.consume("}")?;
894        return Ok(Term::With { typ: Name::new(typ), bod: Box::new(bod) });
895      }
896
897      // Fold
898      if self.try_parse_keyword("fold") {
899        unexpected_tag(self)?;
900        let (bnd, arg) = self.parse_match_arg()?;
901        let (with_bnd, with_arg) = self.parse_with_clause()?;
902        let arms = self.list_like(|p| p.parse_match_arm(), "", "}", ";", false, 1)?;
903        return Ok(Term::Fold { arg: Box::new(arg), bnd, with_bnd, with_arg, arms });
904      }
905
906      // Bend
907      if self.try_parse_keyword("bend") {
908        unexpected_tag(self)?;
909        let args = self.list_like(
910          |p| {
911            let bind = p.parse_var_name()?;
912            let init = if p.try_consume("=") { p.parse_term()? } else { Term::Var { nam: bind.clone() } };
913            Ok((bind, init))
914          },
915          "",
916          "{",
917          ",",
918          false,
919          0,
920        )?;
921        let (bind, init): (Vec<_>, Vec<_>) = args.into_iter().unzip();
922        let bind = bind.into_iter().map(Some).collect::<Vec<_>>();
923        self.skip_trivia();
924        self.parse_keyword("when")?;
925        let cond = self.parse_term()?;
926        self.consume(":")?;
927        let step = self.parse_term()?;
928        self.skip_trivia();
929        self.parse_keyword("else")?;
930        self.consume(":")?;
931        let base = self.parse_term()?;
932        self.consume("}")?;
933        return Ok(Term::Bend {
934          bnd: bind,
935          arg: init,
936          cond: Box::new(cond),
937          step: Box::new(step),
938          base: Box::new(base),
939        });
940      }
941
942      // Open
943      if self.try_parse_keyword("open") {
944        unexpected_tag(self)?;
945        self.skip_trivia();
946        let typ = self.parse_top_level_name()?;
947        self.skip_trivia();
948        let var = self.parse_var_name()?;
949        self.try_consume(";");
950        let bod = self.parse_term()?;
951        return Ok(Term::Open { typ, var, bod: Box::new(bod) });
952      }
953
954      // Var
955      unexpected_tag(self)?;
956      let nam = self.labelled(|p| p.parse_var_name(), "term")?;
957      Ok(Term::Var { nam })
958    })
959  }
960
961  fn parse_name_or_era(&mut self) -> ParseResult<Option<Name>> {
962    self.labelled(
963      |p| {
964        if p.try_consume_exactly("*") {
965          Ok(None)
966        } else {
967          let nam = p.parse_var_name()?;
968          Ok(Some(nam))
969        }
970      },
971      "name or '*'",
972    )
973  }
974
975  /// Parses a tag where it may or may not be valid.
976  ///
977  /// If it is not valid, the returned callback can be used to issue an error.
978  fn parse_tag(&mut self) -> ParseResult<(Option<Tag>, impl FnOnce(&mut Self) -> ParseResult<()>)> {
979    let index = self.index;
980    self.skip_trivia();
981    let tag = if self.peek_one() == Some('#')
982      && !self.peek_many(2).is_some_and(|x| x.chars().nth(1).unwrap().is_ascii_digit())
983    {
984      let msg = "Tagged terms not supported for hvm32.".to_string();
985      return self.err_msg_spanned(&msg, index..index + 1);
986    } else {
987      None
988    };
989    let end_index = self.index;
990    Ok((tag.clone(), move |slf: &mut Self| {
991      if let Some(tag) = tag {
992        let msg = format!("Unexpected tag '{tag}'");
993        slf.err_msg_spanned(&msg, index..end_index)
994      } else {
995        Ok(())
996      }
997    }))
998  }
999
1000  // A named arg with optional name.
1001  fn parse_match_arg(&mut self) -> ParseResult<(Option<Name>, Term)> {
1002    let ini_idx = *self.index();
1003    let mut arg = self.parse_term()?;
1004    let end_idx = *self.index();
1005
1006    self.skip_trivia();
1007    match (&mut arg, self.starts_with("=")) {
1008      (Term::Var { nam }, true) => {
1009        self.consume("=")?;
1010        Ok((Some(std::mem::take(nam)), self.parse_term()?))
1011      }
1012      (Term::Var { nam }, false) => Ok((Some(nam.clone()), Term::Var { nam: std::mem::take(nam) })),
1013      (_, true) => self.expected_spanned("argument name", ini_idx..end_idx),
1014      (arg, false) => Ok((Some(Name::new("%arg")), std::mem::take(arg))),
1015    }
1016  }
1017
1018  /// A named arg with non-optional name.
1019  fn parse_named_arg(&mut self) -> ParseResult<(Option<Name>, Term)> {
1020    let nam = self.parse_var_name()?;
1021    self.skip_trivia();
1022    if self.starts_with("=") {
1023      self.advance_one();
1024      let arg = self.parse_term()?;
1025      Ok((Some(nam), arg))
1026    } else {
1027      let arg = Term::Var { nam: nam.clone() };
1028      Ok((Some(nam), arg))
1029    }
1030  }
1031
1032  fn parse_with_clause(&mut self) -> ParseResult<(Vec<Option<Name>>, Vec<Term>)> {
1033    self.skip_trivia();
1034    let res = if self.try_parse_keyword("with") {
1035      self.list_like(|p| p.parse_named_arg(), "", "{", ",", false, 1)?.into_iter().unzip()
1036    } else {
1037      self.consume_exactly("{")?;
1038      (vec![], vec![])
1039    };
1040    Ok(res)
1041  }
1042
1043  fn parse_match_arm(&mut self) -> ParseResult<MatchRule> {
1044    self.try_consume("|");
1045    self.skip_trivia();
1046    let nam = self.parse_name_or_era()?;
1047    self.consume(":")?;
1048    let bod = self.parse_term()?;
1049    Ok((nam, vec![], bod))
1050  }
1051
1052  fn parse_type_term(&mut self) -> ParseResult<Type> {
1053    let mut left = self.parse_type_atom()?;
1054    self.skip_trivia();
1055    while self.try_consume_exactly("->") {
1056      let right = self.parse_type_term()?;
1057      left = Type::Arr(Box::new(left), Box::new(right));
1058    }
1059    Ok(left)
1060  }
1061
1062  /// Parses a type without an ending arrow.
1063  /// Either an atom, a tuple, a ctr or a parenthesized type.
1064  fn parse_type_atom(&mut self) -> ParseResult<Type> {
1065    self.skip_trivia();
1066    if self.try_parse_keyword("Any") {
1067      Ok(Type::Any)
1068    } else if self.try_parse_keyword("None") {
1069      Ok(Type::None)
1070    } else if self.try_parse_keyword("_") {
1071      Ok(Type::Hole)
1072    } else if self.try_parse_keyword("u24") {
1073      Ok(Type::U24)
1074    } else if self.try_parse_keyword("i24") {
1075      Ok(Type::I24)
1076    } else if self.try_parse_keyword("f24") {
1077      Ok(Type::F24)
1078    } else if self.try_consume_exactly("(") {
1079      // Tuple, constructor or parenthesized expression
1080      let ini_idx = *self.index();
1081      let head = self.parse_type_term()?;
1082      self.skip_trivia();
1083      if self.try_consume_exactly(")") {
1084        // Parens
1085        Ok(head)
1086      } else if self.try_consume_exactly(",") {
1087        // Tuple
1088        let mut types = vec![head];
1089        loop {
1090          types.push(self.parse_type_term()?);
1091          self.skip_trivia();
1092          if !self.try_consume_exactly(",") {
1093            break;
1094          }
1095        }
1096        self.consume(")")?;
1097        Ok(Type::Tup(types))
1098      } else {
1099        // Constructor
1100        let Type::Var(nam) = head else {
1101          let end_idx = *self.index();
1102          // TODO: This is not a good error message
1103          return self.expected_spanned("type constructor", ini_idx..end_idx);
1104        };
1105        let mut args = vec![];
1106        // We know there's at least one argument, otherwise it would go in the parens case.
1107        while !self.try_consume(")") {
1108          args.push(self.parse_type_term()?);
1109          self.skip_trivia();
1110        }
1111        Ok(Type::Ctr(nam, args))
1112      }
1113    } else {
1114      // Variable
1115      // TODO: This will show "expected Name" instead of "expected type"
1116      let nam = self.parse_var_name()?;
1117      Ok(Type::Var(nam))
1118    }
1119  }
1120
1121  fn add_fun_def(&mut self, def: FunDefinition, book: &mut ParseBook, span: Range<usize>) -> ParseResult<()> {
1122    self.check_top_level_redefinition(&def.name, book, span)?;
1123    book.fun_defs.insert(def.name.clone(), def);
1124    Ok(())
1125  }
1126
1127  fn add_imp_def(
1128    &mut self,
1129    def: crate::imp::Definition,
1130    book: &mut ParseBook,
1131    span: Range<usize>,
1132  ) -> ParseResult<()> {
1133    self.check_top_level_redefinition(&def.name, book, span)?;
1134    book.imp_defs.insert(def.name.clone(), def);
1135    Ok(())
1136  }
1137
1138  fn add_hvm(&mut self, def: HvmDefinition, book: &mut ParseBook, span: Range<usize>) -> ParseResult<()> {
1139    self.check_top_level_redefinition(&def.name, book, span)?;
1140    book.hvm_defs.insert(def.name.clone(), def);
1141    Ok(())
1142  }
1143
1144  fn add_type_def(&mut self, adt: Adt, book: &mut ParseBook, span: Range<usize>) -> ParseResult<()> {
1145    self.check_type_redefinition(&adt.name, book, span.clone())?;
1146    for ctr in adt.ctrs.keys() {
1147      if let Some(builtin) = book.contains_builtin_def(ctr) {
1148        let msg = FunParser::redefinition_of_function_msg(builtin, ctr);
1149        return self.err_msg_spanned(&msg, span);
1150      }
1151      match book.ctrs.entry(ctr.clone()) {
1152        indexmap::map::Entry::Vacant(e) => _ = e.insert(adt.name.clone()),
1153        indexmap::map::Entry::Occupied(e) => {
1154          let msg = FunParser::redefinition_of_constructor_msg(e.key());
1155          return self.err_msg_spanned(&msg, span);
1156        }
1157      }
1158    }
1159    book.adts.insert(adt.name.clone(), adt);
1160    Ok(())
1161  }
1162
1163  fn check_top_level_redefinition(
1164    &mut self,
1165    name: &Name,
1166    book: &mut ParseBook,
1167    span: Range<usize>,
1168  ) -> ParseResult<()> {
1169    if let Some(builtin) = book.contains_builtin_def(name) {
1170      let msg = Self::redefinition_of_function_msg(builtin, name);
1171      return self.err_msg_spanned(&msg, span);
1172    }
1173    if book.ctrs.contains_key(name) {
1174      let msg = Self::redefinition_of_constructor_msg(name);
1175      return self.err_msg_spanned(&msg, span);
1176    }
1177    if book.hvm_defs.contains_key(name) {
1178      let msg = Self::redefinition_of_hvm_msg(false, name);
1179      return self.err_msg_spanned(&msg, span);
1180    }
1181    Ok(())
1182  }
1183
1184  fn check_type_redefinition(
1185    &mut self,
1186    name: &Name,
1187    book: &mut ParseBook,
1188    span: Range<usize>,
1189  ) -> ParseResult<()> {
1190    if book.adts.contains_key(name) {
1191      let msg = Self::redefinition_of_type_msg(name);
1192      return self.err_msg_spanned(&msg, span);
1193    }
1194    Ok(())
1195  }
1196}
1197
1198impl<'a> Parser<'a> for FunParser<'a> {
1199  fn input(&mut self) -> &'a str {
1200    self.input
1201  }
1202
1203  fn index(&mut self) -> &mut usize {
1204    &mut self.index
1205  }
1206
1207  /// Generates an error message for parsing failures, including the highlighted context.
1208  ///
1209  /// Override to have our own error message.
1210  fn expected<T>(&mut self, exp: &str) -> ParseResult<T> {
1211    let ini_idx = *self.index();
1212    let end_idx = *self.index() + 1;
1213    self.expected_spanned(exp, ini_idx..end_idx)
1214  }
1215
1216  /// Generates an error message with an additional custom message.
1217  ///
1218  /// Override to have our own error message.
1219  fn expected_and<T>(&mut self, exp: &str, msg: &str) -> ParseResult<T> {
1220    let ini_idx = *self.index();
1221    let end_idx = *self.index() + 1;
1222    self.expected_spanned_and(exp, msg, ini_idx..end_idx)
1223  }
1224
1225  /// Consumes an instance of the given string, erroring if it is not found.
1226  ///
1227  /// Override to have our own error message.
1228  fn consume(&mut self, text: &str) -> ParseResult<()> {
1229    self.skip_trivia();
1230    if self.input().get(*self.index()..).unwrap_or_default().starts_with(text) {
1231      *self.index() += text.len();
1232      Ok(())
1233    } else {
1234      self.expected(format!("'{text}'").as_str())
1235    }
1236  }
1237
1238  fn skip_trivia(&mut self) {
1239    while let Some(c) = self.peek_one() {
1240      if c.is_ascii_whitespace() {
1241        self.advance_one();
1242        continue;
1243      }
1244      if c == '#' {
1245        self.advance_one();
1246        if let Some(c) = self.peek_one() {
1247          if c == '{' {
1248            self.advance_one();
1249            while let Some(c) = self.peek_one() {
1250              self.advance_one();
1251              if c == '#' {
1252                if let Some('}') = self.peek_one() {
1253                  self.advance_one();
1254                  break;
1255                } else {
1256                  self.advance_one();
1257                }
1258              }
1259            }
1260          } else {
1261            while let Some(c) = self.peek_one() {
1262              if c != '\n' {
1263                self.advance_one();
1264              } else {
1265                break;
1266              }
1267            }
1268          }
1269        }
1270        continue;
1271      }
1272      break;
1273    }
1274  }
1275}
1276
1277pub fn is_name_char(c: char) -> bool {
1278  c.is_ascii_alphanumeric() || c == '_' || c == '.' || c == '-' || c == '/'
1279}
1280
1281pub fn is_num_char(c: char) -> bool {
1282  "0123456789+-".contains(c)
1283}
1284
1285pub fn make_fn_type(args: Vec<Type>, ret: Type) -> Type {
1286  args.into_iter().rfold(ret, |acc, typ| Type::Arr(Box::new(typ), Box::new(acc)))
1287}
1288
1289pub fn make_ctr_type(type_name: Name, fields: &[Type], vars: &[Name]) -> Type {
1290  let typ = Type::Ctr(type_name, vars.iter().cloned().map(Type::Var).collect());
1291  let typ = fields.iter().rfold(typ, |acc, typ| Type::Arr(Box::new(typ.clone()), Box::new(acc)));
1292  typ
1293}
1294
1295#[derive(Debug, PartialEq, Eq, Clone, Copy)]
1296pub enum Indent {
1297  Val(isize),
1298  Eof,
1299}
1300
1301impl Indent {
1302  pub fn new(val: isize) -> Self {
1303    Indent::Val(val)
1304  }
1305
1306  pub fn enter_level(&mut self) {
1307    if let Indent::Val(val) = self {
1308      *val += 2;
1309    }
1310  }
1311
1312  pub fn exit_level(&mut self) {
1313    if let Indent::Val(val) = self {
1314      *val -= 2;
1315    }
1316  }
1317}
1318
1319impl<'a> ParserCommons<'a> for FunParser<'a> {}
1320
1321pub trait ParserCommons<'a>: Parser<'a> {
1322  fn labelled<T>(&mut self, parser: impl Fn(&mut Self) -> ParseResult<T>, label: &str) -> ParseResult<T> {
1323    match parser(self) {
1324      Ok(val) => Ok(val),
1325      Err(_) => self.expected(label),
1326    }
1327  }
1328
1329  fn parse_restricted_name(&mut self, kind: &str) -> ParseResult<Name> {
1330    let ini_idx = *self.index();
1331    let name = self.take_while(is_name_char);
1332    if name.is_empty() {
1333      self.expected(&format!("{kind} name"))?
1334    }
1335    let name = Name::new(name.to_owned());
1336    let end_idx = *self.index();
1337    if name.contains("__") {
1338      let msg = format!("{kind} names are not allowed to contain \"__\".");
1339      self.err_msg_spanned(&msg, ini_idx..end_idx)
1340    } else if name.starts_with("//") {
1341      let msg = format!("{kind} names are not allowed to start with \"//\".");
1342      self.err_msg_spanned(&msg, ini_idx..end_idx)
1343    } else {
1344      Ok(name)
1345    }
1346  }
1347
1348  fn parse_top_level_name(&mut self) -> ParseResult<Name> {
1349    self.parse_restricted_name("Top-level")
1350  }
1351
1352  fn parse_var_name(&mut self) -> ParseResult<Name> {
1353    self.parse_restricted_name("Variable")
1354  }
1355
1356  fn parse_name_maybe_alias(&mut self, label: &str) -> ParseResult<(Name, Option<Name>)> {
1357    let name = self.parse_restricted_name(label)?;
1358
1359    if self.try_consume("as") {
1360      self.skip_trivia();
1361      let alias = self.parse_restricted_name("Alias")?;
1362      Ok((name, Some(alias)))
1363    } else {
1364      Ok((name, None))
1365    }
1366  }
1367
1368  fn parse_import_name(&mut self, label: &str) -> ParseResult<(Name, Option<Name>, bool)> {
1369    let (import, alias) = self.parse_name_maybe_alias(label)?;
1370    let relative = import.starts_with("./") | import.starts_with("../");
1371    Ok((import, alias, relative))
1372  }
1373
1374  /// Consumes exactly the text without skipping.
1375  fn consume_exactly(&mut self, text: &str) -> ParseResult<()> {
1376    if self.input().get(*self.index()..).unwrap_or_default().starts_with(text) {
1377      *self.index() += text.len();
1378      Ok(())
1379    } else {
1380      self.expected(format!("'{text}'").as_str())
1381    }
1382  }
1383
1384  fn consume_new_line(&mut self) -> ParseResult<()> {
1385    self.skip_trivia_inline()?;
1386    self.try_consume_exactly("\r");
1387    self.labelled(|p| p.consume_exactly("\n"), "newline")
1388  }
1389
1390  /// Skips trivia, returns the number of trivia characters skipped in the last line.
1391  fn advance_newlines(&mut self) -> ParseResult<Indent> {
1392    loop {
1393      let num_spaces = self.advance_trivia_inline()?;
1394      if self.peek_one() == Some('\r') {
1395        self.advance_one();
1396      }
1397      if self.peek_one() == Some('\n') {
1398        self.advance_one();
1399      } else if self.is_eof() {
1400        return Ok(Indent::Eof);
1401      } else {
1402        return Ok(Indent::Val(num_spaces));
1403      }
1404    }
1405  }
1406
1407  /// Advances the parser to the next non-trivia character in the same line.
1408  /// Returns how many characters were advanced.
1409  fn advance_trivia_inline(&mut self) -> ParseResult<isize> {
1410    let mut char_count = 0;
1411    while let Some(c) = self.peek_one() {
1412      if c == '\t' {
1413        let idx = *self.index();
1414        return self.err_msg_spanned("Tabs are not accepted for indentation.", idx..idx + 1);
1415      }
1416      if " ".contains(c) {
1417        self.advance_one();
1418        char_count += 1;
1419        continue;
1420      }
1421      if c == '#' {
1422        self.advance_one();
1423        char_count += 1;
1424        if let Some(c) = self.peek_one() {
1425          if c == '{' {
1426            self.advance_one();
1427            char_count += 1;
1428            while let Some(c) = self.peek_one() {
1429              self.advance_one();
1430              char_count += 1;
1431              if c == '#' {
1432                if let Some('}') = self.peek_one() {
1433                  self.advance_one();
1434                  char_count += 1;
1435                  break;
1436                } else {
1437                  self.advance_one();
1438                  char_count += 1;
1439                }
1440              }
1441            }
1442          } else {
1443            while let Some(c) = self.peek_one() {
1444              if c != '\n' {
1445                self.advance_one();
1446                char_count += 1;
1447              } else {
1448                break;
1449              }
1450            }
1451          }
1452        }
1453        continue;
1454      }
1455      break;
1456    }
1457    Ok(char_count)
1458  }
1459
1460  /// Skips until the next non-trivia character in the same line.
1461  fn skip_trivia_inline(&mut self) -> ParseResult<()> {
1462    self.advance_trivia_inline()?;
1463    Ok(())
1464  }
1465
1466  fn expected_spanned<T>(&mut self, exp: &str, span: Range<usize>) -> ParseResult<T> {
1467    let is_eof = self.is_eof();
1468    let detected = DisplayFn(|f| if is_eof { write!(f, " end of input") } else { Ok(()) });
1469    let msg = format!("\x1b[1m- expected:\x1b[0m {}\n\x1b[1m- detected:\x1b[0m{}", exp, detected);
1470    self.with_ctx(Err(msg), span)
1471  }
1472
1473  /// Same as `expected_spanned` but adds an information message before the expected message.
1474  fn expected_spanned_and<T>(&mut self, exp: &str, msg: &str, span: Range<usize>) -> ParseResult<T> {
1475    let is_eof = self.is_eof();
1476    let detected = DisplayFn(|f| if is_eof { write!(f, " end of input") } else { Ok(()) });
1477    let msg = format!(
1478      "\x1b[1m- information:\x1b[0m {}\n\x1b[1m- expected:\x1b[0m {}\n\x1b[1m- detected:\x1b[0m{}",
1479      msg, exp, detected,
1480    );
1481    self.with_ctx(Err(msg), span)
1482  }
1483
1484  /// If the parser result is an error, adds code location information to the error message.
1485  fn err_msg_spanned<T>(&mut self, msg: &str, span: Range<usize>) -> ParseResult<T> {
1486    let is_eof = self.is_eof();
1487    let eof_msg = if is_eof { " end of input" } else { "" };
1488    let msg = format!("{msg}\nLocation:{eof_msg}");
1489    self.with_ctx(Err(msg), span)
1490  }
1491
1492  /// If the parser result is an error, adds highlighted code context to the message.
1493  fn with_ctx<T>(&mut self, res: Result<T, impl std::fmt::Display>, span: Range<usize>) -> ParseResult<T> {
1494    res.map_err(|msg| {
1495      let ctx = highlight_error(span.start, span.end, self.input());
1496      let msg = format!("{msg}\n{ctx}");
1497      ParseError::new((span.start, span.end), msg)
1498    })
1499  }
1500
1501  /// Consumes text if the input starts with it or trivia. Otherwise, do nothing.
1502  fn try_consume(&mut self, text: &str) -> bool {
1503    self.skip_trivia();
1504    if self.starts_with(text) {
1505      self.consume(text).unwrap();
1506      true
1507    } else {
1508      false
1509    }
1510  }
1511
1512  /// Consumes text if the input starts exactly with it. Otherwise, do nothing.
1513  fn try_consume_exactly(&mut self, text: &str) -> bool {
1514    if self.starts_with(text) {
1515      self.consume_exactly(text).unwrap();
1516      true
1517    } else {
1518      false
1519    }
1520  }
1521
1522  fn try_parse_keyword(&mut self, keyword: &str) -> bool {
1523    if self.starts_with_keyword(keyword) {
1524      self.consume_exactly(keyword).unwrap();
1525      true
1526    } else {
1527      false
1528    }
1529  }
1530
1531  fn parse_keyword(&mut self, keyword: &str) -> ParseResult<()> {
1532    let ini_idx = *self.index();
1533    self.consume_exactly(keyword)?;
1534    let end_idx = *self.index();
1535    let input = &self.input()[*self.index()..];
1536    let next_is_name = input.chars().next().is_some_and(is_name_char);
1537    if !next_is_name {
1538      Ok(())
1539    } else {
1540      self.expected_spanned(&format!("keyword '{keyword}'"), ini_idx..end_idx + 1)
1541    }
1542  }
1543
1544  fn starts_with_keyword(&mut self, keyword: &str) -> bool {
1545    if self.starts_with(keyword) {
1546      let input = &self.input()[*self.index() + keyword.len()..];
1547      let next_is_name = input.chars().next().is_some_and(is_name_char);
1548      !next_is_name
1549    } else {
1550      false
1551    }
1552  }
1553
1554  /// Parses a list-like structure like "[x1, x2, x3,]".
1555  /// Since a list is always well terminated, we consume newlines.
1556  ///
1557  /// `parser` is a function that parses an element of the list.
1558  ///
1559  /// If `hard_sep` the separator between elements is mandatory.
1560  /// Always accepts trailing separators.
1561  ///
1562  /// `min_els` determines how many elements must be parsed at minimum.
1563  fn list_like<T>(
1564    &mut self,
1565    mut parser: impl FnMut(&mut Self) -> ParseResult<T>,
1566    start: &str,
1567    end: &str,
1568    sep: &str,
1569    hard_sep: bool,
1570    min_els: usize,
1571  ) -> ParseResult<Vec<T>> {
1572    self.consume_exactly(start)?;
1573
1574    let mut els = vec![];
1575    // Consume the minimum number of elements
1576    for i in 0..min_els {
1577      self.skip_trivia();
1578      els.push(parser(self)?);
1579      self.skip_trivia();
1580      if hard_sep && !(i == min_els - 1 && self.starts_with(end)) {
1581        self.consume(sep)?;
1582      } else {
1583        self.try_consume(sep);
1584      }
1585    }
1586
1587    // Consume optional elements
1588    while !self.try_consume(end) {
1589      els.push(parser(self)?);
1590      self.skip_trivia();
1591      if hard_sep && !self.starts_with(end) {
1592        self.consume(sep)?;
1593      } else {
1594        self.try_consume(sep);
1595      }
1596    }
1597    Ok(els)
1598  }
1599
1600  fn try_parse_oper(&mut self) -> Option<Op> {
1601    let opr = if self.try_consume_exactly("+") {
1602      Op::ADD
1603    } else if self.try_consume_exactly("-") {
1604      Op::SUB
1605    } else if self.try_consume_exactly("**") {
1606      Op::POW
1607    } else if self.try_consume_exactly("*") {
1608      Op::MUL
1609    } else if self.try_consume_exactly("/") {
1610      Op::DIV
1611    } else if self.try_consume_exactly("%") {
1612      Op::REM
1613    } else if self.try_consume_exactly("<<") {
1614      Op::SHL
1615    } else if self.try_consume_exactly(">>") {
1616      Op::SHR
1617    } else if self.try_consume_exactly("<=") {
1618      Op::LE
1619    } else if self.try_consume_exactly(">=") {
1620      Op::GE
1621    } else if self.try_consume_exactly("<") {
1622      Op::LT
1623    } else if self.try_consume_exactly(">") {
1624      Op::GT
1625    } else if self.try_consume_exactly("==") {
1626      Op::EQ
1627    } else if self.try_consume_exactly("!=") {
1628      Op::NEQ
1629    } else if self.try_consume_exactly("&") {
1630      Op::AND
1631    } else if self.try_consume_exactly("|") {
1632      Op::OR
1633    } else if self.try_consume_exactly("^") {
1634      Op::XOR
1635    } else {
1636      return None;
1637    };
1638    Some(opr)
1639  }
1640
1641  fn peek_oper(&mut self) -> Option<Op> {
1642    let opr = if self.starts_with("+") {
1643      Op::ADD
1644    } else if self.starts_with("-") {
1645      Op::SUB
1646    } else if self.starts_with("**") {
1647      Op::POW
1648    } else if self.starts_with("*") {
1649      Op::MUL
1650    } else if self.starts_with("/") {
1651      Op::DIV
1652    } else if self.starts_with("%") {
1653      Op::REM
1654    } else if self.starts_with("<<") {
1655      Op::SHL
1656    } else if self.starts_with(">>") {
1657      Op::SHR
1658    } else if self.starts_with("<=") {
1659      Op::LE
1660    } else if self.starts_with(">=") {
1661      Op::GE
1662    } else if self.starts_with("<") {
1663      Op::LT
1664    } else if self.starts_with(">") {
1665      Op::GT
1666    } else if self.starts_with("==") {
1667      Op::EQ
1668    } else if self.starts_with("!=") {
1669      Op::NEQ
1670    } else if self.starts_with("&") {
1671      Op::AND
1672    } else if self.starts_with("|") {
1673      Op::OR
1674    } else if self.starts_with("^") {
1675      Op::XOR
1676    } else {
1677      return None;
1678    };
1679    Some(opr)
1680  }
1681
1682  fn parse_u32(&mut self) -> ParseResult<u32> {
1683    let radix = match self.peek_many(2) {
1684      Some("0x") => {
1685        self.advance_many(2);
1686        Radix::Hex
1687      }
1688      Some("0b") => {
1689        self.advance_many(2);
1690        Radix::Bin
1691      }
1692      _ => Radix::Dec,
1693    };
1694    let num_str = self.take_while(move |c| c.is_digit(radix as u32) || c == '_');
1695    let num_str = num_str.chars().filter(|c| *c != '_').collect::<String>();
1696
1697    let next_is_hex = self.peek_one().is_some_and(|c| "0123456789abcdefABCDEF".contains(c));
1698    if next_is_hex || num_str.is_empty() {
1699      self.expected(format!("valid {radix} digit").as_str())
1700    } else {
1701      u32::from_str_radix(&num_str, radix as u32)
1702        .map_err(|e| self.expected_and::<u64>("integer", &e.to_string()).unwrap_err())
1703    }
1704  }
1705
1706  fn u32_with_radix(&mut self, radix: Radix) -> ParseResult<u32> {
1707    let num_str = self.take_while(move |c| c.is_digit(radix as u32) || c == '_');
1708    let num_str = num_str.chars().filter(|c| *c != '_').collect::<String>();
1709    let next_is_hex = self.peek_one().is_some_and(|c| "0123456789abcdefABCDEF".contains(c));
1710    if next_is_hex || num_str.is_empty() {
1711      self.expected(format!("valid {radix} digit").as_str())
1712    } else {
1713      u32::from_str_radix(&num_str, radix as u32)
1714        .map_err(|e| self.expected_and::<u64>("integer", &e.to_string()).unwrap_err())
1715    }
1716  }
1717
1718  fn parse_number(&mut self) -> ParseResult<Num> {
1719    let ini_idx = *self.index();
1720    let sign = if self.try_consume_exactly("+") {
1721      Some(1)
1722    } else if self.try_consume_exactly("-") {
1723      Some(-1)
1724    } else {
1725      None
1726    };
1727    let radix = match self.peek_many(2) {
1728      Some("0x") => {
1729        self.advance_many(2);
1730        Radix::Hex
1731      }
1732      Some("0b") => {
1733        self.advance_many(2);
1734        Radix::Bin
1735      }
1736      _ => Radix::Dec,
1737    };
1738    let num = self.u32_with_radix(radix)?;
1739    let frac = if let Some('.') = self.peek_one() {
1740      self.advance_one();
1741      let fra_str = self.take_while(|c| c.is_digit(radix as u32) || c == '_');
1742      let fra_str = fra_str.chars().filter(|c| *c != '_').collect::<String>();
1743      let fra = u32::from_str_radix(&fra_str, radix as u32)
1744        .map_err(|e| self.expected_and::<u64>("integer", &e.to_string()).unwrap_err())?;
1745      let fra = fra as f32 / (radix.to_f32()).powi(fra_str.len() as i32);
1746      Some(fra)
1747    } else {
1748      None
1749    };
1750
1751    if let Some(frac) = frac {
1752      let sign = sign.unwrap_or(1);
1753      return Ok(Num::F24(sign as f32 * (num as f32 + frac)));
1754    }
1755
1756    if let Some(sign) = sign {
1757      let num = sign * num as i32;
1758      if !(-0x00800000..=0x007fffff).contains(&num) {
1759        return self.num_range_err(ini_idx, "I24");
1760      }
1761      Ok(Num::I24(num))
1762    } else {
1763      if num >= 1 << 24 {
1764        return self.num_range_err(ini_idx, "U24");
1765      }
1766      Ok(Num::U24(num))
1767    }
1768  }
1769
1770  fn num_range_err<T>(&mut self, ini_idx: usize, typ: &str) -> ParseResult<T> {
1771    let msg = format!("\x1b[1mNumber literal outside of range for {}.\x1b[0m", typ);
1772    let end_idx = *self.index();
1773    self.err_msg_spanned(&msg, ini_idx..end_idx)
1774  }
1775
1776  /// Parses up to 4 base64 characters surrounded by "`".
1777  /// Joins the characters into a u24 and returns it.
1778  fn parse_quoted_symbol(&mut self) -> ParseResult<u32> {
1779    self.consume_exactly("`")?;
1780    let mut result = 0;
1781    let mut count = 0;
1782    while count < 4 {
1783      if self.starts_with("`") {
1784        break;
1785      }
1786      count += 1;
1787      let Some(c) = self.advance_one() else { self.expected("base_64 character")? };
1788      let c = c as u8;
1789      let nxt = match c {
1790        b'A'..=b'Z' => c - b'A',
1791        b'a'..=b'z' => c - b'a' + 26,
1792        b'0'..=b'9' => c - b'0' + 52,
1793        b'+' => 62,
1794        b'/' => 63,
1795        _ => return self.expected("base64 character"),
1796      };
1797      result = (result << 6) | nxt as u32;
1798    }
1799    self.consume_exactly("`")?;
1800    Ok(result)
1801  }
1802
1803  fn check_repeated_ctr_fields(
1804    &mut self,
1805    fields: &[CtrField],
1806    ctr_name: &Name,
1807    span: Range<usize>,
1808  ) -> ParseResult<()> {
1809    for i in 0..fields.len() {
1810      let field = &fields[i];
1811      if fields.iter().skip(i + 1).any(|a: &CtrField| a.nam == field.nam) {
1812        let msg = format!("Found a repeated field '{}' in constructor {}.", field.nam, ctr_name);
1813        return self.err_msg_spanned(&msg, span);
1814      }
1815    }
1816    Ok(())
1817  }
1818
1819  fn redefinition_of_function_msg(builtin: bool, function_name: &str) -> String {
1820    if builtin {
1821      format!("Redefinition of builtin (function) '{function_name}'.")
1822    } else {
1823      format!("Redefinition of function '{function_name}'.")
1824    }
1825  }
1826
1827  fn redefinition_of_hvm_msg(builtin: bool, function_name: &str) -> String {
1828    if builtin {
1829      format!("Redefinition of builtin (native HVM function) '{function_name}'.")
1830    } else {
1831      format!("Redefinition of native HVM function '{function_name}'.")
1832    }
1833  }
1834
1835  fn redefinition_of_constructor_msg(constructor_name: &str) -> String {
1836    if crate::fun::builtins::BUILTIN_CTRS.contains(&constructor_name) {
1837      format!("Redefinition of builtin (constructor) '{constructor_name}'.")
1838    } else {
1839      format!("Redefinition of constructor '{constructor_name}'.")
1840    }
1841  }
1842
1843  fn redefinition_of_type_msg(type_name: &str) -> String {
1844    if crate::fun::builtins::BUILTIN_TYPES.contains(&type_name) {
1845      format!("Redefinition of builtin (type) '{type_name}'.")
1846    } else {
1847      format!("Redefinition of type '{type_name}'.")
1848    }
1849  }
1850}
1851
1852#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1853pub enum Radix {
1854  Bin = 2,
1855  Dec = 10,
1856  Hex = 16,
1857}
1858
1859impl Radix {
1860  fn to_f32(self) -> f32 {
1861    match self {
1862      Radix::Bin => 2.,
1863      Radix::Dec => 10.,
1864      Radix::Hex => 16.,
1865    }
1866  }
1867}
1868
1869impl std::fmt::Display for Radix {
1870  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1871    match self {
1872      Radix::Bin => write!(f, "binary"),
1873      Radix::Dec => write!(f, "decimal"),
1874      Radix::Hex => write!(f, "hexadecimal"),
1875    }
1876  }
1877}