148fb73f7f
be always stored in lowercase
166 lines
3.7 KiB
Rust
166 lines
3.7 KiB
Rust
use crate::
|
|
{
|
|
tokenise,
|
|
api,
|
|
|
|
HashMap,
|
|
Arc,
|
|
Mutex,
|
|
VecDeque,
|
|
warn,
|
|
debug,
|
|
info,
|
|
mpsc::Receiver,
|
|
};
|
|
use super::identifier_parse;
|
|
|
|
pub fn keyword_parse(
|
|
tokens: &[tokenise::Token],
|
|
token: &str,
|
|
mut index: usize,
|
|
happening_queue: &Arc<Mutex<VecDeque<api::DataToSend>>>,
|
|
labels: &HashMap<String, usize>,
|
|
variables: &mut HashMap<String, tokenise::Value>,
|
|
rx: &Receiver<(usize,String)>,
|
|
)
|
|
-> Result<usize, String>
|
|
{
|
|
|
|
match token.to_lowercase().as_str()
|
|
{
|
|
"choice" =>
|
|
{
|
|
(index,_) = choice_parse(tokens, index, happening_queue, rx,variables)?;
|
|
},
|
|
"if" =>
|
|
{
|
|
// TODO can this go in a function?
|
|
let mut keyword = "if".to_string();
|
|
while keyword == "if" || keyword == "elif" || keyword == "else" // TODO less beefy??
|
|
{
|
|
index += 1;
|
|
let mut result: bool = true;
|
|
if keyword != "else"
|
|
{
|
|
let identifier = tokenise::get_identifier_token(tokens, index)?;
|
|
(index,result) = match identifier_parse::identifier_parse(index+1, &identifier, tokens, variables,rx,happening_queue)
|
|
{
|
|
Ok((increment, result)) => (increment,result),
|
|
Err((err,increment)) =>
|
|
{
|
|
warn!("{err}");
|
|
(increment,false)
|
|
}
|
|
}
|
|
}
|
|
if result { index += 1; break; }
|
|
index = tokenise::get_closing_index(tokens,index)?;
|
|
index += 1;
|
|
keyword = match tokenise::get_keyword_token(tokens,index)
|
|
{
|
|
Ok(keyword) => keyword,
|
|
Err(_) => break,
|
|
}
|
|
}
|
|
},
|
|
"else" =>
|
|
{
|
|
index += 1;
|
|
index = tokenise::get_closing_index(tokens, index)?;
|
|
},
|
|
"elif" =>
|
|
{
|
|
loop
|
|
{
|
|
index += 1;
|
|
let Ok(new_index) = tokenise::get_closing_index(tokens, index)
|
|
else { continue; };
|
|
index = new_index;
|
|
break
|
|
}
|
|
},
|
|
"or" =>
|
|
{
|
|
info!("OR command, jumping over");
|
|
index += 2;
|
|
let new_index = tokenise::get_closing_index(tokens, index)?;
|
|
index = new_index;
|
|
},
|
|
// Jump to a particular index based on a label eg GOTO character_check
|
|
"goto" =>
|
|
{
|
|
info!("GOTO command, jumping there");
|
|
index += 1;
|
|
let label = tokenise::get_keyword_token(tokens, index)?;
|
|
index = if let Some(label_index) = labels.get(&label) { *label_index }
|
|
else
|
|
{
|
|
warn!("Label {label} does not exist");
|
|
index + 1
|
|
};
|
|
debug!("Jumping to {index}");
|
|
},
|
|
"pan" =>
|
|
{
|
|
info!("PAN command, informing client");
|
|
index += 1;
|
|
let location = tokenise::get_keyword_token(tokens, index)?;
|
|
api::modify_data(happening_queue, "pan".to_string(), location, String::new(), Vec::new());
|
|
},
|
|
_ =>
|
|
{
|
|
warn!("Invalid command: {token}, index {index}");
|
|
index += 1;
|
|
}
|
|
}
|
|
Ok(index)
|
|
}
|
|
|
|
pub fn choice_parse
|
|
(
|
|
tokens: &[tokenise::Token],
|
|
mut index: usize,
|
|
happening_queue: &Arc<Mutex<VecDeque<api::DataToSend>>>,
|
|
rx: &Receiver<(usize,String)>,
|
|
variables: &HashMap<String,tokenise::Value>,
|
|
)
|
|
-> Result<(usize,String), String>
|
|
{
|
|
let mut next_token: String = "or".to_string();
|
|
let mut choices: Vec<String> = Vec::new();
|
|
let mut choice_indeces: Vec<usize> = Vec::new();
|
|
while next_token == "or"
|
|
{
|
|
index += 1;
|
|
choices.push
|
|
(
|
|
tokenise::get_string_token(tokens, index,variables)?
|
|
);
|
|
index += 1;
|
|
choice_indeces.push(index+1);
|
|
index = match tokenise::get_closing_index(tokens,index)
|
|
{
|
|
Ok(new_index) => new_index + 1,
|
|
Err(_) => break,
|
|
};
|
|
next_token = match tokenise::get_keyword_token(tokens, index)
|
|
{
|
|
Ok(string) => string,
|
|
Err(_) => break,
|
|
}
|
|
};
|
|
api::modify_data(happening_queue, "choice".to_string(), String::new(), String::new(), choices.clone());
|
|
info!("Waiting for client choice");
|
|
debug!("{choice_indeces:?}");
|
|
let choice = match rx.recv()
|
|
{
|
|
Ok((choice,_)) => choice,
|
|
Err(err) =>
|
|
{
|
|
warn!("Error receiving choice from client, defaulting to choice 0 {err}");
|
|
0
|
|
}
|
|
};
|
|
Ok((choice_indeces[choice],choices[choice].clone()))
|
|
}
|