Working on implementing functions

This commit is contained in:
Sebastian Schmidt 2019-03-15 20:26:25 +02:00
parent 3351d19db3
commit b3a616c39a
4 changed files with 54 additions and 13 deletions

View File

@ -1,8 +1,11 @@
use crate::{error::Error, value::Value}; use crate::{error::Error, value::Value};
use std::collections::HashMap; use std::collections::HashMap;
use function::Function;
pub trait Configuration { pub trait Configuration {
fn get_value(&self, identifier: &str) -> Option<&Value>; fn get_value(&self, identifier: &str) -> Option<&Value>;
fn get_function(&self, identifier: &str) -> Option<&Function>;
} }
pub struct EmptyConfiguration; pub struct EmptyConfiguration;
@ -11,12 +14,40 @@ impl Configuration for EmptyConfiguration {
fn get_value(&self, identifier: &str) -> Option<&Value> { fn get_value(&self, identifier: &str) -> Option<&Value> {
None None
} }
fn get_function(&self, identifier: &str) -> Option<&Function> {
None
}
} }
pub type HashMapConfiguration = HashMap<String, Value>; pub struct HashMapConfiguration {
variables: HashMap<String, Value>,
functions: HashMap<String, Function>,
}
impl HashMapConfiguration {
pub fn new() -> Self {
Self {
variables: Default::default(),
functions: Default::default(),
}
}
pub fn insert_variable(&mut self, identifier: String, value: Value) {
self.variables.insert(identifier, value);
}
pub fn insert_function(&mut self, identifier: String, function: Function) {
self.functions.insert(identifier, function);
}
}
impl Configuration for HashMapConfiguration { impl Configuration for HashMapConfiguration {
fn get_value(&self, identifier: &str) -> Option<&Value> { fn get_value(&self, identifier: &str) -> Option<&Value> {
self.get(identifier) self.variables.get(identifier)
}
fn get_function(&self, identifier: &str) -> Option<&Function> {
self.functions.get(identifier)
} }
} }

7
src/function.rs Normal file
View File

@ -0,0 +1,7 @@
use error::Error;
use value::Value;
pub struct Function {
parameter_amount: usize,
function: fn() -> Result<Value, Error>, // TODO continue type
}

View File

@ -8,6 +8,7 @@ mod operator;
mod token; mod token;
mod tree; mod tree;
mod value; mod value;
mod function;
pub fn eval(string: &str) -> Result<Value, Error> { pub fn eval(string: &str) -> Result<Value, Error> {
tree::tokens_to_operator_tree(token::tokenize(string)?)?.eval(&EmptyConfiguration) tree::tokens_to_operator_tree(token::tokenize(string)?)?.eval(&EmptyConfiguration)
@ -109,12 +110,12 @@ mod test {
#[test] #[test]
fn test_with_configuration() { fn test_with_configuration() {
let mut configuration = HashMapConfiguration::new(); let mut configuration = HashMapConfiguration::new();
configuration.insert("tr".to_string(), Value::Boolean(true)); configuration.insert_variable("tr".to_string(), Value::Boolean(true));
configuration.insert("fa".to_string(), Value::Boolean(false)); configuration.insert_variable("fa".to_string(), Value::Boolean(false));
configuration.insert("five".to_string(), Value::Int(5)); configuration.insert_variable("five".to_string(), Value::Int(5));
configuration.insert("six".to_string(), Value::Int(6)); configuration.insert_variable("six".to_string(), Value::Int(6));
configuration.insert("half".to_string(), Value::Float(0.5)); configuration.insert_variable("half".to_string(), Value::Float(0.5));
configuration.insert("zero".to_string(), Value::Int(0)); configuration.insert_variable("zero".to_string(), Value::Int(0));
assert_eq!(eval_with_configuration("tr", &configuration), Ok(Value::Boolean(true))); assert_eq!(eval_with_configuration("tr", &configuration), Ok(Value::Boolean(true)));
assert_eq!(eval_with_configuration("fa", &configuration), Ok(Value::Boolean(false))); assert_eq!(eval_with_configuration("fa", &configuration), Ok(Value::Boolean(false)));

View File

@ -477,12 +477,14 @@ impl Operator for Identifier {
} }
fn eval(&self, arguments: &[Value], configuration: &Configuration) -> Result<Value, Error> { fn eval(&self, arguments: &[Value], configuration: &Configuration) -> Result<Value, Error> {
expect_argument_amount(arguments.len(), 0)?; if arguments.len() == 0 {
if let Some(value) = configuration.get_value(&self.identifier).cloned() { if let Some(value) = configuration.get_value(&self.identifier).cloned() {
Ok(value) Ok(value)
} else { } else {
Err(Error::IdentifierNotFound(self.identifier.clone())) Err(Error::IdentifierNotFound(self.identifier.clone()))
} }
} else {
unimplemented!()
}
} }
} }