Repository: Kindelia/HVM
File: src/ast.rs (Rust)

Code before:
        def.node[index] = hvm::Pair::new(p1, p2);
        return hvm::Port::new(hvm::OPR, index as hvm::Val);
      },
      Tree::Swi { fst, snd } => {
        let index = def.node.len();
        def.node.push(hvm::Pair(0));
        let p1 = fst.build(def, fids, vars);
        let p2 = snd.build(def, fids, vars);
        def.node[index] = hvm::Pair::new(p1, p2);
        return hvm::Port::new(hvm::SWI, index as hvm::Val);
      },
    }
  }

  pub fn direct_dependencies<'name>(&'name self) -> BTreeSet<&'name str> {
    match self {
      Tree::Ref { nam } => BTreeSet::from([nam.as_str()]),
      Tree::Con { fst, snd } => &fst.direct_dependencies() | &snd.direct_dependencies(),
      Tree::Dup { fst, snd } => &fst.direct_dependencies() | &snd.direct_dependencies(),
      Tree::Opr { fst, snd } => &fst.direct_dependencies() | &snd.direct_dependencies(),
      Tree::Swi { fst, snd } => &fst.direct_dependencies() | &snd.direct_dependencies(),
      Tree::Num { val } => BTreeSet::new(),
      Tree::Var { nam } => BTreeSet::new(),
      Tree::Era => BTreeSet::new(),
    }
  }
}

impl Net {
  pub fn build(&self, def: &mut hvm::Def, fids: &BTreeMap<String, hvm::Val>, vars: &mut BTreeMap<String, hvm::Val>) {
    let index = def.node.len();
    def.root = self.root.build(def, fids, vars);
    for (par, fst, snd) in &self.rbag {
      let index = def.rbag.len();
      def.rbag.push(hvm::Pair(0));
      let p1 = fst.build(def, fids, vars);
      let p2 = snd.build(def, fids, vars);
      let rx = hvm::Pair::new(p1, p2);
      let rx = if *par { rx.set_par_flag() } else { rx };
      def.rbag[index] = rx;
    }
  }
}

impl Book {
  pub fn parse(code: &str) -> Result<Self, String> {
    CoreParser::new(code).parse_book()
  }

  pub fn build(&self) -> hvm::Book {
    let mut name_to_fid = BTreeMap::new();

Review comment (bug):
Writing a recursive function like this may not be the best idea since we still don't have a way to increase stack size as needed like in the `hvm-64` repo. I think it's fine for now to add this function like this, since pretty much all the other functions related to trees are also recursive and if this one fails, they do too.

Code after:
        def.node[index] = hvm::Pair::new(p1, p2);
        return hvm::Port::new(hvm::OPR, index as hvm::Val);
      },
      Tree::Swi { fst, snd } => {
        let index = def.node.len();
        def.node.push(hvm::Pair(0));
        let p1 = fst.build(def, fids, vars);
        let p2 = snd.build(def, fids, vars);
        def.node[index] = hvm::Pair::new(p1, p2);
        return hvm::Port::new(hvm::SWI, index as hvm::Val);
      },
    }
  }

  pub fn direct_dependencies<'name>(&'name self) -> BTreeSet<&'name str> {
    let mut stack: Vec<&Tree> = vec![self];
    let mut acc: BTreeSet<&'name str> = BTreeSet::new();
    
    while let Some(curr) = stack.pop() {
      match curr {
        Tree::Ref { nam } => { acc.insert(nam); },
        Tree::Con { fst, snd } => { stack.push(fst); stack.push(snd); },
        Tree::Dup { fst, snd } => { stack.push(fst); stack.push(snd); },
        Tree::Opr { fst, snd } => { stack.push(fst); stack.push(snd); },
        Tree::Swi { fst, snd } => { stack.push(fst); stack.push(snd); },
        Tree::Num { val } => {},
        Tree::Var { nam } => {},
        Tree::Era => {},
      };
    }
    acc
  }
}

impl Net {
  pub fn build(&self, def: &mut hvm::Def, fids: &BTreeMap<String, hvm::Val>, vars: &mut BTreeMap<String, hvm::Val>) {
    let index = def.node.len();
    def.root = self.root.build(def, fids, vars);
    for (par, fst, snd) in &self.rbag {
      let index = def.rbag.len();
      def.rbag.push(hvm::Pair(0));
      let p1 = fst.build(def, fids, vars);
      let p2 = snd.build(def, fids, vars);
      let rx = hvm::Pair::new(p1, p2);
      let rx = if *par { rx.set_par_flag() } else { rx };
      def.rbag[index] = rx;
    }
  }
}

impl Book {