Skip to main content

tidepool_eval/
value.rs

1use crate::env::Env;
2use tidepool_repr::{CoreExpr, DataConId, Literal, VarId};
3
4/// Runtime value for the tree-walking interpreter.
5#[derive(Debug, Clone)]
6pub enum Value {
7    /// Literal value (Int, Word, Char, String, Float, Double)
8    Lit(Literal),
9    /// Fully-applied data constructor
10    Con(DataConId, Vec<Value>),
11    /// Closure: captured env + binder + body
12    Closure(Env, VarId, CoreExpr),
13    /// Reference to a heap-allocated thunk
14    ThunkRef(ThunkId),
15    /// Join point continuation (lives in Env only, never heap-allocated)
16    JoinCont(Vec<VarId>, CoreExpr, Env),
17    /// Partially-applied data constructor: (tag, arity, accumulated args)
18    /// When all args are supplied, collapses to Con.
19    ConFun(DataConId, usize, Vec<Value>),
20}
21
22/// Thunk identifier — index into the thunk store.
23#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
24pub struct ThunkId(pub u32);
25
26#[cfg(test)]
27mod tests {
28    use super::*;
29    use tidepool_repr::{CoreFrame, RecursiveTree};
30
31    #[test]
32    fn test_value_construction() {
33        let env = Env::new();
34        let lit = Value::Lit(Literal::LitInt(42));
35        let con = Value::Con(DataConId(1), vec![lit.clone()]);
36
37        let expr = RecursiveTree {
38            nodes: vec![CoreFrame::Var(VarId(0))],
39        };
40        let closure = Value::Closure(env.clone(), VarId(0), expr.clone());
41        let thunk = Value::ThunkRef(ThunkId(0));
42        let join = Value::JoinCont(vec![VarId(1)], expr, env);
43
44        match lit {
45            Value::Lit(_) => (),
46            _ => panic!("Expected Lit"),
47        }
48        match con {
49            Value::Con(_, _) => (),
50            _ => panic!("Expected Con"),
51        }
52        match closure {
53            Value::Closure(_, _, _) => (),
54            _ => panic!("Expected Closure"),
55        }
56        match thunk {
57            Value::ThunkRef(_) => (),
58            _ => panic!("Expected ThunkRef"),
59        }
60        match join {
61            Value::JoinCont(_, _, _) => (),
62            _ => panic!("Expected JoinCont"),
63        }
64    }
65
66    #[test]
67    fn test_closure_clone() {
68        let env = Env::new();
69        let expr = RecursiveTree {
70            nodes: vec![CoreFrame::Var(VarId(0))],
71        };
72        let closure = Value::Closure(env, VarId(0), expr);
73        let _cloned = closure.clone();
74    }
75}