use crate:: { // Internal code tokenise, api, //Libs HashMap, Arc, Mutex, VecDeque, warn, debug, info, mpsc::Receiver, }; use super::keyword_parse; #[allow(unused_variables)] pub fn identifier_parse ( index: usize, identifier: &String, tokens: &[tokenise::Token], variables: &mut HashMap, rx: &Receiver<(usize,String)>, happening_queue: &Arc>>, ) -> Result<(usize,bool),(String,usize)> { let mut sum_index: usize = index; let current = variables .entry(identifier.clone()) .or_insert(tokenise::Value::Null) .clone(); let operator = tokenise::get_operator_token(tokens, sum_index) .map_err(|err| (err, sum_index))?; sum_index += 1; let result: bool = match tokenise::get_value_token(tokens, sum_index) { // An value that can be directly assigned to or compared against the variable Ok(value) => { sum_index += 1; operator_match(¤t,value,operator,identifier,variables) }, // Another thing like a choice or an input Err(_) => { if operator != tokenise::Operator::Assignment // Only assignment is valid here { return Err((format!("Unexpected operator: {operator:?} at index {}",sum_index-1),sum_index + 1)) }; let keyword = tokenise::get_keyword_token(tokens,sum_index) .map_err(|err| (err,sum_index))?; match keyword.to_lowercase().as_str() { "choice" => { let choice: String; (sum_index, choice) = keyword_parse::choice_parse(tokens, index+1, happening_queue,rx,variables) .map_err(|err| (err,sum_index+1))?; variables.insert(identifier.to_owned(), tokenise::Value::String(choice)); }, "input" => { api::modify_data(happening_queue, "input".to_string(), String::new(), String::new(), Vec::new()); info!("Waiting for client input"); let input = match rx.recv() { Ok((_,input)) => input, Err(err) => { warn!("Error receiving input from client, defaulting to choice \"\" {err}"); "".to_string() } }; variables.insert(identifier.to_owned(), tokenise::Value::String(input)); sum_index += 1; }, _ => { warn!("Unexpected keyword {keyword}"); }, } false }, }; debug!("{variables:?}"); Ok((sum_index,result)) } fn operator_match ( current: &tokenise::Value, value: tokenise::Value, operator: tokenise::Operator, identifier: &String, variables: &mut HashMap ) -> bool { // Operator match box match operator { // Changing a value tokenise::Operator::Assignment => { variables.insert(identifier.to_owned(), value); } , tokenise::Operator::Add => { let result: tokenise::Value = match (value.clone(), current) { (tokenise::Value::Integer(int1),tokenise::Value::Integer(int2)) => tokenise::Value::Integer(int1 + int2), (tokenise::Value::String(str1),tokenise::Value::String(str2)) => tokenise::Value::String(format!("{str1}{str2}")), _ => value, // otherwise invalid }; variables.insert(identifier.to_owned(), result); }, tokenise::Operator::Sub => { let result: tokenise::Value = match (value.clone(), current) { (tokenise::Value::Integer(int1),tokenise::Value::Integer(int2)) => tokenise::Value::Integer(int2 - int1), _ => value, // otherwise invalid }; variables.insert(identifier.to_owned(), result); }, // Comparisons, return a boolean tokenise::Operator::Comparison(comp) => { let result = match (current, &value) { // Integer (tokenise::Value::Integer(current), tokenise::Value::Integer(comparing)) => { match comp { tokenise::Comparison::Equate => current == comparing, tokenise::Comparison::Greater => current > comparing, tokenise::Comparison::Less => current < comparing, tokenise::Comparison::GreaterOrEqual => current >= comparing, tokenise::Comparison::LessOrEqual => current <= comparing, } }, // String (tokenise::Value::String(current), tokenise::Value::String(comparing)) => { match comp { tokenise::Comparison::Equate => current == comparing, tokenise::Comparison::Greater => current > comparing, tokenise::Comparison::Less => current < comparing, tokenise::Comparison::GreaterOrEqual => current >= comparing, tokenise::Comparison::LessOrEqual => current <= comparing, } }, _ => { warn!("Invalid comparison of {current:?} and {value:?}, evaluating false"); false }, }; debug!("Comparison {current:?} comp {value:?} evaluates to {result}"); return result; } } true }