use crate::compiler::cursor::{FunctionCursor, VectorFunctionCursor};
use crate::compiler::value::parameters::{parameter_vectors_match, Parameter};
use crate::compiler::value::values::{
FunctionDefinitionObject, FunctionValuesObject, TypeDefinition, Value,
};
use crate::store::{arguments_match_value, Store, NATIVE_FUNCTIONS};
use crate::{value_is_tuple, value_to_tuple};
use std::collections::HashMap;
use std::io::Error;
pub struct MemoryStore {
function_definitions_registry: HashMap<String, Vec<FunctionDefinitionObject>>,
function_values_registry: HashMap<String, FunctionValuesObject>,
type_definitions: HashMap<String, TypeDefinition>,
}
impl Store for MemoryStore {
fn is_function_name_defined(&self, name: &str) -> Result<bool, Error> {
Ok(self.function_definitions_registry.contains_key(name))
}
fn get_function_value(&self, name: &str, argument: &[Value]) -> Result<Option<Value>, Error> {
if let Some(values) = self.function_values_registry.get(name) {
return Ok(values.values.get(argument).cloned());
} else {
Ok(None)
}
}
fn set_function_value(
&mut self,
name: &str,
argument: &[Value],
value: Value,
) -> Result<(), Error> {
if let Some(values) = self.function_values_registry.get_mut(name) {
values.values.insert(argument.to_vec(), value);
} else {
let mut values = FunctionValuesObject::new();
values.values.insert(argument.to_vec(), value);
self.function_values_registry
.insert(name.to_string(), values);
}
Ok(())
}
fn get_function_definition(
&self,
name: &str,
argument: &[Value],
) -> Result<Option<FunctionDefinitionObject>, Error> {
if let Some(definitions) = self.function_definitions_registry.get(name) {
for definition in definitions {
if arguments_match_value(&definition.formal_arguments, argument) {
return Ok(Some(definition.clone()));
}
}
}
Ok(None)
}
fn set_function_definition(
&mut self,
name: &str,
parameters: &[Parameter],
function: FunctionDefinitionObject,
) -> Result<(), Error> {
if let Some(defs) = self.function_definitions_registry.get_mut(name) {
defs.retain(|definition| {
!parameter_vectors_match(&definition.formal_arguments, parameters)
});
defs.push(function);
} else {
let defs = vec![function];
self.function_definitions_registry
.insert(name.to_string(), defs);
}
Ok(())
}
fn function_cursor(&self, name: &str) -> FunctionCursor {
return match self.function_values_registry.get(name) {
None => FunctionCursor::Vector(VectorFunctionCursor::empty()),
Some(function) => {
let mut lhs = vec![];
let mut rhs = vec![];
for (key, value) in &function.values {
lhs.push(key.clone());
match value {
Value::PrimitiveValue(_) => {
rhs.push(vec![value.clone()]);
}
Value::Tuple(vec) => {
rhs.push(vec.clone());
}
Value::TypedValueInstance(_) => {
rhs.push(vec![value.clone()]);
}
Value::FunctionNameValue(name) => {
panic!(
"Function name values not supported as stored value types yet: {}",
name
);
}
}
}
FunctionCursor::Vector(VectorFunctionCursor::new(lhs, rhs, name))
}
};
}
fn has_values(&self, name: &str) -> bool {
self.function_values_registry.get(name).is_some()
}
fn domain_arity(&self, name: &str) -> Option<u8> {
match self.function_values_registry.get(name) {
Some(function) => match function.values.keys().next() {
None => {
panic!("Cannot have values and not have values at the same time, what the hell")
}
Some(key) => return Some(key.len() as u8),
},
None => {}
};
match self.function_definitions_registry.get(name) {
Some(defs) => {
return Some(defs.first().unwrap().formal_arguments.len() as u8);
}
None => {}
};
match NATIVE_FUNCTIONS.get(name) {
Some(_) => Some(1),
None => None,
}
}
fn codomain_arity(&self, name: &str) -> Option<u8> {
match self.function_values_registry.get(name) {
Some(function) => match function.values.values().next() {
None => {
panic!("Cannot have values and not have values at the same time, what the hell")
}
Some(value) => {
if value_is_tuple!(value) {
return Some(value_to_tuple!(value).len() as u8);
}
return Some(1_u8);
}
},
None => {}
};
match self.function_definitions_registry.get(name) {
Some(_) => {
return Some(1_u8);
}
None => {}
};
match NATIVE_FUNCTIONS.get(name) {
Some(_) => Some(1),
None => None,
}
}
fn set_type_definition(&mut self, name: &str, the_type: TypeDefinition) -> Result<(), Error> {
self.type_definitions.insert(name.to_string(), the_type);
Ok(())
}
fn type_definition_by_name(&self, name: &str) -> Result<Option<TypeDefinition>, Error> {
Ok(self.type_definitions.get(name).cloned())
}
}
impl MemoryStore {
pub fn new() -> Self {
MemoryStore {
function_definitions_registry: HashMap::new(),
function_values_registry: HashMap::new(),
type_definitions: HashMap::new(),
}
}
}
impl Default for MemoryStore {
fn default() -> Self {
Self::new()
}
}