repos / machines.rs.git


commit
50cdfb8
parent
50cdfb8
author
Evgenii Akentev
date
2024-09-24 11:48:20 +0400 +04
Add CEK
7 files changed,  +88, -0
A .gitignore
+1, -0
1@@ -0,0 +1 @@
2+/target
A Cargo.lock
+7, -0
1@@ -0,0 +1,7 @@
2+# This file is automatically @generated by Cargo.
3+# It is not intended for manual editing.
4+version = 3
5+
6+[[package]]
7+name = "machines"
8+version = "0.1.0"
A Cargo.toml
+6, -0
1@@ -0,0 +1,6 @@
2+[package]
3+name = "machines"
4+version = "0.1.0"
5+edition = "2021"
6+
7+[dependencies]
A src/abstract_machines/cek.rs
+67, -0
 1@@ -0,0 +1,67 @@
 2+#[derive(Clone, Debug)]
 3+enum Term {
 4+    Appl(Box<(Term, Term)>),
 5+    Var(usize),
 6+    Abst(Box<Term>),
 7+}
 8+
 9+impl Term {
10+    fn eval(&self, e: Vec<Value>, k: Cont) -> Value {
11+        match self {
12+            Term::Var(v) => k.cont(e[*v].clone()),
13+            Term::Abst(t) => k.cont(Value::Closure(*t.clone(), e)),
14+            Term::Appl(tuple) => {
15+                let (t0, t1) = *tuple.clone();
16+                t0.eval(e.clone(), Cont::C2(t1, e.clone(), Box::new(k)))
17+            }
18+        }
19+    }
20+}
21+
22+#[derive(Clone, Debug)]
23+enum Value {
24+    Closure(Term, Vec<Value>),
25+}
26+
27+impl Value {
28+    fn apply(&self, v1: Value, k: Cont) -> Value {
29+        match self {
30+            Value::Closure(t, e) => {
31+                let mut new_e = vec![v1];
32+                new_e.append(e.clone().as_mut());
33+                t.eval(new_e.clone(), k)
34+            },
35+        }
36+    }
37+}
38+
39+#[derive(Clone)]
40+enum Cont {
41+    C0,
42+    C1(Value, Box<Cont>),
43+    C2(Term, Vec<Value>, Box<Cont>)
44+}
45+
46+impl Cont {
47+    fn cont(&self, v: Value) -> Value {
48+        match self {
49+            Cont::C0 => v,
50+            Cont::C1(v0, k) => { v0.apply(v, *k.clone()) },
51+            Cont::C2(t1, e, k) => { t1.eval(e.to_vec(), Cont::C1(v, k.clone())) }
52+        }
53+    }
54+}
55+
56+
57+pub fn main() {
58+    use Term::*;
59+    println!("CEK:");
60+
61+    let t1: Term = Appl(Box::new((Abst(Box::new(Appl(Box::new((Var(0), Var(0)))))), (Abst(Box::new(Var(0)))))));
62+    let result = t1.eval(vec![], Cont::C0);
63+    println!("T1 eval: {:?}", result);
64+
65+    let t2: Term = Appl(Box::new((Appl(Box::new((Abst(Box::new(Var(0))), Abst(Box::new(Var(0)))))), Abst(Box::new(Var(0))))));
66+    let result2 = t2.eval(vec![], Cont::C0);                                                                     
67+    println!("T2 eval: {:?}", result2);
68+}
A src/abstract_machines/mod.rs
+1, -0
1@@ -0,0 +1 @@
2+pub mod cek;
A src/lib.rs
+1, -0
1@@ -0,0 +1 @@
2+pub mod abstract_machines;
A src/main.rs
+5, -0
1@@ -0,0 +1,5 @@
2+use machines::abstract_machines::cek;
3+
4+fn main() {
5+    cek::main();
6+}