#![allow(renamed_and_removed_lints, clippy::unknown_clippy_lints)]
use arithmetic_parser::{grammars::Grammar, Block};
use core::{cmp::Ordering, fmt};
use crate::{fns, Environment, Error, ExecutableModule, ModuleId, ModuleImports, Value};
pub trait VariableMap<'a, T> {
fn get_variable(&self, name: &str) -> Option<Value<'a, T>>;
fn compile_module<Id, G>(
&self,
id: Id,
block: &Block<'a, G>,
) -> Result<ExecutableModule<'a, T>, Error<'a>>
where
Id: ModuleId,
G: Grammar<'a, Lit = T>,
T: Clone + fmt::Debug,
{
ExecutableModule::builder(id, block)?
.with_imports_from(self)
.try_build()
}
}
impl<'a, T: Clone> VariableMap<'a, T> for Environment<'a, T> {
fn get_variable(&self, name: &str) -> Option<Value<'a, T>> {
self.get(name).cloned()
}
}
impl<'a, T: Clone> VariableMap<'a, T> for ModuleImports<'a, T> {
fn get_variable(&self, name: &str) -> Option<Value<'a, T>> {
self.get(name).cloned()
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct Prelude;
impl Prelude {
#[allow(clippy::missing_panics_doc)] pub fn iter<T: Clone>(self) -> impl Iterator<Item = (&'static str, Value<'static, T>)> {
const VAR_NAMES: &[&str] = &[
"false", "true", "if", "loop", "while", "map", "filter", "fold", "push", "merge",
];
VAR_NAMES
.iter()
.map(move |&var_name| (var_name, self.get_variable(var_name).unwrap()))
}
}
impl<'a, T: Clone> VariableMap<'a, T> for Prelude {
fn get_variable(&self, name: &str) -> Option<Value<'a, T>> {
Some(match name {
"false" => Value::Bool(false),
"true" => Value::Bool(true),
"if" => Value::native_fn(fns::If),
"loop" => Value::native_fn(fns::Loop),
"while" => Value::native_fn(fns::While),
"map" => Value::native_fn(fns::Map),
"filter" => Value::native_fn(fns::Filter),
"fold" => Value::native_fn(fns::Fold),
"push" => Value::native_fn(fns::Push),
"merge" => Value::native_fn(fns::Merge),
_ => return None,
})
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct Assertions;
impl Assertions {
#[allow(clippy::missing_panics_doc)] pub fn iter<T: fmt::Display>(self) -> impl Iterator<Item = (&'static str, Value<'static, T>)> {
const VAR_NAMES: &[&str] = &["assert", "assert_eq"];
VAR_NAMES
.iter()
.map(move |&var_name| (var_name, self.get_variable(var_name).unwrap()))
}
}
impl<'a, T: fmt::Display> VariableMap<'a, T> for Assertions {
fn get_variable(&self, name: &str) -> Option<Value<'a, T>> {
Some(match name {
"assert" => Value::native_fn(fns::Assert),
"assert_eq" => Value::native_fn(fns::AssertEq),
_ => return None,
})
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct Comparisons;
impl<'a, T> VariableMap<'a, T> for Comparisons {
fn get_variable(&self, name: &str) -> Option<Value<'a, T>> {
Some(match name {
"LESS" => Value::opaque_ref(Ordering::Less),
"EQUAL" => Value::opaque_ref(Ordering::Equal),
"GREATER" => Value::opaque_ref(Ordering::Greater),
"cmp" => Value::native_fn(fns::Compare::Raw),
"min" => Value::native_fn(fns::Compare::Min),
"max" => Value::native_fn(fns::Compare::Max),
_ => return None,
})
}
}
impl Comparisons {
#[allow(clippy::missing_panics_doc)] pub fn iter<T>(self) -> impl Iterator<Item = (&'static str, Value<'static, T>)> {
const VAR_NAMES: &[&str] = &["LESS", "EQUAL", "GREATER", "cmp", "min", "max"];
VAR_NAMES
.iter()
.map(move |&var_name| (var_name, self.get_variable(var_name).unwrap()))
}
}