gdritter repos rust-examples / b1032f5
Updated lcalc to use Cargo Getty Ritter 10 years ago
6 changed file(s) with 85 addition(s) and 84 deletion(s). Collapse all Expand all
1 [package]
2
3 name = "lcalc"
4 version = "0.0.2"
5 authors = [ "gdritter@galois.com" ]
+0
-1
lcalc/clean.do less more
1 if [ -e lcalc ]; then rm lcalc; fi
+0
-1
lcalc/default.do less more
1 redo-ifchange lcalc
+0
-2
lcalc/lcalc.do less more
1 redo-ifchange lcalc.rs
2 rustc lcalc.rs -o $3
+0
-80
lcalc/lcalc.rs less more
1 #[deriving(Eq,PartialEq,Clone,Show)]
2 enum Term {
3 Num(int),
4 Var(String),
5 Lam(String, Box<Term>),
6 App(Box<Term>, Box<Term>),
7 Let(String, Box<Term>, Box<Term>),
8 }
9
10 #[deriving(Eq,PartialEq,Clone,Show)]
11 enum Val {
12 VNum(int),
13 VLam(String, Box<Term>, Box<Env>),
14 }
15
16 #[deriving(Eq,PartialEq,Clone,Show)]
17 enum Env {
18 Empty,
19 Binding(String, Box<Val>, Box<Env>),
20 }
21
22 fn lookup(s: &String, e: &Env) -> Box<Val> {
23 match *e {
24 Empty => { fail!(format!("Couldn't find {} in environment", s)) }
25 Binding(ref n, ref v, ref p) => {
26 if n == s {
27 v.clone()
28 } else {
29 lookup(s, &**p)
30 }
31 }
32 }
33 }
34
35 fn lcalc_eval(t: &Term, e: &Env) -> Box<Val> {
36 match t {
37 &Num(num) => { box VNum(num) }
38 &Var(ref str) => { lookup(str, e) }
39 &Lam(ref s, ref b) => { box VLam(s.clone(), b.clone(), box e.clone()) }
40 &App(box ref f, box ref x) => {
41 match *lcalc_eval(f, e) {
42 VLam(ref arg, box ref body, box ref env) => {
43 let newEnv = Binding(arg.clone(),
44 lcalc_eval(x, e),
45 box env.clone());
46 lcalc_eval(body, &newEnv)
47 }
48 _ => fail!()
49 }
50 }
51 &Let(ref s, box ref t, box ref b) => {
52 let newEnv = Binding(s.clone(),
53 lcalc_eval(t, e),
54 box e.clone());
55 lcalc_eval(b, &newEnv)
56 }
57 }
58 }
59
60 fn main() {
61 // (λx.λy.x)(5)(6)
62 let s1 = box App(box App(box Lam("x".to_string(),
63 box Lam("y".to_string(),
64 box Var("x".to_string()))),
65 box Num(5)),
66 box Num(8));
67 // let f = (λx.λy.x)(2) in f 4
68 let s2 = box
69 Let("f".to_string(),
70 box App(box Lam("x".to_string(),
71 box Lam("y".to_string(),
72 box Var("x".to_string()))),
73 box Num(2)),
74 box App(box Var("f".to_string()),
75 box Num(4))
76 );
77 let e = Empty;
78 println!("s1: {:}", lcalc_eval(&*s1, &e));
79 println!("s2: {:}", lcalc_eval(&*s2, &e));
80 }
1 #[deriving(Eq,PartialEq,Clone,Show)]
2 enum Term {
3 Num(int),
4 Var(String),
5 Lam(String, Box<Term>),
6 App(Box<Term>, Box<Term>),
7 Let(String, Box<Term>, Box<Term>),
8 }
9
10 #[deriving(Eq,PartialEq,Clone,Show)]
11 enum Val {
12 VNum(int),
13 VLam(String, Box<Term>, Box<Env>),
14 }
15
16 #[deriving(Eq,PartialEq,Clone,Show)]
17 enum Env {
18 Empty,
19 Binding(String, Box<Val>, Box<Env>),
20 }
21
22 fn lookup(s: &String, e: &Env) -> Box<Val> {
23 match *e {
24 Empty => { fail!(format!("Couldn't find {} in environment", s)) }
25 Binding(ref n, ref v, ref p) => {
26 if n == s {
27 v.clone()
28 } else {
29 lookup(s, &**p)
30 }
31 }
32 }
33 }
34
35 fn lcalc_eval(t: &Term, e: &Env) -> Box<Val> {
36 match t {
37 &Num(num) => { box VNum(num) }
38 &Var(ref str) => { lookup(str, e) }
39 &Lam(ref s, ref b) => { box VLam(s.clone(), b.clone(), box e.clone()) }
40 &App(box ref f, box ref x) => {
41 match *lcalc_eval(f, e) {
42 VLam(ref arg, box ref body, box ref env) => {
43 let newEnv = Binding(arg.clone(),
44 lcalc_eval(x, e),
45 box env.clone());
46 lcalc_eval(body, &newEnv)
47 }
48 _ => fail!()
49 }
50 }
51 &Let(ref s, box ref t, box ref b) => {
52 let newEnv = Binding(s.clone(),
53 lcalc_eval(t, e),
54 box e.clone());
55 lcalc_eval(b, &newEnv)
56 }
57 }
58 }
59
60 fn main() {
61 // (λx.λy.x)(5)(6)
62 let s1 = box App(box App(box Lam("x".to_string(),
63 box Lam("y".to_string(),
64 box Var("x".to_string()))),
65 box Num(5)),
66 box Num(8));
67 // let f = (λx.λy.x)(2) in f 4
68 let s2 = box
69 Let("f".to_string(),
70 box App(box Lam("x".to_string(),
71 box Lam("y".to_string(),
72 box Var("x".to_string()))),
73 box Num(2)),
74 box App(box Var("f".to_string()),
75 box Num(4))
76 );
77 let e = Empty;
78 println!("s1: {:}", lcalc_eval(&*s1, &e));
79 println!("s2: {:}", lcalc_eval(&*s2, &e));
80 }