started working on new tokeniser

This commit is contained in:
2026-05-16 21:11:45 +01:00
parent 94422b307c
commit 0c28bc113d
6 changed files with 125 additions and 30 deletions
+1 -1
View File
@@ -199,4 +199,4 @@ GOTO label
| 12 | Failed to open archive | Make sure the story file is a zip archive. |
| 13 | Unable to setup the characters hashmap. | Make sure the characters.json file exists, is valid JSON and contains valid characters. |
| 14 | Unable to read the main story file. | Make sure the story.ha file exists and is readable. |
| 15 | | |
| 15 | | |
+17 -6
View File
@@ -33,7 +33,7 @@ pub async fn api_process
(
data_to_send: Arc<Mutex<DataToSend>>,
characters: Arc<Mutex<HashMap::<String,character::Character>>>,
tx: Sender<(bool, usize)>,
tx: Sender<(bool, usize, String)>,
)
{
// This data must be passed through to the api route in order to be used
@@ -41,6 +41,7 @@ pub async fn api_process
let characters_filter = warp::any().map(move || Arc::clone(&characters));
let tx_filter = warp::any().map(move || tx.clone());
let tx_filter2 = tx_filter.clone();
let tx_filter3 = tx_filter.clone();
info!("Running server");
@@ -50,11 +51,11 @@ pub async fn api_process
.and(data_filter)
.and(tx_filter)
// Perform this code on a GET request
.map(|state: Arc<Mutex<DataToSend>>, tx_handle: Sender<(bool,usize)>|
.map(|state: Arc<Mutex<DataToSend>>, tx_handle: Sender<(bool,usize,String)>|
{
debug!("GET: {state:?}");
let reply = state.as_ref();
let _ = tx_handle.send((true,0));
let _ = tx_handle.send((true,0,String::new()));
warp::reply::json(&reply) // Send the reply data (data_to_send formatted as JSON)
}).boxed();
let characters = warp::path("character")
@@ -89,14 +90,24 @@ pub async fn api_process
.and(warp::post())
.and(warp::body::json())
.and(tx_filter2)
.map(|index: usize, tx_handle: Sender<(bool,usize)>| {
.map(|index: usize, tx_handle: Sender<(bool,usize,String)>| {
debug!("Choice: {index}");
let _ = tx_handle.send((true,index));
let _ = tx_handle.send((true,index,String::new()));
let reply = "ack";
warp::reply::json(&reply)
}).boxed();
let input = warp::path("input")
.and(warp::post())
.and(warp::body::json())
.and(tx_filter3)
.map(|input: String, tx_handle: Sender<(bool, usize, String)>|
{
let _ = tx_handle.send((true,0,input));
let reply = "ack";
warp::reply::json(&reply)
}).boxed();
let routes = main.or(characters).or(choice);
let routes = main.or(characters).or(choice).or(input);
// Start the server
warp::serve(routes)
.run(([127, 0, 0, 1],config::API_PORT))
+18 -17
View File
@@ -39,25 +39,26 @@ pub struct Clothing
shoes: String,
}
impl Character {
// Big ass ugly function because rust doesn't support referencing struct entries by string
pub fn set_field(&mut self, field: &str, value: &str) -> Result<(), ()> {
match field {
"name" => self.name = value.to_string(),
"gender" => self.gender = value.to_string(),
"eye_color" => self.eye_color = value.to_string(),
"pronoun_subject" => self.pronoun_subject = value.to_string(),
"pronoun_object" => self.pronoun_object = value.to_string(),
"pronoun_deppos" => self.pronoun_deppos = value.to_string(),
"pronoun_indpos" => self.pronoun_indpos = value.to_string(),
"pronoun_reflex" => self.pronoun_reflex = value.to_string(),
"head_shape" => self.head_shape = value.to_string(),
"hair_style" => self.hair_style = value.to_string(),
"torso_shape" => self.torso_shape = value.to_string(),
"arm_shape" => self.arm_shape = value.to_string(),
"leg_shape" => self.leg_shape = value.to_string(),
"hair_color" => self.hair_color = value.to_string(),
"clothing.top" => self.clothing.top = value.to_string(),
"clothing.bottom" => self.clothing.bottom = value.to_string(),
"clothing.shoes" => self.clothing.shoes = value.to_string(),
"name" => self.name = value.to_string(),
"gender" => self.gender = value.to_string(),
"eye_color" => self.eye_color = value.to_string(),
"pronoun_subject" => self.pronoun_subject = value.to_string(),
"pronoun_object" => self.pronoun_object = value.to_string(),
"pronoun_deppos" => self.pronoun_deppos = value.to_string(),
"pronoun_indpos" => self.pronoun_indpos = value.to_string(),
"pronoun_reflex" => self.pronoun_reflex = value.to_string(),
"head_shape" => self.head_shape = value.to_string(),
"hair_style" => self.hair_style = value.to_string(),
"torso_shape" => self.torso_shape = value.to_string(),
"arm_shape" => self.arm_shape = value.to_string(),
"leg_shape" => self.leg_shape = value.to_string(),
"hair_color" => self.hair_color = value.to_string(),
"clothing.top" => self.clothing.top = value.to_string(),
"clothing.bottom" => self.clothing.bottom = value.to_string(),
"clothing.shoes" => self.clothing.shoes = value.to_string(),
_ => return Err(()),
}
+9 -2
View File
@@ -3,6 +3,7 @@ mod character;
mod config;
mod api;
mod traits;
mod tokenise;
use std::
{
@@ -96,7 +97,6 @@ async fn main()
api::api_process(data_clone1, characters_clone1, tx_clone).await;
});
// setup the parsing stuff //
// Read the file and split it into tokens
// file read from a zip file /story.ha
@@ -114,6 +114,7 @@ async fn main()
exit(14);
});
// Tokenise story file
/*
let tokens: Vec<&str> = file_contents
.split_whitespace()
.collect();
@@ -121,8 +122,13 @@ async fn main()
{
warn!("No END statement, story may exit unexpectedly");
}
*/
let space_seperated: Vec<&str> = file_contents
.split_whitespace()
.collect();
let (tokens, labels,_) = tokenise::tokenise(&space_seperated, 0).unwrap();
debug!("{tokens:?}");
/*
let data_clone2 = Arc::clone(&data_to_send);
let characters_clone2 = Arc::clone(&characters);
// Run the parsing process for the DSL
@@ -142,4 +148,5 @@ async fn main()
exit(1);
},
}
*/
}
+4 -4
View File
@@ -23,7 +23,7 @@ pub fn token_parse(
tokens: &Vec<&str>,
characters: &Arc<Mutex<HashMap::<String, character::Character>>>,
data_to_send: &Arc<Mutex<api::DataToSend>>,
rx: &Receiver<(bool,usize)>,
rx: &Receiver<(bool,usize,String)>,
) -> Result<(),String>
{
info!("DSL parsing begun");
@@ -76,13 +76,13 @@ pub fn token_parse(
Err(error) => return Err(error),
};
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),
Ok((_,choice,_)) => (None::<bool>, choice, None::<String>),
Err(err) =>
{
warn!("Error receiving choice from client, defaulting to choice 0 {err}");
(None::<bool>, 0)
(None::<bool>, 0, None::<String>)
}
};
index = jump_points[choice];
+76
View File
@@ -0,0 +1,76 @@
use crate::
{
debug,
exit,
};
#[derive(Debug)]
pub enum Token
{
Null,
String(String),
Object(Vec<Token>),
}
pub fn tokenise(space_seperated: &Vec<&str>, mut index: usize)
-> Result<(Vec<Token>,Vec<(String,usize)>,usize),String>
{
let mut tokenised_data: Vec<Token> = Vec::new();
let mut labels: Vec<(String,usize)> = Vec::new();
while index < space_seperated.len()
{
let mut item = space_seperated[index].to_string();
let mut object: Vec<Token> = Vec::new();
debug!("{item}");
if item.starts_with("\"")
{
(index, item) = match tokenise_string(&space_seperated, index)
{
Some((index,item)) => (index, item),
None => exit(1),
};
tokenised_data.push(Token::String(item));
}
else if item == "{"
{
(object, labels, index) = match tokenise(&space_seperated, index+1) // !WARNING! recursive call
{
Ok((object,labels,index)) => (object,labels,index),
Err(err) => return Err(err),
};
tokenised_data.push(Token::Object(object));
}
else if item == "}"
{
return Ok((tokenised_data,labels,index));
}
else { tokenised_data.push(Token::String(item)); }
index += 1;
}
return Ok((tokenised_data, labels, 0));
}
fn tokenise_string(space_seperated: &Vec<&str>, mut index: usize)
-> Option<(usize, String)>
{
let mut string = String::new();
let mut chars = space_seperated[index].chars();
chars.next();
string += chars.as_str();
for item in &space_seperated[index+1..]
{
if item.ends_with("\"")
{
let mut chars = item.chars();
chars.next_back();
string += format!(" {}", chars.as_str()).as_str();
break
}
else
{
string += format!(" {}", item).as_str();
}
index += 1;
}
return Some((index+1,string))
}