use std::{cmp::Ordering, env, fs}; use gentoo_utils::{ Parseable, atom::{Atom, Cpv}, }; use mon::{Parser, input::InputIter, tag}; enum Operator { Comment, Yes, No, Eq, Gt, Lt, } fn parse_operator<'a>() -> impl Parser<&'a str, Output = Operator> { let comment = tag("***").map(|_| Operator::Comment); let yes = tag("+").map(|_| Operator::Yes); let no = tag("-").map(|_| Operator::No); let eq = tag("=").map(|_| Operator::Eq); let gt = tag(">").map(|_| Operator::Gt); let lt = tag("<").map(|_| Operator::Lt); comment.or(yes).or(no).or(eq).or(gt).or(lt) } fn main() { let path = env::args() .nth(1) .expect("pass path to porthole.txt as first parameter"); let porthole_txt = fs::read_to_string(&path).expect("failed to open porthole.txt"); for line in porthole_txt.lines() { if line.is_empty() { continue; } let operator = parse_operator() .parse_finished(InputIter::new( line.split_ascii_whitespace().next().unwrap(), )) .unwrap(); match &operator { Operator::Comment => continue, Operator::Yes => { let a = Atom::parser() .parse_finished(InputIter::new( line.split_ascii_whitespace().nth(1).unwrap(), )) .unwrap(); assert_eq!( line.split_ascii_whitespace().nth(1).unwrap(), &a.to_string() ); } Operator::No => { assert!( Atom::parser() .parse_finished(InputIter::new( line.split_ascii_whitespace().nth(1).unwrap() )) .is_err() ); } Operator::Eq | Operator::Gt | Operator::Lt => { let a = Cpv::parser() .parse_finished(InputIter::new( line.split_ascii_whitespace().nth(1).unwrap(), )) .unwrap(); let b = Cpv::parser() .parse_finished(InputIter::new( line.split_ascii_whitespace().nth(2).unwrap(), )) .unwrap(); assert_eq!( a.partial_cmp(&b).unwrap(), match &operator { Operator::Eq => Ordering::Equal, Operator::Gt => Ordering::Greater, Operator::Lt => Ordering::Less, _ => unreachable!(), } ); } } } }