Skip to main content

mest_core/
thunk.rs

1use crate::ast::{Env, EvalError, ExprKind, Value};
2use lasso::Rodeo;
3use std::cell::RefCell;
4use std::rc::Rc;
5
6#[derive(Clone, Debug)]
7pub struct Thunk<'bump> {
8    expr: &'bump ExprKind<'bump>,
9    env: Rc<RefCell<Env<'bump>>>,
10    value: Rc<RefCell<Option<Value<'bump>>>>,
11}
12
13impl<'bump> Thunk<'bump> {
14    pub fn new(expr: &'bump ExprKind<'bump>, env: Env<'bump>) -> Self {
15        Self {
16            expr,
17            env: Rc::new(RefCell::new(env)),
18            value: Rc::new(RefCell::new(None)),
19        }
20    }
21
22    pub fn new_shared(expr: &'bump ExprKind<'bump>, env: Rc<RefCell<Env<'bump>>>) -> Self {
23        Self {
24            expr,
25            env,
26            value: Rc::new(RefCell::new(None)),
27        }
28    }
29
30    pub fn env_cell(&self) -> Rc<RefCell<Env<'bump>>> {
31        Rc::clone(&self.env)
32    }
33
34    pub fn force(&self, rodeo: &Rodeo) -> Result<Value<'bump>, EvalError> {
35        if let Some(val) = self.value.borrow().as_ref() {
36            return Ok(val.clone());
37        }
38        let env = self.env.borrow().clone();
39        let val = self.expr.eval_lazy(&env, rodeo)?;
40        *self.value.borrow_mut() = Some(val.clone());
41        Ok(val)
42    }
43}