use crate::op::*; use crate::tokenizer::Token; use std::iter::Peekable; fn is_mul_text_token(text_token: &str) -> bool { if text_token.ends_with("mul") { true } else { false } } fn parse_mul<'a>(token_iter: &mut Peekable>) -> Option { // Take OpenParenthesis or return None if !token_iter.next_if_eq(&&Token::OpenParenthesis).is_some() { return None; } // Take Number or return None let lhs = if let Some(Token::Number(lhs)) = token_iter.next_if(|v| matches!(v, Token::Number(_))) { lhs.to_owned() } else { return None; }; // Take Comma or return None if !token_iter.next_if_eq(&&Token::Comma).is_some() { return None; } // Take Number or return None let rhs = if let Some(Token::Number(rhs)) = token_iter.next_if(|v: &&Token| matches!(v, Token::Number(_))) { rhs.to_owned() } else { return None; }; // Take CloseParenthesis or return None if !token_iter.next_if_eq(&&Token::CloseParenthesis).is_some() { return None; } Some(MulOp::new(lhs, rhs)) } fn is_do_text_token(text_token: &str) -> bool { if text_token.ends_with("do") { true } else { false } } fn parse_do<'a>(token_iter: &mut Peekable>) -> Option { // Take OpenParenthesis or return None if !token_iter.next_if_eq(&&Token::OpenParenthesis).is_some() { return None; } // Take CloseParenthesis or return None if !token_iter.next_if_eq(&&Token::CloseParenthesis).is_some() { return None; } Some(DoOp::new()) } fn is_dont_text_token(text_token: &str) -> bool { if text_token.ends_with("don't") { true } else { false } } fn parse_dont<'a>(token_iter: &mut Peekable>) -> Option { // Take OpenParenthesis or return None if !token_iter.next_if_eq(&&Token::OpenParenthesis).is_some() { return None; } // Take CloseParenthesis or return None if !token_iter.next_if_eq(&&Token::CloseParenthesis).is_some() { return None; } Some(DontOp::new()) } /// Parse all tokens into Ops pub fn parse_tokens(tokens: &Vec) -> Vec { let mut tokens = tokens.iter().peekable(); let mut muls: Vec = Vec::new(); while let Some(token) = tokens.next() { match token { Token::Text(t) => { if is_mul_text_token(t) { let op = parse_mul(tokens.by_ref()); if let Some(op) = op { muls.push(Ops::Mul(op)); } } else if is_do_text_token(t) { let op = parse_do(tokens.by_ref()); if let Some(op) = op { muls.push(Ops::Do(op)); } } else if is_dont_text_token(t) { let op = parse_dont(tokens.by_ref()); if let Some(op) = op { muls.push(Ops::Dont(op)); } } } _ => (), } } muls }