1use std::cell::RefCell;
2
3use crate::{value::NumLike, Value};
4
5type ParentsPartials<T> = (usize, T);
6
7#[derive(Clone, Copy)]
8pub struct Node<T> {
9    pub parents_partials: [ParentsPartials<T>; 2],
10}
11
12pub struct Scope<T> {
13    pub nodes: RefCell<Vec<Node<T>>>,
14}
15
16impl<T: NumLike> Scope<T> {
17    pub fn new() -> Scope<T> {
18        Scope {
19            nodes: RefCell::new(Vec::<Node<T>>::new()),
20        }
21    }
22
23    pub fn value(&self, value: T) -> Value<T> {
24        let len = self.nodes.borrow().len();
25        self.nodes.borrow_mut().push(Node {
26            parents_partials: [(len, T::zero()), (len, T::zero())],
27        });
28        Value {
29            scope: self,
30            idx: len,
31            val: value,
32        }
33    }
34
35    pub fn op(
36        &self,
37        lhs_partial: T,
38        rhs_partial: T,
39        lhs_idx: usize,
40        rhs_idx: usize,
41        new_value: T,
42    ) -> Value<T> {
43        let len = self.nodes.borrow().len();
44        self.nodes.borrow_mut().push(Node {
45            parents_partials: [(lhs_idx, lhs_partial), (rhs_idx, rhs_partial)],
46        });
47        Value {
48            scope: self,
49            idx: len,
50            val: new_value,
51        }
52    }
53
54    pub fn constant_op(&self, partial: T, idx: usize, new_value: T) -> Value<T> {
55        let len = self.nodes.borrow().len();
56        self.nodes.borrow_mut().push(Node {
57            parents_partials: [(idx, partial), (len, T::zero())],
58        });
59        Value {
60            scope: self,
61            idx: len,
62            val: new_value,
63        }
64    }
65}