+++ /dev/null
-# 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"
+++ /dev/null
-mod stack;
-use lazy_static::lazy_static;
-use regex::Regex;
-use std::io;
-
-#[derive(Debug)]
-enum JoyVal {
- True,
- False,
- List(stack::List<JoyVal>),
- Int(i64),
- Sym(String),
-}
-
-fn tokenize(str: &str) -> JoyVal {
- lazy_static! {
- static ref RE: Regex = Regex::new(
- r"(?x)
- (?P<true>true)\b
- | (?P<false>false)\b
- | (?P<lbracket>\[)
- | (?P<rbracket>\])
- | (?P<int>\d+)
- | (?P<atom>[^\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<JoyVal>, mut e: stack::List<JoyVal>) -> stack::List<JoyVal> {
- 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);
-}
+++ /dev/null
-// https://rust-unofficial.github.io/too-many-lists/third.html
-use std::rc::Rc;
-
-#[derive(Debug)]
-pub struct List<T> {
- head: Link<T>,
-}
-
-type Link<T> = Option<Rc<Node<T>>>;
-
-#[derive(Debug)]
-struct Node<T> {
- elem: T,
- next: Link<T>,
-}
-
-impl<T> List<T> {
- pub fn new() -> Self {
- List { head: None }
- }
- pub fn push(&self, elem: T) -> List<T> {
- List {
- head: Some(Rc::new(Node {
- elem: elem,
- next: self.head.clone(),
- })),
- }
- }
- pub fn tail(&self) -> List<T> {
- 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<T>) -> List<T> {
- 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<T> Drop for List<T> {
- 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<T>>,
-}
-
-impl<'a, T> Iterator for Iter<'a, T> {
- type Item = &'a T;
-
- fn next(&mut self) -> Option<Self::Item> {
- 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));
- }
-}