1#![allow(renamed_and_removed_lints, clippy::unknown_clippy_lints)]
4use arithmetic_parser::{grammars::Grammar, Block};
8
9use core::{cmp::Ordering, fmt};
10
11use crate::{fns, Environment, Error, ExecutableModule, ModuleId, ModuleImports, Value};
12
13pub trait VariableMap<'a, T> {
15 fn get_variable(&self, name: &str) -> Option<Value<'a, T>>;
17
18 fn compile_module<Id, G>(
22 &self,
23 id: Id,
24 block: &Block<'a, G>,
25 ) -> Result<ExecutableModule<'a, T>, Error<'a>>
26 where
27 Id: ModuleId,
28 G: Grammar<'a, Lit = T>,
29 T: Clone + fmt::Debug,
30 {
31 ExecutableModule::builder(id, block)?
32 .with_imports_from(self)
33 .try_build()
34 }
35}
36
37impl<'a, T: Clone> VariableMap<'a, T> for Environment<'a, T> {
38 fn get_variable(&self, name: &str) -> Option<Value<'a, T>> {
39 self.get(name).cloned()
40 }
41}
42
43impl<'a, T: Clone> VariableMap<'a, T> for ModuleImports<'a, T> {
44 fn get_variable(&self, name: &str) -> Option<Value<'a, T>> {
45 self.get(name).cloned()
46 }
47}
48
49#[derive(Debug, Clone, Copy, Default)]
58pub struct Prelude;
59
60impl Prelude {
61 #[allow(clippy::missing_panics_doc)] pub fn iter<T: Clone>(self) -> impl Iterator<Item = (&'static str, Value<'static, T>)> {
64 const VAR_NAMES: &[&str] = &[
65 "false", "true", "if", "loop", "while", "map", "filter", "fold", "push", "merge",
66 ];
67
68 VAR_NAMES
69 .iter()
70 .map(move |&var_name| (var_name, self.get_variable(var_name).unwrap()))
71 }
72}
73
74impl<'a, T: Clone> VariableMap<'a, T> for Prelude {
75 fn get_variable(&self, name: &str) -> Option<Value<'a, T>> {
76 Some(match name {
77 "false" => Value::Bool(false),
78 "true" => Value::Bool(true),
79 "if" => Value::native_fn(fns::If),
80 "loop" => Value::native_fn(fns::Loop),
81 "while" => Value::native_fn(fns::While),
82 "map" => Value::native_fn(fns::Map),
83 "filter" => Value::native_fn(fns::Filter),
84 "fold" => Value::native_fn(fns::Fold),
85 "push" => Value::native_fn(fns::Push),
86 "merge" => Value::native_fn(fns::Merge),
87 _ => return None,
88 })
89 }
90}
91
92#[derive(Debug, Clone, Copy, Default)]
94pub struct Assertions;
95
96impl Assertions {
97 #[allow(clippy::missing_panics_doc)] pub fn iter<T: fmt::Display>(self) -> impl Iterator<Item = (&'static str, Value<'static, T>)> {
100 const VAR_NAMES: &[&str] = &["assert", "assert_eq"];
101
102 VAR_NAMES
103 .iter()
104 .map(move |&var_name| (var_name, self.get_variable(var_name).unwrap()))
105 }
106}
107
108impl<'a, T: fmt::Display> VariableMap<'a, T> for Assertions {
109 fn get_variable(&self, name: &str) -> Option<Value<'a, T>> {
110 Some(match name {
111 "assert" => Value::native_fn(fns::Assert),
112 "assert_eq" => Value::native_fn(fns::AssertEq),
113 _ => return None,
114 })
115 }
116}
117
118#[derive(Debug, Clone, Copy, Default)]
120pub struct Comparisons;
121
122impl<'a, T> VariableMap<'a, T> for Comparisons {
123 fn get_variable(&self, name: &str) -> Option<Value<'a, T>> {
124 Some(match name {
125 "LESS" => Value::opaque_ref(Ordering::Less),
126 "EQUAL" => Value::opaque_ref(Ordering::Equal),
127 "GREATER" => Value::opaque_ref(Ordering::Greater),
128 "cmp" => Value::native_fn(fns::Compare::Raw),
129 "min" => Value::native_fn(fns::Compare::Min),
130 "max" => Value::native_fn(fns::Compare::Max),
131 _ => return None,
132 })
133 }
134}
135
136impl Comparisons {
137 #[allow(clippy::missing_panics_doc)] pub fn iter<T>(self) -> impl Iterator<Item = (&'static str, Value<'static, T>)> {
140 const VAR_NAMES: &[&str] = &["LESS", "EQUAL", "GREATER", "cmp", "min", "max"];
141
142 VAR_NAMES
143 .iter()
144 .map(move |&var_name| (var_name, self.get_variable(var_name).unwrap()))
145 }
146}