pub mod csv;
pub mod memory;
pub mod serde;
use crate::compiler::cursor::FunctionCursor;
use crate::compiler::value::parameters::Parameter;
use crate::compiler::value::values::{
FunctionDefinitionObject, FunctionValuesObject, TypeDefinition, Value,
};
use crate::{boolean_to_value, parameter_is_constant, parameter_to_constant};
use phf::phf_map;
use std::io::Error;
pub type NativeFn = fn(&[Value]) -> Value;
fn print(args: &[Value]) -> Value {
for value in args {
print!("{} ", value);
}
boolean_to_value!(true)
}
static NATIVE_FUNCTIONS: phf::Map<&'static str, NativeFn> = phf_map! {
"print" => print as _,
};
pub trait Store {
fn is_function_name_defined(&self, name: &str) -> Result<bool, Error>;
fn get_function_value(&self, name: &str, argument: &[Value]) -> Result<Option<Value>, Error>;
fn set_function_value(
&mut self,
name: &str,
argument: &[Value],
value: Value,
) -> Result<(), Error>;
fn get_function_definition(
&self,
name: &str,
argument: &[Value],
) -> Result<Option<FunctionDefinitionObject>, Error>;
fn get_native_function(&self, name: &str) -> Result<Option<&NativeFn>, Error> {
Ok(NATIVE_FUNCTIONS.get(name))
}
fn set_function_definition(
&mut self,
name: &str,
parameters: &[Parameter], function: FunctionDefinitionObject,
) -> Result<(), Error>;
fn function_cursor(&self, name: &str) -> FunctionCursor;
fn has_values(&self, name: &str) -> bool;
fn domain_arity(&self, name: &str) -> Option<u8>;
fn codomain_arity(&self, name: &str) -> Option<u8>;
fn set_type_definition(&mut self, name: &str, the_type: TypeDefinition) -> Result<(), Error>;
fn type_definition_by_name(&self, name: &str) -> Result<Option<TypeDefinition>, Error>;
}
pub(crate) fn arguments_match_value(formal_arguments: &[Parameter], argument: &[Value]) -> bool {
if formal_arguments.len() != argument.len() {
return false;
}
for (def_param_index, def_param) in formal_arguments.iter().enumerate() {
let arg_param = &argument[def_param_index];
if parameter_is_constant!(def_param) {
if !(parameter_to_constant!(def_param).equals(arg_param)) {
return false;
}
}
}
true
}
#[cfg(test)]
pub mod test_mock {
use crate::compiler::cursor::{FunctionCursor, VectorFunctionCursor};
use crate::compiler::value::parameters::Parameter;
use crate::compiler::value::values::{FunctionDefinitionObject, TypeDefinition, Value};
use crate::store::Store;
use crate::{empty_tuple_value, vector_to_value};
use std::collections::HashMap;
use std::io::Error;
pub struct StoreHasAllValuesMock {
pub arities: HashMap<String, (u8, u8)>,
}
impl Store for StoreHasAllValuesMock {
fn is_function_name_defined(&self, _name: &str) -> Result<bool, Error> {
Ok(true)
}
fn get_function_value(
&self,
_name: &str,
_argument: &[Value],
) -> Result<Option<Value>, Error> {
Ok(Some(empty_tuple_value!()))
}
fn set_function_value(
&mut self,
_name: &str,
_argument: &[Value],
_value: Value,
) -> Result<(), Error> {
Ok(())
}
fn get_function_definition(
&self,
_name: &str,
_argument: &[Value],
) -> Result<Option<FunctionDefinitionObject>, Error> {
Ok(Some(FunctionDefinitionObject::default()))
}
fn set_function_definition(
&mut self,
_name: &str,
_parameters: &[Parameter],
_function: FunctionDefinitionObject,
) -> Result<(), Error> {
Ok(())
}
fn function_cursor(&self, name: &str) -> FunctionCursor {
FunctionCursor::Vector(VectorFunctionCursor::new(vec![], vec![], name))
}
fn has_values(&self, name: &str) -> bool {
self.arities.contains_key(name)
}
fn domain_arity(&self, name: &str) -> Option<u8> {
return match self.arities.get(name) {
None => None,
Some((domain, _codomain)) => Some(*domain),
};
}
fn codomain_arity(&self, name: &str) -> Option<u8> {
return match self.arities.get(name) {
None => None,
Some((_domain, codomain)) => Some(*codomain),
};
}
fn set_type_definition(
&mut self,
_name: &str,
_the_type: TypeDefinition,
) -> Result<(), Error> {
todo!()
}
fn type_definition_by_name(&self, _name: &str) -> Result<Option<TypeDefinition>, Error> {
todo!()
}
}
}