repos / machines.rs.git


machines.rs.git / src / abstract_machines
Evgenii Akentev  ·  2024-09-24

cek.rs

 1#[derive(Clone, Debug)]
 2enum Term {
 3    Appl(Box<(Term, Term)>),
 4    Var(usize),
 5    Abst(Box<Term>),
 6}
 7
 8impl Term {
 9    fn eval(&self, e: Vec<Value>, k: Cont) -> Value {
10        match self {
11            Term::Var(v) => k.cont(e[*v].clone()),
12            Term::Abst(t) => k.cont(Value::Closure(*t.clone(), e)),
13            Term::Appl(tuple) => {
14                let (t0, t1) = *tuple.clone();
15                t0.eval(e.clone(), Cont::C2(t1, e.clone(), Box::new(k)))
16            }
17        }
18    }
19}
20
21#[derive(Clone, Debug)]
22enum Value {
23    Closure(Term, Vec<Value>),
24}
25
26impl Value {
27    fn apply(&self, v1: Value, k: Cont) -> Value {
28        match self {
29            Value::Closure(t, e) => {
30                let mut new_e = vec![v1];
31                new_e.append(e.clone().as_mut());
32                t.eval(new_e.clone(), k)
33            },
34        }
35    }
36}
37
38#[derive(Clone)]
39enum Cont {
40    C0,
41    C1(Value, Box<Cont>),
42    C2(Term, Vec<Value>, Box<Cont>)
43}
44
45impl Cont {
46    fn cont(&self, v: Value) -> Value {
47        match self {
48            Cont::C0 => v,
49            Cont::C1(v0, k) => { v0.apply(v, *k.clone()) },
50            Cont::C2(t1, e, k) => { t1.eval(e.to_vec(), Cont::C1(v, k.clone())) }
51        }
52    }
53}
54
55
56pub fn main() {
57    use Term::*;
58    println!("CEK:");
59
60    let t1: Term = Appl(Box::new((Abst(Box::new(Appl(Box::new((Var(0), Var(0)))))), (Abst(Box::new(Var(0)))))));
61    let result = t1.eval(vec![], Cont::C0);
62    println!("T1 eval: {:?}", result);
63
64    let t2: Term = Appl(Box::new((Appl(Box::new((Abst(Box::new(Var(0))), Abst(Box::new(Var(0)))))), Abst(Box::new(Var(0))))));
65    let result2 = t2.eval(vec![], Cont::C0);                                                                     
66    println!("T2 eval: {:?}", result2);
67}