bend/fun/transform/
apply_args.rs

1use crate::{
2  diagnostics::Diagnostics,
3  fun::{Ctx, Pattern, Rule, Term},
4};
5
6impl Ctx<'_> {
7  /// Applies the arguments to the program being run by applying them to the main function.
8  ///
9  /// Example:
10  /// ```hvm
11  /// main x1 x2 x3 = (MainBody x1 x2 x3)
12  /// ```
13  /// Calling with `bend run <file> arg1 arg2 arg3`, it becomes:
14  /// ```hvm
15  /// main = (λx1 λx2 λx3 (MainBody x1 x2 x3) arg1 arg2 arg3)
16  /// ```
17  pub fn apply_args(&mut self, args: Option<Vec<Term>>) -> Result<(), Diagnostics> {
18    if let Some(entrypoint) = &self.book.entrypoint {
19      let main_def = &mut self.book.defs[entrypoint];
20
21      // Since we fatal error, no need to exit early
22      let n_rules = main_def.rules.len();
23      if n_rules != 1 {
24        self.info.add_function_error(
25          format!("Expected the entrypoint function to have only one rule, found {n_rules}."),
26          entrypoint.clone(),
27          main_def.source.clone(),
28        );
29      }
30
31      let mut main_body = std::mem::take(&mut main_def.rules[0].body);
32
33      for pat in main_def.rules[0].pats.iter().rev() {
34        if let Pattern::Var(var) = pat {
35          main_body = Term::lam(Pattern::Var(var.clone()), main_body);
36        } else {
37          self.info.add_function_error(
38            format!("Expected the entrypoint function to only have variable patterns, found '{pat}'."),
39            entrypoint.clone(),
40            main_def.source.clone(),
41          );
42        }
43      }
44
45      if let Some(args) = args {
46        main_body = Term::call(main_body, args);
47      }
48
49      main_def.rules = vec![Rule { pats: vec![], body: main_body }];
50    }
51
52    self.info.fatal(())
53  }
54}