1use tan::{
2 context::Context,
3 error::Error,
4 expr::Expr,
5 util::{
6 args::{
7 unpack_bool_arg, unpack_float_arg, unpack_int_arg, unpack_stringable_arg, unpack_u8_arg,
8 },
9 module_util::require_module,
10 },
11};
12
13pub fn eq_int(args: &[Expr]) -> Result<Expr, Error> {
35 let a = unpack_int_arg(args, 0, "a")?;
43 let b = unpack_int_arg(args, 1, "b")?;
44
45 Ok(Expr::Bool(a == b))
46}
47
48pub fn eq_u8(args: &[Expr]) -> Result<Expr, Error> {
49 let a = unpack_u8_arg(args, 0, "a")?;
57 let b = unpack_u8_arg(args, 1, "b")?;
58
59 Ok(Expr::Bool(a == b))
60}
61
62pub fn eq_float(args: &[Expr]) -> Result<Expr, Error> {
63 let a = unpack_float_arg(args, 0, "a")?;
70 let b = unpack_float_arg(args, 1, "b")?;
71
72 Ok(Expr::Bool(a == b))
73}
74
75pub fn eq_bool(args: &[Expr]) -> Result<Expr, Error> {
76 let a = unpack_bool_arg(args, 0, "a")?;
80 let b = unpack_bool_arg(args, 1, "b")?;
81
82 Ok(Expr::Bool(a == b))
83}
84
85pub fn eq_string(args: &[Expr]) -> Result<Expr, Error> {
86 let a = unpack_stringable_arg(args, 0, "a")?;
93 let b = unpack_stringable_arg(args, 1, "b")?;
94
95 Ok(Expr::Bool(a == b))
96}
97
98pub fn eq_symbol(args: &[Expr]) -> Result<Expr, Error> {
100 let [a, b] = args else {
106 return Err(Error::invalid_arguments(
107 "`=` requires at least two arguments",
108 None,
109 ));
110 };
111
112 let Some(a) = a.as_symbolic() else {
113 return Err(Error::invalid_arguments(
114 &format!("`{a}` is not a Symbol"),
115 a.range(),
116 ));
117 };
118
119 let Some(b) = b.as_symbolic() else {
120 return Err(Error::invalid_arguments(
121 &format!("`{b}` is not a Symbol"),
122 b.range(),
123 ));
124 };
125
126 Ok(Expr::Bool(a == b))
127}
128
129pub fn not_eq_int(args: &[Expr]) -> Result<Expr, Error> {
132 Ok(Expr::Bool(eq_int(args)?.is_false()))
133}
134
135pub fn not_eq_float(args: &[Expr]) -> Result<Expr, Error> {
136 Ok(Expr::Bool(eq_float(args)?.is_false()))
137}
138
139pub fn not_eq_string(args: &[Expr]) -> Result<Expr, Error> {
140 Ok(Expr::Bool(eq_string(args)?.is_false()))
141}
142
143pub fn not_eq_symbol(args: &[Expr]) -> Result<Expr, Error> {
145 let [a, b] = args else {
151 return Err(Error::invalid_arguments(
152 "`!=` requires at least two arguments",
153 None,
154 ));
155 };
156
157 let Some(a) = a.as_symbolic() else {
158 return Err(Error::invalid_arguments(
159 &format!("`{a}` is not a String"),
160 a.range(),
161 ));
162 };
163
164 let Some(b) = b.as_symbolic() else {
165 return Err(Error::invalid_arguments(
166 &format!("`{b}` is not a Symbol"),
167 b.range(),
168 ));
169 };
170
171 Ok(Expr::Bool(a != b))
172}
173
174pub fn int_gt(args: &[Expr]) -> Result<Expr, Error> {
175 let [a, b] = args else {
177 return Err(Error::invalid_arguments(
178 "`>` requires at least two arguments",
179 None,
180 ));
181 };
182
183 let Some(a) = a.as_int() else {
184 return Err(Error::invalid_arguments(
185 &format!("`{a}` is not an Int"),
186 a.range(),
187 ));
188 };
189
190 let Some(b) = b.as_int() else {
191 return Err(Error::invalid_arguments(
192 &format!("`{b}` is not an Int"),
193 b.range(),
194 ));
195 };
196
197 Ok(Expr::Bool(a > b))
198}
199
200pub fn float_gt(args: &[Expr]) -> Result<Expr, Error> {
201 let [a, b] = args else {
203 return Err(Error::invalid_arguments(
204 "`>` requires at least two arguments",
205 None,
206 ));
207 };
208
209 let Some(a) = a.as_float() else {
210 return Err(Error::invalid_arguments(
211 &format!("`{a}` is not a Float"),
212 a.range(),
213 ));
214 };
215
216 let Some(b) = b.as_float() else {
217 return Err(Error::invalid_arguments(
218 &format!("`{b}` is not a Float"),
219 b.range(),
220 ));
221 };
222
223 Ok(Expr::Bool(a > b))
224}
225
226pub fn int_gte(args: &[Expr]) -> Result<Expr, Error> {
227 let a = unpack_int_arg(args, 0, "a")?;
230 let b = unpack_int_arg(args, 1, "b")?;
231
232 Ok(Expr::Bool(a >= b))
233}
234
235pub fn float_gte(args: &[Expr]) -> Result<Expr, Error> {
236 let a = unpack_float_arg(args, 0, "a")?;
239 let b = unpack_float_arg(args, 1, "b")?;
240
241 Ok(Expr::Bool(a >= b))
242}
243
244pub fn int_lt(args: &[Expr]) -> Result<Expr, Error> {
245 let [a, b] = args else {
247 return Err(Error::invalid_arguments(
248 "`<` requires at least two arguments",
249 None,
250 ));
251 };
252
253 let Some(a) = a.as_int() else {
254 return Err(Error::invalid_arguments(
255 &format!("`{a}` is not an Int"),
256 a.range(),
257 ));
258 };
259
260 let Some(b) = b.as_int() else {
261 return Err(Error::invalid_arguments(
262 &format!("`{b}` is not an Int"),
263 b.range(),
264 ));
265 };
266
267 Ok(Expr::Bool(a < b))
268}
269
270pub fn float_lt(args: &[Expr]) -> Result<Expr, Error> {
271 let a = unpack_float_arg(args, 0, "a")?;
274 let b = unpack_float_arg(args, 1, "b")?;
275
276 Ok(Expr::Bool(a < b))
277}
278
279pub fn int_lte(args: &[Expr]) -> Result<Expr, Error> {
280 let a = unpack_int_arg(args, 0, "a")?;
283 let b = unpack_int_arg(args, 1, "b")?;
284
285 Ok(Expr::Bool(a <= b))
286}
287
288pub fn float_lte(args: &[Expr]) -> Result<Expr, Error> {
289 let a = unpack_float_arg(args, 0, "a")?;
292 let b = unpack_float_arg(args, 1, "b")?;
293
294 Ok(Expr::Bool(a <= b))
295}
296
297pub fn setup_lib_eq(context: &mut Context) {
300 let module = require_module("prelude", context);
301
302 module.insert_invocable("=$$Int$$Int", Expr::foreign_func(&eq_int));
304 module.insert_invocable("=$$U8$$U8", Expr::foreign_func(&eq_u8));
305 module.insert_invocable("=$$Bool$$Bool", Expr::foreign_func(&eq_bool));
306 module.insert_invocable("=$$Float$$Float", Expr::foreign_func(&eq_float));
307 module.insert_invocable("=$$String$$String", Expr::foreign_func(&eq_string));
308 module.insert_invocable("=$$KeySymbol$$KeySymbol", Expr::foreign_func(&eq_symbol));
310 module.insert_invocable("=$$Type$$Type", Expr::foreign_func(&eq_symbol));
312 module.insert_invocable("=$$Type$$String", Expr::foreign_func(&eq_symbol));
313 module.insert_invocable("=$$Type$$KeySymbol", Expr::foreign_func(&eq_symbol));
314
315 module.insert_invocable("!=$$Int$$Int", Expr::foreign_func(¬_eq_int));
316 module.insert_invocable("!=$$Float$$Float", Expr::foreign_func(¬_eq_float));
317 module.insert_invocable("!=$$String$$String", Expr::foreign_func(¬_eq_string));
318 module.insert_invocable("!=$$Symbol$$Symbol", Expr::foreign_func(¬_eq_symbol));
319 module.insert_invocable(
320 "!=$$KeySymbol$$KeySymbol",
321 Expr::foreign_func(¬_eq_symbol),
322 );
323
324 module.insert_invocable(">$$Int$$Int", Expr::foreign_func(&int_gt));
325 module.insert_invocable(">$$Float$$Float", Expr::foreign_func(&float_gt));
326 module.insert_invocable(">=$$Int$$Int", Expr::foreign_func(&int_gte));
327 module.insert_invocable(">=$$Float$$Float", Expr::foreign_func(&float_gte));
328 module.insert_invocable("<$$Int$$Int", Expr::foreign_func(&int_lt));
329 module.insert_invocable("<$$Float$$Float", Expr::foreign_func(&float_lt));
330 module.insert_invocable("<=$$Int$$Int", Expr::foreign_func(&int_lte));
331 module.insert_invocable("<=$$Float$$Float", Expr::foreign_func(&float_lte));
332}