Updated lcalc to use Cargo
Getty Ritter
11 years ago
| 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 | } |