added basic variable functionality, doesn't really do anything at the
moment but you can assign and change variables.
This commit is contained in:
@@ -20,6 +20,7 @@ mod character_parse;
|
||||
mod keyword_parse;
|
||||
mod identifier_parse;
|
||||
|
||||
|
||||
// Parse the tokens in a file
|
||||
// Returns success or an error string
|
||||
pub fn token_parse(
|
||||
@@ -31,6 +32,7 @@ pub fn token_parse(
|
||||
) -> Result<(),String>
|
||||
{
|
||||
let mut index: usize = 0;
|
||||
let mut variables: HashMap<String, tokenise::Value> = HashMap::new();
|
||||
info!("Client has connected");
|
||||
// Run an infinite loop
|
||||
loop
|
||||
@@ -70,7 +72,7 @@ pub fn token_parse(
|
||||
// Identifier
|
||||
Some(tokenise::Token::Identifier(name)) =>
|
||||
{
|
||||
index = match identifier_parse::identifier_parse(index+1,tokens)
|
||||
index = match identifier_parse::identifier_parse(index+1,name,tokens,&mut variables)
|
||||
{
|
||||
Ok(increment) => increment,
|
||||
Err((err,increment)) =>
|
||||
|
||||
@@ -46,7 +46,7 @@ pub fn character_parse
|
||||
info!("SAYS command with character {character_name}");
|
||||
sum_index += 1;
|
||||
let output = tokenise::get_string_token(tokens, sum_index)
|
||||
.map_err(|err| (err, index))?;
|
||||
.map_err(|err| (err, sum_index))?;
|
||||
debug!("Saying {output}");
|
||||
api::modify_data(happening_queue, "output".to_string(), output, character_name, vec![]);
|
||||
},
|
||||
@@ -56,10 +56,10 @@ pub fn character_parse
|
||||
{
|
||||
sum_index += 1;
|
||||
let feature = tokenise::get_keyword_token(tokens, sum_index)
|
||||
.map_err(|err| (err, index))?;
|
||||
.map_err(|err| (err, sum_index))?;
|
||||
sum_index += 1;
|
||||
let string = tokenise::get_string_token(tokens, sum_index)
|
||||
.map_err(|err| (err, index))?;
|
||||
.map_err(|err| (err, sum_index))?;
|
||||
info!("CHANGE command with character {character_name} feature {feature}");
|
||||
let mut characters = characters.lock().unwrap_or_exit("Character Mutex was poisoned",3);
|
||||
if let Some(character) = characters.get_mut(&character_name)
|
||||
@@ -74,7 +74,7 @@ pub fn character_parse
|
||||
{
|
||||
sum_index += 1;
|
||||
let content = tokenise::get_keyword_token(tokens, sum_index)
|
||||
.map_err(|err| (err, index))?;
|
||||
.map_err(|err| (err, sum_index))?;
|
||||
api::modify_data(happening_queue, keyword.to_lowercase(), content, character_name, vec![]);
|
||||
},
|
||||
// Catch all condition, if the instruction is unrecognised as a
|
||||
|
||||
@@ -2,12 +2,10 @@ use crate::
|
||||
{
|
||||
// Internal code
|
||||
character,
|
||||
api,
|
||||
tokenise,
|
||||
UnwrapOrExit,
|
||||
parsing,
|
||||
//Libs
|
||||
Mutex,
|
||||
Arc,
|
||||
HashMap,
|
||||
VecDeque,
|
||||
info,
|
||||
@@ -19,10 +17,55 @@ use crate::
|
||||
pub fn identifier_parse
|
||||
(
|
||||
index: usize,
|
||||
identifier: &String,
|
||||
tokens: &[tokenise::Token],
|
||||
variables: &mut HashMap<String, tokenise::Value>,
|
||||
) -> Result<usize,(String,usize)>
|
||||
{
|
||||
let mut sum_index: usize = index;
|
||||
if ! variables.contains_key(identifier)
|
||||
{
|
||||
variables.insert(identifier.to_string(), tokenise::Value::Null);
|
||||
}
|
||||
let operator = tokenise::get_operator_token(tokens, sum_index)
|
||||
.map_err(|err| (err, sum_index))?;
|
||||
sum_index += 1;
|
||||
let value = tokenise::get_value_token(tokens, sum_index)
|
||||
.map_err(|err| (err, sum_index))?;
|
||||
match operator
|
||||
{
|
||||
// Changing a value
|
||||
tokenise::Operator::Assignment =>
|
||||
{
|
||||
variables.insert(identifier.to_string(), value);
|
||||
} ,
|
||||
tokenise::Operator::Add =>
|
||||
{
|
||||
let current = variables.get(identifier).unwrap();
|
||||
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.clone(), // otherwise invalid
|
||||
|
||||
};
|
||||
variables.insert(identifier.to_string(), result);
|
||||
},
|
||||
tokenise::Operator::Sub =>
|
||||
{
|
||||
let current = variables.get(identifier).unwrap();
|
||||
let result: tokenise::Value = match (value.clone(), current)
|
||||
{
|
||||
(tokenise::Value::Integer(int1),tokenise::Value::Integer(int2)) => tokenise::Value::Integer(int2 - int1),
|
||||
_ => value.clone(), // otherwise invalid
|
||||
|
||||
};
|
||||
// TODO comparisons :DDD
|
||||
variables.insert(identifier.to_string(), result);
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
debug!("{variables:?}");
|
||||
sum_index += 1;
|
||||
Ok(sum_index)
|
||||
}
|
||||
|
||||
+37
-10
@@ -6,19 +6,21 @@ use crate::
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Token
|
||||
{
|
||||
String(String),
|
||||
#[allow(dead_code)]
|
||||
Integer(i64), // idk someone might want to do a big number
|
||||
#[allow(dead_code)]
|
||||
Bool(bool),
|
||||
|
||||
#[allow(dead_code)]
|
||||
Value(Value),
|
||||
Operator(Operator),
|
||||
Keyword(String), // Keywords aren't checked for validity in this stage
|
||||
Identifier(String),
|
||||
Bracket((Bracket,usize)), // Stores the index of the matching deliminator
|
||||
Character(String),
|
||||
}
|
||||
#[derive(Debug,Clone)]
|
||||
pub enum Value
|
||||
{
|
||||
String(String),
|
||||
Integer(i64),
|
||||
Bool(bool),
|
||||
Null,
|
||||
}
|
||||
#[derive(Debug,Clone,PartialEq,Eq)]
|
||||
pub enum Bracket
|
||||
{
|
||||
@@ -41,11 +43,27 @@ pub enum Operator
|
||||
LessOrEqual,
|
||||
}
|
||||
|
||||
pub fn get_operator_token(tokens: &[Token], index: usize)
|
||||
-> Result<Operator, String>
|
||||
{
|
||||
match tokens.get(index) {
|
||||
Some(Token::Operator(op)) => Ok(op.clone()),
|
||||
Some(_) => Err("Unexpected token".to_string()),
|
||||
None => Err("File unexpectedly reached termination point".to_string()),
|
||||
}
|
||||
}
|
||||
pub fn get_string_token(tokens: &[Token], index: usize)
|
||||
-> Result<String, String>
|
||||
{
|
||||
match tokens.get(index) {
|
||||
Some(Token::String(s)) => Ok(s.clone()),
|
||||
Some(Token::Value(val)) =>
|
||||
{
|
||||
match val
|
||||
{
|
||||
Value::String(s) => Ok(s.clone()),
|
||||
_ => Err("Unexpected value type".to_string()),
|
||||
}
|
||||
},
|
||||
Some(_) => Err("Unexpected token".to_string()),
|
||||
None => Err("File unexpectedly reached termination point".to_string()),
|
||||
}
|
||||
@@ -68,6 +86,15 @@ pub fn get_closing_index(tokens: &[Token], index: usize)
|
||||
None => Err("File unexpectedly reached termination point".to_string()),
|
||||
}
|
||||
}
|
||||
pub fn get_value_token(tokens: &[Token], index: usize)
|
||||
-> Result<Value, String>
|
||||
{
|
||||
match tokens.get(index) {
|
||||
Some(Token::Value(val)) => Ok(val.clone()),
|
||||
Some(_) => Err("Unexpected token".to_string()),
|
||||
None => Err("File unexpectedly reached termination point".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
// Tokenise the story to Vec<Token>
|
||||
// It can contain sub-objects (using recursive calls)
|
||||
@@ -122,7 +149,7 @@ pub fn tokenise(file_contents: &str)
|
||||
else { return Err("File unexpectedly ended: No closing quote".to_string()) };
|
||||
index = new_index;
|
||||
item = new_item;
|
||||
tokenised_data.push(Token::String(item));
|
||||
tokenised_data.push(Token::Value(Value::String(item)));
|
||||
}
|
||||
// variable/identifier
|
||||
else if item.starts_with("$")
|
||||
@@ -134,7 +161,7 @@ pub fn tokenise(file_contents: &str)
|
||||
// Integer
|
||||
else if item.parse::<i64>().is_ok()
|
||||
{
|
||||
tokenised_data.push(Token::Integer(item.parse::<i64>().unwrap()));
|
||||
tokenised_data.push(Token::Value(Value::Integer(item.parse::<i64>().unwrap()))); // unwrap is fine here because I checked
|
||||
}
|
||||
// Labels
|
||||
else if item.ends_with(':')
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
@tim change name "Timothy Fineshooter"
|
||||
$x = 3
|
||||
$x + 1
|
||||
$x - 2
|
||||
label:
|
||||
choice "choice numero uno" {
|
||||
@tim says "super sad"
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user