Changed how the data is tokenised

This commit is contained in:
2026-05-17 12:47:22 +01:00
parent 0c28bc113d
commit 13049309b2
10 changed files with 303 additions and 164 deletions
+33 -65
View File
@@ -4,6 +4,7 @@ use crate::
// Internal code
character,
api,
tokenise,
// Libraries
mpsc::Receiver,
@@ -14,13 +15,12 @@ use crate::
warn,
};
mod strings;
mod character_parse;
// Parse the tokens in a file
// Returns success or an error string
pub fn token_parse(
tokens: &Vec<&str>,
tokens: &Vec<tokenise::Token>,
characters: &Arc<Mutex<HashMap::<String, character::Character>>>,
data_to_send: &Arc<Mutex<api::DataToSend>>,
rx: &Receiver<(bool,usize,String)>,
@@ -31,16 +31,14 @@ pub fn token_parse(
if rx.recv().is_err()
{
warn!("Some issue with api");
// TOD eh?
// TODO eh?
}
info!("Client has connected");
// Run an infinite loop
'parse_loop: loop
{
// Get the next token
let token = tokens
.get(index)
.ok_or_else(|| "File unexpectedly reached termination point".to_string())?;
let token = tokenise::get_string_token(tokens, index)?;
debug!("{index}: {token}");
// The instructions are related to characters
if token.starts_with('@')
@@ -70,39 +68,48 @@ pub fn token_parse(
},
"choice" =>
{
let (_,jump_points) = match choice_parse(index+1, tokens, data_to_send)
debug!("Doing CHOICE");
let mut next_token = token;
let mut choices: Vec<String> = Vec::new();
let mut choice_indeces: Vec<usize> = Vec::new();
while next_token == "or" || next_token == "choice"
{
Ok((increment,jump_point)) => (increment,jump_point),
Err(error) => return Err(error),
};
index += 1;
choices.push
(
tokenise::get_string_token(tokens, index)?
);
choice_indeces.push(index+1);
index += 2;
next_token = match tokenise::get_string_token(tokens, index)
{
Ok(string) => string,
Err(_) => break,
}
}
debug!("{choices:?}");
debug!("{choice_indeces:?}");
api::modify_data(data_to_send, "choice".to_string(), String::new(), String::new(), choices);
if rx.recv().is_err() { warn!("Error sending choices to client"); }
let (_, choice, _) = match rx.recv()
let choice = match rx.recv()
{
Ok((_,choice,_)) => (None::<bool>, choice, None::<String>),
Ok((_,choice,_)) => choice_indeces[choice],
Err(err) =>
{
warn!("Error receiving choice from client, defaulting to choice 0 {err}");
(None::<bool>, 0, None::<String>)
0
}
};
index = jump_points[choice];
info!("CHOICE command with {} choices",jump_points.len());
debug!("{jump_points:?} {choice} {index}");
let object = tokenise::get_object_token(tokens, choice)?; // TODO make more efficient
debug!("{object:?}");
// Don't propogate exit error
let _ = token_parse(object, characters, data_to_send, rx);
continue 'parse_loop
},
"or" =>
{
info!("OR command, jumping over");
index += match strings::closing_char(&tokens[index..], '{','}')
{
Some(index) => index,
None => return Err(String::from("No closing brace")),
};
continue
},
"}" =>
{
index += 1;
index += 2;
continue
},
_ =>
@@ -117,42 +124,3 @@ pub fn token_parse(
}
}
}
// Parse the options in a choice clause and returns the idexes of the code blocks
fn choice_parse
(
index: usize,
tokens: &[&str],
data_to_send: &Arc<Mutex<api::DataToSend>>,
) -> Result<(usize, Vec<usize>), String>
{
let mut sum_index: usize = index;
let mut choices: Vec<String> = Vec::new();
let mut choice_indeces: Vec<usize> = Vec::new();
// Ensure the index is valid (the index is not beyond the vector)
// Get the initial choice
let (choice_string, counter) = strings::extract_quoted(&tokens[sum_index..])
.ok_or_else(|| "No choice string".to_string())?;
sum_index += counter;
choices.push(choice_string);
choice_indeces.push(sum_index+1);
sum_index += strings::closing_char(&tokens[sum_index..], '{','}')
.ok_or_else(|| "No closing brace".to_string())? + 1;
// Find all the alternate choices labelled with OR
// Fill out the choices vector with all the choice strings
while tokens[sum_index].to_lowercase() == "or"
{
let (choice_string, counter) = strings::extract_quoted(&tokens[sum_index+1..])
.ok_or_else(|| "No choice string".to_string())?;
sum_index += counter;
choices.push(choice_string);
choice_indeces.push(sum_index+2);
sum_index += strings::closing_char(&tokens[sum_index..], '{','}')
.ok_or_else(|| "No closing brace".to_string())? + 1;
}
debug!("{choices:?}");
// Send the choices to the Client via the API
api::modify_data(data_to_send, "choice".to_string(), String::new(), String::new(), choices);
// Return the choice indeces
Ok((sum_index + 1, choice_indeces))
}