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