From 547fac6e57582136da0c69e845ab9a0dbbbc8a50 Mon Sep 17 00:00:00 2001 From: Wong Jia Hau Date: Fri, 14 Feb 2020 10:44:35 +0800 Subject: [PATCH 1/4] Changed List to Pair, and also re-implemented type_of --- src/node.rs | 49 ++++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/src/node.rs b/src/node.rs index 50ebb16..2d8a17f 100644 --- a/src/node.rs +++ b/src/node.rs @@ -1,37 +1,40 @@ #[derive(Clone, PartialEq, Debug)] pub enum Node { - Atom(Atom), - List(List), - Type(i64) + Atom(&'static str), + Pair(Box, Box), + Type(Type), } -pub type Atom = &'static str; - -// ===================================== -// List -// ===================================== -pub type List = Vec; +#[derive(Clone, PartialEq, Debug)] +pub enum Type { + Universe(i64), + Atom, + Pair(Box, Box) +} -pub fn cons(list: List, atom: Atom) -> Node { - let mut cloned_list = list.clone(); - cloned_list.push(Node::Atom(atom)); - Node::List(cloned_list) +pub fn cons(node: Node, atom: Node) -> Node { + Node::Pair(Box::new(node), Box::new(atom)) } -pub fn car(list: List) -> Node { - list.first().unwrap().clone() +pub fn car(node: Node) -> Result { + match node { + Node::Pair(a, _) => Result::Ok(*a), + _ => Result::Err("Can only apply car to Pair") + } } -pub fn cdr(list: List) -> Node { - let mut cloned_list = list.clone(); - cloned_list.remove(0); - Node::List(cloned_list) +pub fn cdr(node: Node) -> Result { + match node { + Node::Pair(_, b) => Result::Ok(*b), + _ => Result::Err("Cannot apply cdr to Pair") + } } -pub fn type_of(node: Node) -> Node { +pub fn type_of(node: Node) -> Type { match node { - Node::Atom(_) => Node::Type(0), - Node::List(_) => Node::Type(0), - Node::Type(n) => Node::Type(n + 1) + Node::Atom(_) => Type::Atom, + Node::Pair(a, b) => Type::Pair(Box::new(type_of(*a)), Box::new(type_of(*b))), + Node::Type(Type::Universe(n)) => Type::Universe(n + 1), + Node::Type(_) => Type::Universe(0) } } \ No newline at end of file From 8da73c29912bff877664f5e4e5e2cf27bec38436 Mon Sep 17 00:00:00 2001 From: zypeh Date: Fri, 14 Feb 2020 16:14:48 +0800 Subject: [PATCH 2/4] Renaming & test case added --- src/lib.rs | 117 ++++++++++++++++++++++++++++++++++++++-------------- src/node.rs | 46 +++++++++++---------- 2 files changed, 111 insertions(+), 52 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4c99006..8a774bc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,9 +2,8 @@ pub mod node; #[cfg(test)] mod tests { - use crate::node::*; use crate::node::Node::*; - + use crate::node::*; #[test] fn atom_cmp() { assert_eq!(Atom("ratatouille"), Atom("ratatouille")); @@ -12,58 +11,116 @@ mod tests { } #[test] - fn list_cmp() { + fn pair_cmp() { assert_eq!( - List(vec![Atom("ratatouille")]), - List(vec![Atom("ratatouille")]) + PairNode(Pair { + 0: Box::new(Atom("ratatouille")), + 1: Box::new(Atom("ratatouille")), + }), + PairNode(Pair { + 0: Box::new(Atom("ratatouille")), + 1: Box::new(Atom("ratatouille")), + }) + ); + + assert_ne!( + PairNode(Pair { + 0: Box::new(Atom("ratatouille")), + 1: Box::new(Atom("ratatouille")), + }), + PairNode(Pair { + 0: Box::new(Atom("ratatouille")), + 1: Box::new(Atom("baguette")), + }) + ); + + assert_ne!( + PairNode(Pair { + 0: Box::new(Atom("ratatouille")), + 1: Box::new(Atom("ratatouille")), + }), + PairNode(Pair { + 0: Box::new(Atom("baguette")), + 1: Box::new(Atom("ratatouille")), + }) ); assert_ne!( - List(vec![Atom("ratatouille")]), - List(vec![Atom("baguette")]) + PairNode(Pair { + 0: Box::new(Atom("ratatouille")), + 1: Box::new(Atom("baguette")), + }), + PairNode(Pair { + 0: Box::new(Atom("baguette")), + 1: Box::new(Atom("baguette")), + }) + ); + + assert_ne!( + PairNode(Pair { + 0: Box::new(Atom("baguette")), + 1: Box::new(Atom("baguette")), + }), + PairNode(Pair { + 0: Box::new(Atom("baguette")), + 1: Box::new(Atom("ratatouille")), + }) ); } #[test] - fn list_cons() { - use crate::node::cons; + fn pair_cons() { assert_eq!( - cons(vec![Atom("ratatouille")], "baguette"), - List(vec![Atom("ratatouille"), Atom("baguette")]) + Pair::cons(Atom("ratatouille"), Atom("baguette")), + Pair { + 0: Box::new(Atom("ratatouille")), + 1: Box::new(Atom("baguette")), + } ) } #[test] - fn list_car() { - use crate::node::car; + fn pair_car() { assert_eq!( - car(vec![Atom("ratatouille"), Atom("baguette")]), + Pair::car(Pair { + 0: Box::new(Atom("ratatouille")), + 1: Box::new(Atom("baguette")), + }), Atom("ratatouille") ); } #[test] - fn list_cdr() { - use crate::node::cdr; + fn pair_cdr() { assert_eq!( - cdr(vec![Atom("ratatouille"), Atom("baguette")]), - List(vec![Atom("baguette")]) + Pair::cdr(Pair { + 0: Box::new(Atom("ratatouille")), + 1: Box::new(Atom("baguette")), + }), + Atom("baguette") ); assert_eq!( - cdr(vec![ - Atom("ratatouille"), - Atom("baguette"), - Atom("aubergine") - ]), - List(vec![Atom("baguette"), Atom("aubergine")]) + Pair::cdr(Pair { + 0: Box::new(Atom("ratatouille")), + 1: Box::new(Node::PairNode(Pair { + 0: Box::new(Atom("baguette")), + 1: Box::new(Atom("aubergine")), + })) + }), + Node::PairNode(Pair { + 0: Box::new(Atom("baguette")), + 1: Box::new(Atom("aubergine")), + }) ) } - #[test] - fn type_of_term() { - assert_eq!(type_of(Atom("yo")), Type(0)); - assert_eq!(type_of(List(vec![])), Type(0)); - assert_eq!(type_of(Type(0)), Type(1)) - } + // #[test] + // fn type_of_term() { + // use crate::node::type_of; + // use crate::node::Type; + // assert_eq!(type_of(Atom("yo")), Type::Atom); + // // assert_eq!(type_of(List(vec![])), Type::Pair()); + // assert_eq!(type_of(Type)), Type::Universe(1)); + // } } diff --git a/src/node.rs b/src/node.rs index 2d8a17f..60ceb92 100644 --- a/src/node.rs +++ b/src/node.rs @@ -1,40 +1,42 @@ #[derive(Clone, PartialEq, Debug)] pub enum Node { Atom(&'static str), - Pair(Box, Box), - Type(Type), + PairNode(Pair), + TypeNode(Type), + Unit, } #[derive(Clone, PartialEq, Debug)] pub enum Type { - Universe(i64), - Atom, - Pair(Box, Box) + Universe(u32), + AtomTy, + PairTy(Pair), + Unit, } -pub fn cons(node: Node, atom: Node) -> Node { - Node::Pair(Box::new(node), Box::new(atom)) -} +#[derive(Clone, PartialEq, Debug)] +pub struct Pair(pub Box, pub Box); -pub fn car(node: Node) -> Result { - match node { - Node::Pair(a, _) => Result::Ok(*a), - _ => Result::Err("Can only apply car to Pair") +impl Pair { + pub fn cons(node1: T, node2: T) -> Pair { + Pair(Box::new(node1), Box::new(node2)) } -} -pub fn cdr(node: Node) -> Result { - match node { - Node::Pair(_, b) => Result::Ok(*b), - _ => Result::Err("Cannot apply cdr to Pair") + pub fn car(pair: Pair) -> T { + *pair.0 + } + + pub fn cdr(pair: Pair) -> T { + *pair.1 } } pub fn type_of(node: Node) -> Type { match node { - Node::Atom(_) => Type::Atom, - Node::Pair(a, b) => Type::Pair(Box::new(type_of(*a)), Box::new(type_of(*b))), - Node::Type(Type::Universe(n)) => Type::Universe(n + 1), - Node::Type(_) => Type::Universe(0) + Node::Atom(_) => Type::AtomTy, + Node::PairNode(p) => Type::PairTy(Pair(Box::new(type_of(*p.0)), Box::new(type_of(*p.1)))), + Node::TypeNode(Type::Universe(n)) => Type::Universe(n + 1), + Node::TypeNode(_) => Type::Universe(0), + Node::Unit => Type::Unit, } -} \ No newline at end of file +} From 5e3393fd88c50432a3a4a64bebca81e1b36341c9 Mon Sep 17 00:00:00 2001 From: zypeh Date: Fri, 14 Feb 2020 16:57:49 +0800 Subject: [PATCH 3/4] review: bugfixes tuple syntax and self arg --- src/lib.rs | 117 ++++++++++++++++++++++++---------------------------- src/node.rs | 10 ++--- 2 files changed, 59 insertions(+), 68 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 8a774bc..ea0d2b1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,58 +13,52 @@ mod tests { #[test] fn pair_cmp() { assert_eq!( - PairNode(Pair { - 0: Box::new(Atom("ratatouille")), - 1: Box::new(Atom("ratatouille")), - }), - PairNode(Pair { - 0: Box::new(Atom("ratatouille")), - 1: Box::new(Atom("ratatouille")), - }) + PairNode(Pair( + Box::new(Atom("ratatouille")), + Box::new(Atom("ratatouille")), + )), + PairNode(Pair( + Box::new(Atom("ratatouille")), + Box::new(Atom("ratatouille")), + )) ); assert_ne!( - PairNode(Pair { - 0: Box::new(Atom("ratatouille")), - 1: Box::new(Atom("ratatouille")), - }), - PairNode(Pair { - 0: Box::new(Atom("ratatouille")), - 1: Box::new(Atom("baguette")), - }) + PairNode(Pair( + Box::new(Atom("ratatouille")), + Box::new(Atom("ratatouille")) + )), + PairNode(Pair( + Box::new(Atom("ratatouille")), + Box::new(Atom("baguette")), + )) ); assert_ne!( - PairNode(Pair { - 0: Box::new(Atom("ratatouille")), - 1: Box::new(Atom("ratatouille")), - }), - PairNode(Pair { - 0: Box::new(Atom("baguette")), - 1: Box::new(Atom("ratatouille")), - }) + PairNode(Pair( + Box::new(Atom("ratatouille")), + Box::new(Atom("ratatouille")), + )), + PairNode(Pair( + Box::new(Atom("baguette")), + Box::new(Atom("ratatouille")), + )) ); assert_ne!( - PairNode(Pair { - 0: Box::new(Atom("ratatouille")), - 1: Box::new(Atom("baguette")), - }), - PairNode(Pair { - 0: Box::new(Atom("baguette")), - 1: Box::new(Atom("baguette")), - }) + PairNode(Pair( + Box::new(Atom("ratatouille")), + Box::new(Atom("baguette")), + )), + PairNode(Pair(Box::new(Atom("baguette")), Box::new(Atom("baguette")),)) ); assert_ne!( - PairNode(Pair { - 0: Box::new(Atom("baguette")), - 1: Box::new(Atom("baguette")), - }), - PairNode(Pair { - 0: Box::new(Atom("baguette")), - 1: Box::new(Atom("ratatouille")), - }) + PairNode(Pair(Box::new(Atom("baguette")), Box::new(Atom("baguette")),)), + PairNode(Pair( + Box::new(Atom("baguette")), + Box::new(Atom("ratatouille")), + )) ); } @@ -72,20 +66,17 @@ mod tests { fn pair_cons() { assert_eq!( Pair::cons(Atom("ratatouille"), Atom("baguette")), - Pair { - 0: Box::new(Atom("ratatouille")), - 1: Box::new(Atom("baguette")), - } + Pair(Box::new(Atom("ratatouille")), Box::new(Atom("baguette")),) ) } #[test] fn pair_car() { assert_eq!( - Pair::car(Pair { - 0: Box::new(Atom("ratatouille")), - 1: Box::new(Atom("baguette")), - }), + Pair::car(Pair( + Box::new(Atom("ratatouille")), + Box::new(Atom("baguette")) + )), Atom("ratatouille") ); } @@ -93,25 +84,25 @@ mod tests { #[test] fn pair_cdr() { assert_eq!( - Pair::cdr(Pair { - 0: Box::new(Atom("ratatouille")), - 1: Box::new(Atom("baguette")), - }), + Pair::cdr(Pair( + Box::new(Atom("ratatouille")), + Box::new(Atom("baguette")), + )), Atom("baguette") ); assert_eq!( - Pair::cdr(Pair { - 0: Box::new(Atom("ratatouille")), - 1: Box::new(Node::PairNode(Pair { - 0: Box::new(Atom("baguette")), - 1: Box::new(Atom("aubergine")), - })) - }), - Node::PairNode(Pair { - 0: Box::new(Atom("baguette")), - 1: Box::new(Atom("aubergine")), - }) + Pair::cdr(Pair( + Box::new(Atom("ratatouille")), + Box::new(Node::PairNode(Pair( + Box::new(Atom("baguette")), + Box::new(Atom("aubergine")), + ))), + )), + Node::PairNode(Pair( + Box::new(Atom("baguette")), + Box::new(Atom("aubergine")), + )) ) } diff --git a/src/node.rs b/src/node.rs index 60ceb92..b57b243 100644 --- a/src/node.rs +++ b/src/node.rs @@ -8,7 +8,7 @@ pub enum Node { #[derive(Clone, PartialEq, Debug)] pub enum Type { - Universe(u32), + Universe(i64), AtomTy, PairTy(Pair), Unit, @@ -22,12 +22,12 @@ impl Pair { Pair(Box::new(node1), Box::new(node2)) } - pub fn car(pair: Pair) -> T { - *pair.0 + pub fn car(self) -> T { + *self.0 } - pub fn cdr(pair: Pair) -> T { - *pair.1 + pub fn cdr(self) -> T { + *self.1 } } From 0d4e29b029c9673dd13f65ccb49040646c55a23d Mon Sep 17 00:00:00 2001 From: Wong Jia Hau Date: Fri, 14 Feb 2020 22:58:43 +0800 Subject: [PATCH 4/4] Rename T-Ty to T --- src/lib.rs | 14 ++++++-------- src/node.rs | 8 ++++---- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ea0d2b1..daaf2ee 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -106,12 +106,10 @@ mod tests { ) } - // #[test] - // fn type_of_term() { - // use crate::node::type_of; - // use crate::node::Type; - // assert_eq!(type_of(Atom("yo")), Type::Atom); - // // assert_eq!(type_of(List(vec![])), Type::Pair()); - // assert_eq!(type_of(Type)), Type::Universe(1)); - // } + #[test] + fn type_of_term() { + use crate::node::type_of; + use crate::node::Type; + assert_eq!(type_of(Atom("yo")), Type::Atom); + } } diff --git a/src/node.rs b/src/node.rs index b57b243..ad03c76 100644 --- a/src/node.rs +++ b/src/node.rs @@ -9,8 +9,8 @@ pub enum Node { #[derive(Clone, PartialEq, Debug)] pub enum Type { Universe(i64), - AtomTy, - PairTy(Pair), + Atom, + Pair(Pair), Unit, } @@ -33,8 +33,8 @@ impl Pair { pub fn type_of(node: Node) -> Type { match node { - Node::Atom(_) => Type::AtomTy, - Node::PairNode(p) => Type::PairTy(Pair(Box::new(type_of(*p.0)), Box::new(type_of(*p.1)))), + Node::Atom(_) => Type::Atom, + Node::PairNode(p) => Type::Pair(Pair(Box::new(type_of(*p.0)), Box::new(type_of(*p.1)))), Node::TypeNode(Type::Universe(n)) => Type::Universe(n + 1), Node::TypeNode(_) => Type::Universe(0), Node::Unit => Type::Unit,