diff --git a/implementations/Rust/.gitignore b/implementations/Rust/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/implementations/Rust/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/implementations/Rust/Cargo.lock b/implementations/Rust/Cargo.lock deleted file mode 100644 index c9cd6a3..0000000 --- a/implementations/Rust/Cargo.lock +++ /dev/null @@ -1,49 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aho-corasick" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" -dependencies = [ - "memchr", -] - -[[package]] -name = "crust" -version = "0.1.0" -dependencies = [ - "lazy_static", - "regex", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "memchr" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" - -[[package]] -name = "regex" -version = "1.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" diff --git a/implementations/Rust/Cargo.toml b/implementations/Rust/Cargo.toml deleted file mode 100644 index 8dad137..0000000 --- a/implementations/Rust/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "crust" -version = "0.1.0" -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -regex = "1" -lazy_static = "1" - diff --git a/implementations/Rust/src/main.rs b/implementations/Rust/src/main.rs deleted file mode 100644 index 968165f..0000000 --- a/implementations/Rust/src/main.rs +++ /dev/null @@ -1,86 +0,0 @@ -mod stack; -use lazy_static::lazy_static; -use regex::Regex; -use std::io; - -#[derive(Debug)] -enum JoyVal { - True, - False, - List(stack::List), - Int(i64), - Sym(String), -} - -fn tokenize(str: &str) -> JoyVal { - lazy_static! { - static ref RE: Regex = Regex::new( - r"(?x) - (?Ptrue)\b - | (?Pfalse)\b - | (?P\[) - | (?P\]) - | (?P\d+) - | (?P[^\s+\[\]]+) " - ) - .unwrap(); - } - - let mut frame = vec![]; - let mut stack = vec![]; - for cap in RE.captures_iter(str) { - // Is this better than the if/elif/else chain below? - // More importantly, how would I go about figuring that out? - match cap.name("true") { - Some(_) => { - frame.push(JoyVal::True); - continue; - } - None => {} - } - // Is there a better way to do this? - //if cap.name("true") != None { - // println!("T"); - //} else - if cap.name("false") != None { - frame.push(JoyVal::False); - } else if cap.name("lbracket") != None { - stack.push(frame); - frame = vec![]; - } else if cap.name("rbracket") != None { - let v = frame; - frame = stack.pop().expect("Extra closing bracket."); - frame.push(JoyVal::List(stack::List::vec_to_list(v))); - } else if cap.name("int") != None { - frame.push(JoyVal::Int(cap[0].parse().unwrap())); - } else if cap.name("atom") != None { - frame.push(JoyVal::Sym(String::from(&cap[0]))); - } else { - println!("wtf"); - } - } - JoyVal::List(stack::List::vec_to_list(frame)) -} - -fn joy(mut s: stack::List, mut e: stack::List) -> stack::List { - while !e.empty() { - let term = e.head().expect("How!?"); - e = e.tail(); - match term { - JoyVal::True => { s = s.push(JoyVal::True) } - JoyVal::False => { s = s.push(JoyVal::False) } - JoyVal::List(_) => { s = s.push(term) } - JoyVal::Int(_) => { s = s.push(term) } - JoyVal::Sym(_) => { s = s.push(term) } - } - } - s -} - -fn main() { - println!("Enter a number:"); - let mut n = String::new(); - let m = io::stdin().read_line(&mut n).expect("WTF?"); - println!("{:?}", tokenize(&n)); - println!("Entered: {} {}", m, n); -} diff --git a/implementations/Rust/src/stack.rs b/implementations/Rust/src/stack.rs deleted file mode 100644 index 75fd9ef..0000000 --- a/implementations/Rust/src/stack.rs +++ /dev/null @@ -1,133 +0,0 @@ -// https://rust-unofficial.github.io/too-many-lists/third.html -use std::rc::Rc; - -#[derive(Debug)] -pub struct List { - head: Link, -} - -type Link = Option>>; - -#[derive(Debug)] -struct Node { - elem: T, - next: Link, -} - -impl List { - pub fn new() -> Self { - List { head: None } - } - pub fn push(&self, elem: T) -> List { - List { - head: Some(Rc::new(Node { - elem: elem, - next: self.head.clone(), - })), - } - } - pub fn tail(&self) -> List { - List { - head: self.head.as_ref().and_then(|node| node.next.clone()), - } - } - pub fn head(&self) -> Option<&T> { - self.head.as_ref().map(|node| &node.elem) - } - pub fn iter(&self) -> Iter<'_, T> { - Iter { - next: self.head.as_deref(), - } - } - pub fn vec_to_list(v: Vec) -> List { - let mut list = List::new(); - for t in v.into_iter().rev() { - list = list.push(t); - } - list - } - pub fn empty(&self) -> bool { - match self.head { - Some(_) => false, - None => true - } - } -} - -impl Drop for List { - fn drop(&mut self) { - let mut head = self.head.take(); - while let Some(node) = head { - if let Ok(mut node) = Rc::try_unwrap(node) { - head = node.next.take(); - } else { - break; - } - } - } -} - -pub struct Iter<'a, T> { - next: Option<&'a Node>, -} - -impl<'a, T> Iterator for Iter<'a, T> { - type Item = &'a T; - - fn next(&mut self) -> Option { - self.next.map(|node| { - self.next = node.next.as_deref(); - &node.elem - }) - } -} - -#[cfg(test)] -mod test { - use super::List; - - #[test] - fn basics() { - let list = List::new(); - assert_eq!(list.head(), None); - assert_eq!(list.empty(), true); - - let list = list.push(1).push(2).push(3); - assert_eq!(list.empty(), false); - assert_eq!(list.head(), Some(&3)); - - let list = list.tail(); - assert_eq!(list.head(), Some(&2)); - - let list = list.tail(); - assert_eq!(list.head(), Some(&1)); - - let list = list.tail(); - assert_eq!(list.head(), None); - - // Make sure empty tail works - let list = list.tail(); - assert_eq!(list.head(), None); - } - - #[test] - fn iter() { - let list = List::new().push(1).push(2).push(3); - - let mut iter = list.iter(); - assert_eq!(iter.next(), Some(&3)); - assert_eq!(iter.next(), Some(&2)); - assert_eq!(iter.next(), Some(&1)); - } - - #[test] - fn v2l() { - let v = vec![1, 2, 3]; - let list = List::vec_to_list(v); - - let mut iter = list.iter(); - assert_eq!(iter.next(), Some(&1)); - assert_eq!(iter.next(), Some(&2)); - assert_eq!(iter.next(), Some(&3)); - } -}