1use crate::{builder, error};
6
7use super::{MapKey, SymbolIndex, Term};
8use super::{SymbolTable, TemporarySymbolTable};
9use regex::Regex;
10use std::sync::Arc;
11use std::{
12 collections::{HashMap, HashSet},
13 convert::TryFrom,
14};
15
16#[derive(Clone)]
17pub struct ExternFunc(
18 pub Arc<
19 dyn Fn(builder::Term, Option<builder::Term>) -> Result<builder::Term, String> + Send + Sync,
20 >,
21);
22
23impl std::fmt::Debug for ExternFunc {
24 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 write!(f, "<function>")
26 }
27}
28
29impl ExternFunc {
30 pub fn new(
31 f: Arc<
32 dyn Fn(builder::Term, Option<builder::Term>) -> Result<builder::Term, String>
33 + Send
34 + Sync,
35 >,
36 ) -> Self {
37 Self(f)
38 }
39
40 pub fn call(
41 &self,
42 symbols: &mut TemporarySymbolTable,
43 name: &str,
44 left: Term,
45 right: Option<Term>,
46 ) -> Result<Term, error::Expression> {
47 let left = builder::Term::from_datalog(left, symbols)?;
48 let right = right
49 .map(|right| builder::Term::from_datalog(right, symbols))
50 .transpose()?;
51 match self.0(left, right) {
52 Ok(t) => Ok(t.to_datalog(symbols)),
53 Err(e) => Err(error::Expression::ExternEvalError(name.to_string(), e)),
54 }
55 }
56}
57
58#[derive(Debug, Clone, PartialEq, Hash, Eq)]
59pub struct Expression {
60 pub ops: Vec<Op>,
61}
62
63#[derive(Debug, Clone, PartialEq, Hash, Eq)]
64pub enum Op {
65 Value(Term),
66 Unary(Unary),
67 Binary(Binary),
68 Closure(Vec<u32>, Vec<Op>),
69}
70
71#[derive(Debug, Clone, PartialEq, Hash, Eq)]
73pub enum Unary {
74 Negate,
75 Parens,
76 Length,
77 TypeOf,
78 Ffi(SymbolIndex),
79}
80
81impl Unary {
82 fn evaluate(
83 &self,
84 value: Term,
85 symbols: &mut TemporarySymbolTable,
86 extern_funcs: &HashMap<String, ExternFunc>,
87 ) -> Result<Term, error::Expression> {
88 match (self, value) {
89 (Unary::Negate, Term::Bool(b)) => Ok(Term::Bool(!b)),
90 (Unary::Parens, i) => Ok(i),
91 (Unary::Length, Term::Str(i)) => symbols
92 .get_symbol(i)
93 .map(|s| Term::Integer(s.len() as i64))
94 .ok_or(error::Expression::UnknownSymbol(i)),
95 (Unary::Length, Term::Bytes(s)) => Ok(Term::Integer(s.len() as i64)),
96 (Unary::Length, Term::Set(s)) => Ok(Term::Integer(s.len() as i64)),
97 (Unary::Length, Term::Array(a)) => Ok(Term::Integer(a.len() as i64)),
98 (Unary::Length, Term::Map(m)) => Ok(Term::Integer(m.len() as i64)),
99 (Unary::TypeOf, t) => {
100 let type_string = match t {
101 Term::Variable(_) => return Err(error::Expression::InvalidType),
102 Term::Integer(_) => "integer",
103 Term::Str(_) => "string",
104 Term::Date(_) => "date",
105 Term::Bytes(_) => "bytes",
106 Term::Bool(_) => "bool",
107 Term::Set(_) => "set",
108 Term::Null => "null",
109 Term::Array(_) => "array",
110 Term::Map(_) => "map",
111 };
112 let sym = symbols.insert(type_string);
113 Ok(Term::Str(sym))
114 }
115 (Unary::Ffi(name), i) => {
116 let name = symbols
117 .get_symbol(*name)
118 .ok_or(error::Expression::UnknownSymbol(*name))?
119 .to_owned();
120 let fun = extern_funcs
121 .get(&name)
122 .ok_or(error::Expression::UndefinedExtern(name.to_owned()))?;
123 fun.call(symbols, &name, i, None)
124 }
125 _ => {
126 Err(error::Expression::InvalidType)
128 }
129 }
130 }
131
132 pub fn print(&self, value: String, symbols: &SymbolTable) -> String {
133 match self {
134 Unary::Negate => format!("!{}", value),
135 Unary::Parens => format!("({})", value),
136 Unary::Length => format!("{}.length()", value),
137 Unary::TypeOf => format!("{}.type()", value),
138 Unary::Ffi(name) => {
139 format!("{value}.extern::{}()", symbols.print_symbol_default(*name))
140 }
141 }
142 }
143}
144
145#[derive(Debug, Clone, PartialEq, Hash, Eq)]
147pub enum Binary {
148 LessThan,
149 GreaterThan,
150 LessOrEqual,
151 GreaterOrEqual,
152 Equal,
153 Contains,
154 Prefix,
155 Suffix,
156 Regex,
157 Add,
158 Sub,
159 Mul,
160 Div,
161 And,
162 Or,
163 Intersection,
164 Union,
165 BitwiseAnd,
166 BitwiseOr,
167 BitwiseXor,
168 NotEqual,
169 HeterogeneousEqual,
170 HeterogeneousNotEqual,
171 LazyAnd,
172 LazyOr,
173 All,
174 Any,
175 Get,
176 Ffi(SymbolIndex),
177 TryOr,
178}
179
180impl Binary {
181 fn evaluate_with_closure(
182 &self,
183 left: Term,
184 right: Vec<Op>,
185 params: &[u32],
186 values: &mut HashMap<u32, Term>,
187 symbols: &mut TemporarySymbolTable,
188 extern_func: &HashMap<String, ExternFunc>,
189 ) -> Result<Term, error::Expression> {
190 match (self, left, params) {
191 (Binary::TryOr, fallback, []) => {
193 let e = Expression { ops: right.clone() };
194 match e.evaluate(values, symbols, extern_func) {
195 Ok(v) => Ok(v),
196 Err(_) => Ok(fallback),
197 }
198 }
199 (Binary::LazyOr, Term::Bool(true), []) => Ok(Term::Bool(true)),
201 (Binary::LazyOr, Term::Bool(false), []) => {
202 let e = Expression { ops: right.clone() };
203 e.evaluate(values, symbols, extern_func)
204 }
205 (Binary::LazyAnd, Term::Bool(false), []) => Ok(Term::Bool(false)),
206 (Binary::LazyAnd, Term::Bool(true), []) => {
207 let e = Expression { ops: right.clone() };
208 e.evaluate(values, symbols, extern_func)
209 }
210
211 (Binary::All, Term::Set(set_values), [param]) => {
213 for value in set_values.iter() {
214 values.insert(*param, value.clone());
215 let e = Expression { ops: right.clone() };
216 let result = e.evaluate(values, symbols, extern_func);
217 values.remove(param);
218 match result? {
219 Term::Bool(true) => {}
220 Term::Bool(false) => return Ok(Term::Bool(false)),
221 _ => return Err(error::Expression::InvalidType),
222 };
223 }
224 Ok(Term::Bool(true))
225 }
226 (Binary::Any, Term::Set(set_values), [param]) => {
227 for value in set_values.iter() {
228 values.insert(*param, value.clone());
229 let e = Expression { ops: right.clone() };
230 let result = e.evaluate(values, symbols, extern_func);
231 values.remove(param);
232 match result? {
233 Term::Bool(false) => {}
234 Term::Bool(true) => return Ok(Term::Bool(true)),
235 _ => return Err(error::Expression::InvalidType),
236 };
237 }
238 Ok(Term::Bool(false))
239 }
240
241 (Binary::All, Term::Array(array), [param]) => {
243 for value in array.iter() {
244 values.insert(*param, value.clone());
245 let e = Expression { ops: right.clone() };
246 let result = e.evaluate(values, symbols, extern_func);
247 values.remove(param);
248 match result? {
249 Term::Bool(true) => {}
250 Term::Bool(false) => return Ok(Term::Bool(false)),
251 _ => return Err(error::Expression::InvalidType),
252 };
253 }
254 Ok(Term::Bool(true))
255 }
256 (Binary::Any, Term::Array(array), [param]) => {
257 for value in array.iter() {
258 values.insert(*param, value.clone());
259 let e = Expression { ops: right.clone() };
260 let result = e.evaluate(values, symbols, extern_func);
261 values.remove(param);
262 match result? {
263 Term::Bool(false) => {}
264 Term::Bool(true) => return Ok(Term::Bool(true)),
265 _ => return Err(error::Expression::InvalidType),
266 };
267 }
268 Ok(Term::Bool(false))
269 }
270
271 (Binary::All, Term::Map(map), [param]) => {
273 for (key, value) in map.iter() {
274 let key = match key {
275 MapKey::Integer(i) => Term::Integer(*i),
276 MapKey::Str(i) => Term::Str(*i),
277 };
278 values.insert(*param, Term::Array(vec![key, value.clone()]));
279
280 let e = Expression { ops: right.clone() };
281 let result = e.evaluate(values, symbols, extern_func);
282 values.remove(param);
283 match result? {
284 Term::Bool(true) => {}
285 Term::Bool(false) => return Ok(Term::Bool(false)),
286 _ => return Err(error::Expression::InvalidType),
287 };
288 }
289 Ok(Term::Bool(true))
290 }
291 (Binary::Any, Term::Map(map), [param]) => {
292 for (key, value) in map.iter() {
293 let key = match key {
294 MapKey::Integer(i) => Term::Integer(*i),
295 MapKey::Str(i) => Term::Str(*i),
296 };
297 values.insert(*param, Term::Array(vec![key, value.clone()]));
298
299 let e = Expression { ops: right.clone() };
300 let result = e.evaluate(values, symbols, extern_func);
301 values.remove(param);
302 match result? {
303 Term::Bool(false) => {}
304 Term::Bool(true) => return Ok(Term::Bool(true)),
305 _ => return Err(error::Expression::InvalidType),
306 };
307 }
308 Ok(Term::Bool(false))
309 }
310 (_, _, _) => Err(error::Expression::InvalidType),
311 }
312 }
313 fn evaluate(
314 &self,
315 left: Term,
316 right: Term,
317 symbols: &mut TemporarySymbolTable,
318 extern_funcs: &HashMap<String, ExternFunc>,
319 ) -> Result<Term, error::Expression> {
320 match (self, left, right) {
321 (Binary::LessThan, Term::Integer(i), Term::Integer(j)) => Ok(Term::Bool(i < j)),
323 (Binary::GreaterThan, Term::Integer(i), Term::Integer(j)) => Ok(Term::Bool(i > j)),
324 (Binary::LessOrEqual, Term::Integer(i), Term::Integer(j)) => Ok(Term::Bool(i <= j)),
325 (Binary::GreaterOrEqual, Term::Integer(i), Term::Integer(j)) => Ok(Term::Bool(i >= j)),
326 (Binary::Equal | Binary::HeterogeneousEqual, Term::Integer(i), Term::Integer(j)) => {
327 Ok(Term::Bool(i == j))
328 }
329 (
330 Binary::NotEqual | Binary::HeterogeneousNotEqual,
331 Term::Integer(i),
332 Term::Integer(j),
333 ) => Ok(Term::Bool(i != j)),
334 (Binary::Add, Term::Integer(i), Term::Integer(j)) => i
335 .checked_add(j)
336 .map(Term::Integer)
337 .ok_or(error::Expression::Overflow),
338 (Binary::Sub, Term::Integer(i), Term::Integer(j)) => i
339 .checked_sub(j)
340 .map(Term::Integer)
341 .ok_or(error::Expression::Overflow),
342 (Binary::Mul, Term::Integer(i), Term::Integer(j)) => i
343 .checked_mul(j)
344 .map(Term::Integer)
345 .ok_or(error::Expression::Overflow),
346 (Binary::Div, Term::Integer(i), Term::Integer(j)) => i
347 .checked_div(j)
348 .map(Term::Integer)
349 .ok_or(error::Expression::DivideByZero),
350 (Binary::BitwiseAnd, Term::Integer(i), Term::Integer(j)) => Ok(Term::Integer(i & j)),
351 (Binary::BitwiseOr, Term::Integer(i), Term::Integer(j)) => Ok(Term::Integer(i | j)),
352 (Binary::BitwiseXor, Term::Integer(i), Term::Integer(j)) => Ok(Term::Integer(i ^ j)),
353
354 (Binary::Prefix, Term::Str(s), Term::Str(pref)) => {
356 match (symbols.get_symbol(s), symbols.get_symbol(pref)) {
357 (Some(s), Some(pref)) => Ok(Term::Bool(s.starts_with(pref))),
358 (Some(_), None) => Err(error::Expression::UnknownSymbol(pref)),
359 _ => Err(error::Expression::UnknownSymbol(s)),
360 }
361 }
362 (Binary::Suffix, Term::Str(s), Term::Str(suff)) => {
363 match (symbols.get_symbol(s), symbols.get_symbol(suff)) {
364 (Some(s), Some(suff)) => Ok(Term::Bool(s.ends_with(suff))),
365 (Some(_), None) => Err(error::Expression::UnknownSymbol(suff)),
366 _ => Err(error::Expression::UnknownSymbol(s)),
367 }
368 }
369 (Binary::Regex, Term::Str(s), Term::Str(r)) => {
370 match (symbols.get_symbol(s), symbols.get_symbol(r)) {
371 (Some(s), Some(r)) => Ok(Term::Bool(
372 Regex::new(r).map(|re| re.is_match(s)).unwrap_or(false),
373 )),
374 (Some(_), None) => Err(error::Expression::UnknownSymbol(r)),
375 _ => Err(error::Expression::UnknownSymbol(s)),
376 }
377 }
378 (Binary::Contains, Term::Str(s), Term::Str(pattern)) => {
379 match (symbols.get_symbol(s), symbols.get_symbol(pattern)) {
380 (Some(s), Some(pattern)) => Ok(Term::Bool(s.contains(pattern))),
381 (Some(_), None) => Err(error::Expression::UnknownSymbol(pattern)),
382 _ => Err(error::Expression::UnknownSymbol(s)),
383 }
384 }
385 (Binary::Add, Term::Str(s1), Term::Str(s2)) => {
386 match (symbols.get_symbol(s1), symbols.get_symbol(s2)) {
387 (Some(s1), Some(s2)) => {
388 let s = format!("{}{}", s1, s2);
389 let sym = symbols.insert(&s);
390 Ok(Term::Str(sym))
391 }
392 (Some(_), None) => Err(error::Expression::UnknownSymbol(s2)),
393 _ => Err(error::Expression::UnknownSymbol(s1)),
394 }
395 }
396 (Binary::Equal | Binary::HeterogeneousEqual, Term::Str(i), Term::Str(j)) => {
397 Ok(Term::Bool(i == j))
398 }
399 (Binary::NotEqual | Binary::HeterogeneousNotEqual, Term::Str(i), Term::Str(j)) => {
400 Ok(Term::Bool(i != j))
401 }
402
403 (Binary::LessThan, Term::Date(i), Term::Date(j)) => Ok(Term::Bool(i < j)),
405 (Binary::GreaterThan, Term::Date(i), Term::Date(j)) => Ok(Term::Bool(i > j)),
406 (Binary::LessOrEqual, Term::Date(i), Term::Date(j)) => Ok(Term::Bool(i <= j)),
407 (Binary::GreaterOrEqual, Term::Date(i), Term::Date(j)) => Ok(Term::Bool(i >= j)),
408 (Binary::Equal | Binary::HeterogeneousEqual, Term::Date(i), Term::Date(j)) => {
409 Ok(Term::Bool(i == j))
410 }
411 (Binary::NotEqual | Binary::HeterogeneousNotEqual, Term::Date(i), Term::Date(j)) => {
412 Ok(Term::Bool(i != j))
413 }
414
415 (Binary::Equal | Binary::HeterogeneousEqual, Term::Bytes(i), Term::Bytes(j)) => {
419 Ok(Term::Bool(i == j))
420 }
421 (Binary::NotEqual | Binary::HeterogeneousNotEqual, Term::Bytes(i), Term::Bytes(j)) => {
422 Ok(Term::Bool(i != j))
423 }
424
425 (Binary::Equal | Binary::HeterogeneousEqual, Term::Set(set), Term::Set(s)) => {
427 Ok(Term::Bool(set == s))
428 } (Binary::NotEqual | Binary::HeterogeneousNotEqual, Term::Set(set), Term::Set(s)) => {
430 Ok(Term::Bool(set != s))
431 } (Binary::Intersection, Term::Set(set), Term::Set(s)) => {
433 Ok(Term::Set(set.intersection(&s).cloned().collect()))
434 }
435 (Binary::Union, Term::Set(set), Term::Set(s)) => {
436 Ok(Term::Set(set.union(&s).cloned().collect()))
437 }
438 (Binary::Contains, Term::Set(set), Term::Set(s)) => Ok(Term::Bool(set.is_superset(&s))),
439 (Binary::Contains, Term::Set(set), Term::Integer(i)) => {
440 Ok(Term::Bool(set.contains(&Term::Integer(i))))
441 }
442 (Binary::Contains, Term::Set(set), Term::Date(i)) => {
443 Ok(Term::Bool(set.contains(&Term::Date(i))))
444 }
445 (Binary::Contains, Term::Set(set), Term::Bool(i)) => {
446 Ok(Term::Bool(set.contains(&Term::Bool(i))))
447 }
448 (Binary::Contains, Term::Set(set), Term::Str(i)) => {
449 Ok(Term::Bool(set.contains(&Term::Str(i))))
450 }
451 (Binary::Contains, Term::Set(set), Term::Bytes(i)) => {
452 Ok(Term::Bool(set.contains(&Term::Bytes(i))))
453 }
454
455 (Binary::And, Term::Bool(i), Term::Bool(j)) => Ok(Term::Bool(i & j)),
457 (Binary::Or, Term::Bool(i), Term::Bool(j)) => Ok(Term::Bool(i | j)),
458 (Binary::Equal | Binary::HeterogeneousEqual, Term::Bool(i), Term::Bool(j)) => {
459 Ok(Term::Bool(i == j))
460 }
461 (Binary::NotEqual | Binary::HeterogeneousNotEqual, Term::Bool(i), Term::Bool(j)) => {
462 Ok(Term::Bool(i != j))
463 }
464
465 (Binary::Equal | Binary::HeterogeneousEqual, Term::Null, Term::Null) => {
467 Ok(Term::Bool(true))
468 }
469 (Binary::HeterogeneousEqual, Term::Null, _) => Ok(Term::Bool(false)),
470 (Binary::HeterogeneousEqual, _, Term::Null) => Ok(Term::Bool(false)),
471 (Binary::NotEqual | Binary::HeterogeneousNotEqual, Term::Null, Term::Null) => {
472 Ok(Term::Bool(false))
473 }
474 (Binary::HeterogeneousNotEqual, Term::Null, _) => Ok(Term::Bool(true)),
475 (Binary::HeterogeneousNotEqual, _, Term::Null) => Ok(Term::Bool(true)),
476
477 (Binary::Equal | Binary::HeterogeneousEqual, Term::Array(i), Term::Array(j)) => {
479 Ok(Term::Bool(i == j))
480 }
481 (Binary::NotEqual | Binary::HeterogeneousNotEqual, Term::Array(i), Term::Array(j)) => {
482 Ok(Term::Bool(i != j))
483 }
484 (Binary::Contains, Term::Array(i), j) => {
485 Ok(Term::Bool(i.iter().any(|elem| elem == &j)))
486 }
487 (Binary::Prefix, Term::Array(i), Term::Array(j)) => Ok(Term::Bool(i.starts_with(&j))),
488 (Binary::Suffix, Term::Array(i), Term::Array(j)) => Ok(Term::Bool(i.ends_with(&j))),
489 (Binary::Get, Term::Array(i), Term::Integer(index)) => Ok(TryFrom::try_from(index)
490 .ok()
491 .and_then(|index: usize| i.get(index).cloned())
492 .unwrap_or(Term::Null)),
493
494 (Binary::Equal | Binary::HeterogeneousEqual, Term::Map(i), Term::Map(j)) => {
496 Ok(Term::Bool(i == j))
497 }
498 (Binary::NotEqual | Binary::HeterogeneousNotEqual, Term::Map(i), Term::Map(j)) => {
499 Ok(Term::Bool(i != j))
500 }
501 (Binary::Contains, Term::Map(i), j) => {
502 Ok(Term::Bool(i.iter().any(|elem| match (elem.0, &j) {
503 (super::MapKey::Integer(k), Term::Integer(l)) => k == l,
504 (super::MapKey::Str(k), Term::Str(l)) => k == l,
505 _ => false,
506 })))
507 }
508 (Binary::Get, Term::Map(m), Term::Integer(i)) => match m.get(&MapKey::Integer(i)) {
509 Some(term) => Ok(term.clone()),
510 None => Ok(Term::Null),
511 },
512 (Binary::Get, Term::Map(m), Term::Str(i)) => match m.get(&MapKey::Str(i)) {
513 Some(term) => Ok(term.clone()),
514 None => Ok(Term::Null),
515 },
516
517 (Binary::HeterogeneousEqual, _, _) => Ok(Term::Bool(false)),
519 (Binary::HeterogeneousNotEqual, _, _) => Ok(Term::Bool(true)),
520
521 (Binary::Ffi(name), left, right) => {
523 let name = symbols
524 .get_symbol(*name)
525 .ok_or(error::Expression::UnknownSymbol(*name))?
526 .to_owned();
527 let fun = extern_funcs
528 .get(&name)
529 .ok_or(error::Expression::UndefinedExtern(name.to_owned()))?;
530 fun.call(symbols, &name, left, Some(right))
531 }
532
533 _ => {
534 Err(error::Expression::InvalidType)
536 }
537 }
538 }
539
540 pub fn print(&self, left: String, right: String, symbols: &SymbolTable) -> String {
541 match self {
542 Binary::LessThan => format!("{} < {}", left, right),
543 Binary::GreaterThan => format!("{} > {}", left, right),
544 Binary::LessOrEqual => format!("{} <= {}", left, right),
545 Binary::GreaterOrEqual => format!("{} >= {}", left, right),
546 Binary::Equal => format!("{} === {}", left, right),
547 Binary::HeterogeneousEqual => format!("{} == {}", left, right),
548 Binary::NotEqual => format!("{} !== {}", left, right),
549 Binary::HeterogeneousNotEqual => format!("{} != {}", left, right),
550 Binary::Contains => format!("{}.contains({})", left, right),
551 Binary::Prefix => format!("{}.starts_with({})", left, right),
552 Binary::Suffix => format!("{}.ends_with({})", left, right),
553 Binary::Regex => format!("{}.matches({})", left, right),
554 Binary::Add => format!("{} + {}", left, right),
555 Binary::Sub => format!("{} - {}", left, right),
556 Binary::Mul => format!("{} * {}", left, right),
557 Binary::Div => format!("{} / {}", left, right),
558 Binary::And => format!("{} &&! {}", left, right),
559 Binary::Or => format!("{} ||! {}", left, right),
560 Binary::Intersection => format!("{}.intersection({})", left, right),
561 Binary::Union => format!("{}.union({})", left, right),
562 Binary::BitwiseAnd => format!("{} & {}", left, right),
563 Binary::BitwiseOr => format!("{} | {}", left, right),
564 Binary::BitwiseXor => format!("{} ^ {}", left, right),
565 Binary::LazyAnd => format!("{left} && {right}"),
566 Binary::LazyOr => format!("{left} || {right}"),
567 Binary::All => format!("{left}.all({right})"),
568 Binary::Any => format!("{left}.any({right})"),
569 Binary::Get => format!("{left}.get({right})"),
570 Binary::Ffi(name) => format!(
571 "{left}.extern::{}({right})",
572 symbols.print_symbol_default(*name)
573 ),
574 Binary::TryOr => format!("{left}.try_or({right})"),
575 }
576 }
577}
578
579#[derive(Clone, Debug)]
580enum StackElem {
581 Closure(Vec<u32>, Vec<Op>),
582 Term(Term),
583}
584
585impl Expression {
586 pub fn evaluate(
587 &self,
588 values: &HashMap<u32, Term>,
589 symbols: &mut TemporarySymbolTable,
590 extern_funcs: &HashMap<String, ExternFunc>,
591 ) -> Result<Term, error::Expression> {
592 let mut stack: Vec<StackElem> = Vec::new();
593
594 for op in self.ops.iter() {
595 match op {
598 Op::Value(Term::Variable(i)) => match values.get(i) {
599 Some(term) => stack.push(StackElem::Term(term.clone())),
600 None => {
601 return Err(error::Expression::UnknownVariable(*i));
603 }
604 },
605 Op::Value(term) => stack.push(StackElem::Term(term.clone())),
606 Op::Unary(unary) => {
607 match stack.pop() {
608 Some(StackElem::Term(term)) => stack.push(StackElem::Term(
609 unary.evaluate(term, symbols, extern_funcs)?,
610 )),
611 _ => {
612 return Err(error::Expression::InvalidStack);
613 }
614 }
615 }
616 Op::Binary(binary) => match (stack.pop(), stack.pop()) {
617 (Some(StackElem::Term(right_term)), Some(StackElem::Term(left_term))) => stack
618 .push(StackElem::Term(binary.evaluate(
619 left_term,
620 right_term,
621 symbols,
622 extern_funcs,
623 )?)),
624 (
625 Some(StackElem::Closure(params, right_ops)),
626 Some(StackElem::Term(left_term)),
627 ) => {
628 if values
629 .keys()
630 .collect::<HashSet<_>>()
631 .intersection(¶ms.iter().collect())
632 .next()
633 .is_some()
634 {
635 return Err(error::Expression::ShadowedVariable);
636 }
637 let mut values = values.clone();
638 stack.push(StackElem::Term(binary.evaluate_with_closure(
639 left_term,
640 right_ops,
641 ¶ms,
642 &mut values,
643 symbols,
644 extern_funcs,
645 )?))
646 }
647 (
648 Some(StackElem::Term(right_term)),
649 Some(StackElem::Closure(params, left_ops)),
650 ) => {
651 if values
652 .keys()
653 .collect::<HashSet<_>>()
654 .intersection(¶ms.iter().collect())
655 .next()
656 .is_some()
657 {
658 return Err(error::Expression::ShadowedVariable);
659 }
660 let mut values = values.clone();
661 stack.push(StackElem::Term(binary.evaluate_with_closure(
662 right_term,
663 left_ops,
664 ¶ms,
665 &mut values,
666 symbols,
667 extern_funcs,
668 )?))
669 }
670
671 _ => {
672 return Err(error::Expression::InvalidStack);
673 }
674 },
675 Op::Closure(params, ops) => {
676 stack.push(StackElem::Closure(params.clone(), ops.clone()));
677 }
678 }
679 }
680
681 if stack.len() == 1 {
682 match stack.remove(0) {
683 StackElem::Term(t) => Ok(t),
684 _ => Err(error::Expression::InvalidStack),
685 }
686 } else {
687 Err(error::Expression::InvalidStack)
688 }
689 }
690
691 pub fn print(&self, symbols: &SymbolTable) -> Option<String> {
692 let mut stack: Vec<String> = Vec::new();
693
694 for op in self.ops.iter() {
695 match op {
697 Op::Value(i) => stack.push(symbols.print_term(i)),
698 Op::Unary(unary) => match stack.pop() {
699 None => return None,
700 Some(s) => stack.push(unary.print(s, symbols)),
701 },
702 Op::Binary(binary) => match (stack.pop(), stack.pop()) {
703 (Some(right), Some(left)) => stack.push(binary.print(left, right, symbols)),
704 _ => return None,
705 },
706 Op::Closure(params, ops) => {
707 let exp_body = Expression { ops: ops.clone() };
708 let body = match exp_body.print(symbols) {
709 Some(c) => c,
710 _ => return None,
711 };
712
713 if params.is_empty() {
714 stack.push(body);
715 } else {
716 let param_group = params
717 .iter()
718 .map(|s| symbols.print_term(&Term::Variable(*s)))
719 .collect::<Vec<_>>()
720 .join(", ");
721 stack.push(format!("{param_group} -> {body}"));
722 }
723 }
724 }
725 }
726
727 if stack.len() == 1 {
728 Some(stack.remove(0))
729 } else {
730 None
731 }
732 }
733}
734
735#[cfg(test)]
736mod tests {
737 use std::collections::{BTreeMap, BTreeSet};
738
739 use super::*;
740 use crate::datalog::{MapKey, SymbolTable, TemporarySymbolTable};
741
742 #[test]
743 fn negate() {
744 let mut symbols = SymbolTable::new();
745 symbols.insert("test1");
746 symbols.insert("test2");
747 symbols.insert("var1");
748 let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
749
750 let ops = vec![
751 Op::Value(Term::Integer(1)),
752 Op::Value(Term::Variable(2)),
753 Op::Binary(Binary::LessThan),
754 Op::Unary(Unary::Parens),
755 Op::Unary(Unary::Negate),
756 ];
757
758 let values: HashMap<u32, Term> = [(2, Term::Integer(0))].iter().cloned().collect();
759
760 println!("ops: {:?}", ops);
761
762 let e = Expression { ops };
763 println!("print: {}", e.print(&symbols).unwrap());
764
765 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
766 assert_eq!(res, Ok(Term::Bool(true)));
767 }
768
769 #[test]
770 fn bitwise() {
771 for (op, v1, v2, expected) in [
772 (Binary::BitwiseAnd, 9, 10, 8),
773 (Binary::BitwiseAnd, 9, 1, 1),
774 (Binary::BitwiseAnd, 9, 0, 0),
775 (Binary::BitwiseOr, 1, 2, 3),
776 (Binary::BitwiseOr, 2, 2, 2),
777 (Binary::BitwiseOr, 2, 0, 2),
778 (Binary::BitwiseXor, 1, 0, 1),
779 (Binary::BitwiseXor, 1, 1, 0),
780 ] {
781 let symbols = SymbolTable::new();
782 let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
783
784 let ops = vec![
785 Op::Value(Term::Integer(v1)),
786 Op::Value(Term::Integer(v2)),
787 Op::Binary(op),
788 ];
789
790 println!("ops: {:?}", ops);
791
792 let e = Expression { ops };
793 println!("print: {}", e.print(&symbols).unwrap());
794
795 let res = e.evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default());
796 assert_eq!(res, Ok(Term::Integer(expected)));
797 }
798 }
799
800 #[test]
801 fn checked() {
802 let symbols = SymbolTable::new();
803 let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
804 let ops = vec![
805 Op::Value(Term::Integer(1)),
806 Op::Value(Term::Integer(0)),
807 Op::Binary(Binary::Div),
808 ];
809
810 let values = HashMap::new();
811 let e = Expression { ops };
812 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
813 assert_eq!(res, Err(error::Expression::DivideByZero));
814
815 let ops = vec![
816 Op::Value(Term::Integer(1)),
817 Op::Value(Term::Integer(i64::MAX)),
818 Op::Binary(Binary::Add),
819 ];
820
821 let values = HashMap::new();
822 let e = Expression { ops };
823 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
824 assert_eq!(res, Err(error::Expression::Overflow));
825
826 let ops = vec![
827 Op::Value(Term::Integer(-10)),
828 Op::Value(Term::Integer(i64::MAX)),
829 Op::Binary(Binary::Sub),
830 ];
831
832 let values = HashMap::new();
833 let e = Expression { ops };
834 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
835 assert_eq!(res, Err(error::Expression::Overflow));
836
837 let ops = vec![
838 Op::Value(Term::Integer(2)),
839 Op::Value(Term::Integer(i64::MAX)),
840 Op::Binary(Binary::Mul),
841 ];
842
843 let values = HashMap::new();
844 let e = Expression { ops };
845 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
846 assert_eq!(res, Err(error::Expression::Overflow));
847 }
848
849 #[test]
850 fn printer() {
851 let mut symbols = SymbolTable::new();
852 symbols.insert("test1");
853 symbols.insert("test2");
854 symbols.insert("var1");
855
856 let ops1 = vec![
857 Op::Value(Term::Integer(-1)),
858 Op::Value(Term::Variable(1026)),
859 Op::Binary(Binary::LessThan),
860 ];
861
862 let ops2 = vec![
863 Op::Value(Term::Integer(1)),
864 Op::Value(Term::Integer(2)),
865 Op::Value(Term::Integer(3)),
866 Op::Binary(Binary::Add),
867 Op::Binary(Binary::LessThan),
868 ];
869
870 let ops3 = vec![
871 Op::Value(Term::Integer(1)),
872 Op::Value(Term::Integer(2)),
873 Op::Binary(Binary::Add),
874 Op::Value(Term::Integer(3)),
875 Op::Binary(Binary::LessThan),
876 ];
877
878 println!("ops1: {:?}", ops1);
879 println!("ops2: {:?}", ops2);
880 println!("ops3: {:?}", ops3);
881 let e1 = Expression { ops: ops1 };
882 let e2 = Expression { ops: ops2 };
883 let e3 = Expression { ops: ops3 };
884
885 assert_eq!(e1.print(&symbols).unwrap(), "-1 < $var1");
886
887 assert_eq!(e2.print(&symbols).unwrap(), "1 < 2 + 3");
888
889 assert_eq!(e3.print(&symbols).unwrap(), "1 + 2 < 3");
890 }
892
893 #[test]
894 fn null_equal() {
895 let symbols = SymbolTable::new();
896 let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
897 let values: HashMap<u32, Term> = HashMap::new();
898 let operands = vec![Op::Value(Term::Null), Op::Value(Term::Null)];
899 let operators = vec![
900 Op::Binary(Binary::Equal),
901 Op::Binary(Binary::HeterogeneousEqual),
902 ];
903
904 for op in operators {
905 let mut ops = operands.clone();
906 ops.push(op);
907 println!("ops: {:?}", ops);
908
909 let e = Expression { ops };
910 println!("print: {}", e.print(&symbols).unwrap());
911
912 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
913 assert_eq!(res, Ok(Term::Bool(true)));
914 }
915 }
916
917 #[test]
918 fn null_not_equal() {
919 let symbols = SymbolTable::new();
920 let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
921 let values: HashMap<u32, Term> = HashMap::new();
922 let operands = vec![Op::Value(Term::Null), Op::Value(Term::Null)];
923 let operators = vec![
924 Op::Binary(Binary::NotEqual),
925 Op::Binary(Binary::HeterogeneousNotEqual),
926 ];
927
928 for op in operators {
929 let mut ops = operands.clone();
930 ops.push(op);
931 println!("ops: {:?}", ops);
932
933 let e = Expression { ops };
934 println!("print: {}", e.print(&symbols).unwrap());
935
936 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
937 assert_eq!(res, Ok(Term::Bool(false)));
938 }
939 }
940
941 #[test]
942 fn null_heterogeneous() {
943 let symbols = SymbolTable::new();
944 let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
945 let values: HashMap<u32, Term> = HashMap::new();
946 let operands = vec![Op::Value(Term::Null), Op::Value(Term::Integer(1))];
947 let operators = HashMap::from([
948 (Op::Binary(Binary::HeterogeneousNotEqual), true),
949 (Op::Binary(Binary::HeterogeneousEqual), false),
950 ]);
951
952 for (op, result) in operators {
953 let mut ops = operands.clone();
954 ops.push(op);
955 println!("ops: {:?}", ops);
956
957 let e = Expression { ops };
958 println!("print: {}", e.print(&symbols).unwrap());
959
960 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
961 assert_eq!(res, Ok(Term::Bool(result)));
962 }
963 }
964
965 #[test]
966 fn equal_heterogeneous() {
967 let symbols = SymbolTable::new();
968 let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
969 let values: HashMap<u32, Term> = HashMap::new();
970 let operands_samples = [
971 vec![Op::Value(Term::Bool(true)), Op::Value(Term::Integer(1))],
972 vec![Op::Value(Term::Bool(true)), Op::Value(Term::Str(1))],
973 vec![Op::Value(Term::Integer(1)), Op::Value(Term::Str(1))],
974 vec![
975 Op::Value(Term::Set(BTreeSet::from([Term::Integer(1)]))),
976 Op::Value(Term::Set(BTreeSet::from([Term::Str(1)]))),
977 ],
978 vec![
979 Op::Value(Term::Bytes(Vec::new())),
980 Op::Value(Term::Integer(1)),
981 ],
982 vec![
983 Op::Value(Term::Bytes(Vec::new())),
984 Op::Value(Term::Str(1025)),
985 ],
986 vec![Op::Value(Term::Date(12)), Op::Value(Term::Integer(1))],
987 ];
988 let operators = HashMap::from([
989 (Op::Binary(Binary::HeterogeneousNotEqual), true),
990 (Op::Binary(Binary::HeterogeneousEqual), false),
991 ]);
992
993 for operands in operands_samples {
994 let operands_reversed: Vec<_> = operands.iter().cloned().rev().collect();
995 for operand in [operands, operands_reversed] {
996 for (op, result) in &operators {
997 let mut ops = operand.clone();
998 ops.push(op.clone());
999 println!("ops: {:?}", ops);
1000
1001 let e = Expression { ops };
1002 println!("print: {}", e.print(&symbols).unwrap());
1003
1004 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1005 assert_eq!(res, Ok(Term::Bool(*result)));
1006 }
1007 }
1008 }
1009 }
1010
1011 #[test]
1012 fn strict_equal_heterogeneous() {
1013 let symbols = SymbolTable::new();
1014 let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1015 let values: HashMap<u32, Term> = HashMap::new();
1016 let operands_samples = [
1017 vec![Op::Value(Term::Bool(true)), Op::Value(Term::Integer(1))],
1018 vec![Op::Value(Term::Bool(true)), Op::Value(Term::Str(1))],
1019 vec![Op::Value(Term::Integer(1)), Op::Value(Term::Str(1))],
1020 vec![
1021 Op::Value(Term::Bytes(Vec::new())),
1022 Op::Value(Term::Integer(1)),
1023 ],
1024 vec![
1025 Op::Value(Term::Bytes(Vec::new())),
1026 Op::Value(Term::Str(1025)),
1027 ],
1028 vec![Op::Value(Term::Date(12)), Op::Value(Term::Integer(1))],
1029 ];
1030 let operators = vec![Op::Binary(Binary::NotEqual), Op::Binary(Binary::Equal)];
1031
1032 for operands in operands_samples {
1033 let operands_reversed: Vec<_> = operands.iter().cloned().rev().collect();
1034 for operand in [operands, operands_reversed] {
1035 for op in &operators {
1036 let mut ops = operand.clone();
1037 ops.push(op.clone());
1038 println!("ops: {:?}", ops);
1039
1040 let e = Expression { ops };
1041 println!("print: {}", e.print(&symbols).unwrap());
1042
1043 e.evaluate(&values, &mut tmp_symbols, &Default::default())
1044 .unwrap_err();
1045 }
1046 }
1047 }
1048 }
1049
1050 #[test]
1051 fn laziness() {
1052 let symbols = SymbolTable::new();
1053 let mut symbols = TemporarySymbolTable::new(&symbols);
1054
1055 let ops1 = vec![
1056 Op::Value(Term::Bool(false)),
1057 Op::Closure(
1058 vec![],
1059 vec![
1060 Op::Value(Term::Bool(true)),
1061 Op::Closure(vec![], vec![Op::Value(Term::Bool(true))]),
1062 Op::Binary(Binary::LazyAnd),
1063 ],
1064 ),
1065 Op::Binary(Binary::LazyOr),
1066 ];
1067 let e2 = Expression { ops: ops1 };
1068
1069 let res2 = e2
1070 .evaluate(&HashMap::new(), &mut symbols, &Default::default())
1071 .unwrap();
1072 assert_eq!(res2, Term::Bool(true));
1073 }
1074
1075 #[test]
1076 fn any() {
1077 let mut symbols = SymbolTable::new();
1078 let p = symbols.insert("param") as u32;
1079 let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1080
1081 let ops1 = vec![
1082 Op::Value(Term::Set([Term::Bool(false), Term::Bool(true)].into())),
1083 Op::Closure(vec![p], vec![Op::Value(Term::Variable(p))]),
1084 Op::Binary(Binary::Any),
1085 ];
1086 let e1 = Expression { ops: ops1 };
1087 println!("{:?}", e1.print(&symbols));
1088
1089 let res1 = e1
1090 .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1091 .unwrap();
1092 assert_eq!(res1, Term::Bool(true));
1093
1094 let ops2 = vec![
1095 Op::Value(Term::Set([Term::Integer(1), Term::Integer(2)].into())),
1096 Op::Closure(
1097 vec![p],
1098 vec![
1099 Op::Value(Term::Variable(p)),
1100 Op::Value(Term::Integer(0)),
1101 Op::Binary(Binary::LessThan),
1102 ],
1103 ),
1104 Op::Binary(Binary::Any),
1105 ];
1106 let e2 = Expression { ops: ops2 };
1107 println!("{:?}", e2.print(&symbols));
1108
1109 let res2 = e2
1110 .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1111 .unwrap();
1112 assert_eq!(res2, Term::Bool(false));
1113
1114 let ops3 = vec![
1115 Op::Value(Term::Set([Term::Integer(1), Term::Integer(2)].into())),
1116 Op::Closure(vec![p], vec![Op::Value(Term::Integer(0))]),
1117 Op::Binary(Binary::Any),
1118 ];
1119 let e3 = Expression { ops: ops3 };
1120 println!("{:?}", e3.print(&symbols));
1121
1122 let err3 = e3
1123 .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1124 .unwrap_err();
1125 assert_eq!(err3, error::Expression::InvalidType);
1126 }
1127
1128 #[test]
1129 fn all() {
1130 let mut symbols = SymbolTable::new();
1131 let p = symbols.insert("param") as u32;
1132 let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1133
1134 let ops1 = vec![
1135 Op::Value(Term::Set([Term::Integer(1), Term::Integer(2)].into())),
1136 Op::Closure(
1137 vec![p],
1138 vec![
1139 Op::Value(Term::Variable(p)),
1140 Op::Value(Term::Integer(0)),
1141 Op::Binary(Binary::GreaterThan),
1142 ],
1143 ),
1144 Op::Binary(Binary::All),
1145 ];
1146 let e1 = Expression { ops: ops1 };
1147 println!("{:?}", e1.print(&symbols));
1148
1149 let res1 = e1
1150 .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1151 .unwrap();
1152 assert_eq!(res1, Term::Bool(true));
1153
1154 let ops2 = vec![
1155 Op::Value(Term::Set([Term::Integer(1), Term::Integer(2)].into())),
1156 Op::Closure(
1157 vec![p],
1158 vec![
1159 Op::Value(Term::Variable(p)),
1160 Op::Value(Term::Integer(0)),
1161 Op::Binary(Binary::LessThan),
1162 ],
1163 ),
1164 Op::Binary(Binary::All),
1165 ];
1166 let e2 = Expression { ops: ops2 };
1167 println!("{:?}", e2.print(&symbols));
1168
1169 let res2 = e2
1170 .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1171 .unwrap();
1172 assert_eq!(res2, Term::Bool(false));
1173
1174 let ops3 = vec![
1175 Op::Value(Term::Set([Term::Integer(1), Term::Integer(2)].into())),
1176 Op::Closure(vec![p], vec![Op::Value(Term::Integer(0))]),
1177 Op::Binary(Binary::All),
1178 ];
1179 let e3 = Expression { ops: ops3 };
1180 println!("{:?}", e3.print(&symbols));
1181
1182 let err3 = e3
1183 .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1184 .unwrap_err();
1185 assert_eq!(err3, error::Expression::InvalidType);
1186 }
1187
1188 #[test]
1189 fn nested_closures() {
1190 let mut symbols = SymbolTable::new();
1191 let p = symbols.insert("p") as u32;
1192 let q = symbols.insert("q") as u32;
1193 let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1194
1195 let ops1 = vec![
1196 Op::Value(Term::Set(
1197 [Term::Integer(1), Term::Integer(2), Term::Integer(3)].into(),
1198 )),
1199 Op::Closure(
1200 vec![p],
1201 vec![
1202 Op::Value(Term::Variable(p)),
1203 Op::Value(Term::Integer(1)),
1204 Op::Binary(Binary::GreaterThan),
1205 Op::Closure(
1206 vec![],
1207 vec![
1208 Op::Value(Term::Set(
1209 [Term::Integer(3), Term::Integer(4), Term::Integer(5)].into(),
1210 )),
1211 Op::Closure(
1212 vec![q],
1213 vec![
1214 Op::Value(Term::Variable(p)),
1215 Op::Value(Term::Variable(q)),
1216 Op::Binary(Binary::Equal),
1217 ],
1218 ),
1219 Op::Binary(Binary::Any),
1220 ],
1221 ),
1222 Op::Binary(Binary::LazyAnd),
1223 ],
1224 ),
1225 Op::Binary(Binary::Any),
1226 ];
1227 let e1 = Expression { ops: ops1 };
1228 println!("{}", e1.print(&symbols).unwrap());
1229
1230 let res1 = e1
1231 .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1232 .unwrap();
1233 assert_eq!(res1, Term::Bool(true));
1234 }
1235
1236 #[test]
1237 fn variable_shadowing() {
1238 let mut symbols = SymbolTable::new();
1239 let p = symbols.insert("param") as u32;
1240 let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1241
1242 let ops1 = vec![
1243 Op::Value(Term::Set([Term::Integer(1), Term::Integer(2)].into())),
1244 Op::Closure(
1245 vec![p],
1246 vec![
1247 Op::Value(Term::Variable(p)),
1248 Op::Value(Term::Integer(0)),
1249 Op::Binary(Binary::GreaterThan),
1250 ],
1251 ),
1252 Op::Binary(Binary::All),
1253 ];
1254 let e1 = Expression { ops: ops1 };
1255 println!("{:?}", e1.print(&symbols));
1256
1257 let mut values = HashMap::new();
1258 values.insert(p, Term::Null);
1259 let res1 = e1.evaluate(&values, &mut tmp_symbols, &Default::default());
1260 assert_eq!(res1, Err(error::Expression::ShadowedVariable));
1261
1262 let mut symbols = SymbolTable::new();
1263 let p = symbols.insert("p") as u32;
1264 let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1265
1266 let ops2 = vec![
1267 Op::Value(Term::Set(
1268 [Term::Integer(1), Term::Integer(2), Term::Integer(3)].into(),
1269 )),
1270 Op::Closure(
1271 vec![p],
1272 vec![
1273 Op::Value(Term::Variable(p)),
1274 Op::Value(Term::Integer(1)),
1275 Op::Binary(Binary::GreaterThan),
1276 Op::Closure(
1277 vec![],
1278 vec![
1279 Op::Value(Term::Set(
1280 [Term::Integer(3), Term::Integer(4), Term::Integer(5)].into(),
1281 )),
1282 Op::Closure(
1283 vec![p],
1284 vec![
1285 Op::Value(Term::Variable(p)),
1286 Op::Value(Term::Variable(p)),
1287 Op::Binary(Binary::Equal),
1288 ],
1289 ),
1290 Op::Binary(Binary::Any),
1291 ],
1292 ),
1293 Op::Binary(Binary::LazyAnd),
1294 ],
1295 ),
1296 Op::Binary(Binary::Any),
1297 ];
1298 let e2 = Expression { ops: ops2 };
1299 println!("{}", e2.print(&symbols).unwrap());
1300
1301 let res2 = e2.evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default());
1302 assert_eq!(res2, Err(error::Expression::ShadowedVariable));
1303 }
1304
1305 #[test]
1306 fn array() {
1307 let symbols = SymbolTable::new();
1308 let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1309 let ops = vec![
1310 Op::Value(Term::Array(vec![Term::Integer(0), Term::Integer(1)])),
1311 Op::Value(Term::Array(vec![Term::Integer(0), Term::Integer(1)])),
1312 Op::Binary(Binary::Equal),
1313 ];
1314
1315 let values = HashMap::new();
1316 let e = Expression { ops };
1317 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1318 assert_eq!(res, Ok(Term::Bool(true)));
1319
1320 let ops = vec![
1321 Op::Value(Term::Array(vec![Term::Integer(0), Term::Integer(1)])),
1322 Op::Value(Term::Array(vec![Term::Integer(0)])),
1323 Op::Binary(Binary::Equal),
1324 ];
1325
1326 let values = HashMap::new();
1327 let e = Expression { ops };
1328 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1329 assert_eq!(res, Ok(Term::Bool(false)));
1330
1331 let ops = vec![
1332 Op::Value(Term::Array(vec![Term::Integer(0), Term::Integer(1)])),
1333 Op::Value(Term::Integer(1)),
1334 Op::Binary(Binary::Contains),
1335 ];
1336
1337 let values = HashMap::new();
1338 let e = Expression { ops };
1339 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1340 assert_eq!(res, Ok(Term::Bool(true)));
1341
1342 let ops = vec![
1343 Op::Value(Term::Array(vec![Term::Integer(0), Term::Integer(1)])),
1344 Op::Value(Term::Integer(2)),
1345 Op::Binary(Binary::Contains),
1346 ];
1347
1348 let values = HashMap::new();
1349 let e = Expression { ops };
1350 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1351 assert_eq!(res, Ok(Term::Bool(false)));
1352
1353 let ops = vec![
1354 Op::Value(Term::Array(vec![
1355 Term::Integer(0),
1356 Term::Integer(1),
1357 Term::Integer(2),
1358 ])),
1359 Op::Value(Term::Array(vec![Term::Integer(0), Term::Integer(1)])),
1360 Op::Binary(Binary::Prefix),
1361 ];
1362
1363 let values = HashMap::new();
1364 let e = Expression { ops };
1365 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1366 assert_eq!(res, Ok(Term::Bool(true)));
1367
1368 let ops = vec![
1369 Op::Value(Term::Array(vec![
1370 Term::Integer(0),
1371 Term::Integer(1),
1372 Term::Integer(2),
1373 ])),
1374 Op::Value(Term::Array(vec![Term::Integer(2), Term::Integer(1)])),
1375 Op::Binary(Binary::Prefix),
1376 ];
1377
1378 let values = HashMap::new();
1379 let e = Expression { ops };
1380 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1381 assert_eq!(res, Ok(Term::Bool(false)));
1382
1383 let ops = vec![
1384 Op::Value(Term::Array(vec![
1385 Term::Integer(0),
1386 Term::Integer(1),
1387 Term::Integer(2),
1388 ])),
1389 Op::Value(Term::Array(vec![Term::Integer(1), Term::Integer(2)])),
1390 Op::Binary(Binary::Suffix),
1391 ];
1392
1393 let values = HashMap::new();
1394 let e = Expression { ops };
1395 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1396 assert_eq!(res, Ok(Term::Bool(true)));
1397
1398 let ops = vec![
1399 Op::Value(Term::Array(vec![
1400 Term::Integer(0),
1401 Term::Integer(1),
1402 Term::Integer(2),
1403 ])),
1404 Op::Value(Term::Array(vec![Term::Integer(0), Term::Integer(2)])),
1405 Op::Binary(Binary::Suffix),
1406 ];
1407
1408 let values = HashMap::new();
1409 let e = Expression { ops };
1410 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1411 assert_eq!(res, Ok(Term::Bool(false)));
1412
1413 let ops = vec![
1415 Op::Value(Term::Array(vec![
1416 Term::Integer(0),
1417 Term::Integer(1),
1418 Term::Integer(2),
1419 ])),
1420 Op::Value(Term::Integer(1)),
1421 Op::Binary(Binary::Get),
1422 ];
1423
1424 let values = HashMap::new();
1425 let e = Expression { ops };
1426 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1427 assert_eq!(res, Ok(Term::Integer(1)));
1428
1429 let ops = vec![
1431 Op::Value(Term::Array(vec![
1432 Term::Integer(0),
1433 Term::Integer(1),
1434 Term::Integer(2),
1435 ])),
1436 Op::Value(Term::Integer(3)),
1437 Op::Binary(Binary::Get),
1438 ];
1439
1440 let values = HashMap::new();
1441 let e = Expression { ops };
1442 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1443 assert_eq!(res, Ok(Term::Null));
1444
1445 let p = tmp_symbols.insert("param") as u32;
1447 let ops1 = vec![
1448 Op::Value(Term::Array([Term::Integer(1), Term::Integer(2)].into())),
1449 Op::Closure(
1450 vec![p],
1451 vec![
1452 Op::Value(Term::Variable(p)),
1453 Op::Value(Term::Integer(0)),
1454 Op::Binary(Binary::GreaterThan),
1455 ],
1456 ),
1457 Op::Binary(Binary::All),
1458 ];
1459 let e1 = Expression { ops: ops1 };
1460 println!("{:?}", e1.print(&symbols));
1461
1462 let res1 = e1
1463 .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1464 .unwrap();
1465 assert_eq!(res1, Term::Bool(true));
1466
1467 let ops1 = vec![
1469 Op::Value(Term::Array([Term::Integer(1), Term::Integer(2)].into())),
1470 Op::Closure(
1471 vec![p],
1472 vec![
1473 Op::Value(Term::Variable(p)),
1474 Op::Value(Term::Integer(0)),
1475 Op::Binary(Binary::Equal),
1476 ],
1477 ),
1478 Op::Binary(Binary::Any),
1479 ];
1480 let e1 = Expression { ops: ops1 };
1481 println!("{:?}", e1.print(&symbols));
1482
1483 let res1 = e1
1484 .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1485 .unwrap();
1486 assert_eq!(res1, Term::Bool(false));
1487 }
1488
1489 #[test]
1490 fn map() {
1491 let mut symbols = SymbolTable::new();
1492 let p = symbols.insert("param") as u32;
1493 let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1494
1495 let ops = vec![
1496 Op::Value(Term::Map(
1497 [
1498 (MapKey::Str(1), Term::Integer(0)),
1499 (MapKey::Str(2), Term::Integer(1)),
1500 ]
1501 .iter()
1502 .cloned()
1503 .collect(),
1504 )),
1505 Op::Value(Term::Map(
1506 [
1507 (MapKey::Str(2), Term::Integer(1)),
1508 (MapKey::Str(1), Term::Integer(0)),
1509 ]
1510 .iter()
1511 .cloned()
1512 .collect(),
1513 )),
1514 Op::Binary(Binary::Equal),
1515 ];
1516
1517 let values = HashMap::new();
1518 let e = Expression { ops };
1519 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1520 assert_eq!(res, Ok(Term::Bool(true)));
1521
1522 let ops = vec![
1523 Op::Value(Term::Map(
1524 [
1525 (MapKey::Str(1), Term::Integer(0)),
1526 (MapKey::Str(2), Term::Integer(1)),
1527 ]
1528 .iter()
1529 .cloned()
1530 .collect(),
1531 )),
1532 Op::Value(Term::Map(
1533 [(MapKey::Str(1), Term::Integer(0))]
1534 .iter()
1535 .cloned()
1536 .collect(),
1537 )),
1538 Op::Binary(Binary::Equal),
1539 ];
1540
1541 let values = HashMap::new();
1542 let e = Expression { ops };
1543 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1544 assert_eq!(res, Ok(Term::Bool(false)));
1545
1546 let ops = vec![
1547 Op::Value(Term::Map(
1548 [
1549 (MapKey::Str(1), Term::Integer(0)),
1550 (MapKey::Str(2), Term::Integer(1)),
1551 ]
1552 .iter()
1553 .cloned()
1554 .collect(),
1555 )),
1556 Op::Value(Term::Str(1)),
1557 Op::Binary(Binary::Contains),
1558 ];
1559
1560 let values = HashMap::new();
1561 let e = Expression { ops };
1562 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1563 assert_eq!(res, Ok(Term::Bool(true)));
1564
1565 let ops = vec![
1566 Op::Value(Term::Map(
1567 [
1568 (MapKey::Str(1), Term::Integer(0)),
1569 (MapKey::Str(2), Term::Integer(1)),
1570 ]
1571 .iter()
1572 .cloned()
1573 .collect(),
1574 )),
1575 Op::Value(Term::Integer(0)),
1576 Op::Binary(Binary::Contains),
1577 ];
1578
1579 let values = HashMap::new();
1580 let e = Expression { ops };
1581 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1582 assert_eq!(res, Ok(Term::Bool(false)));
1583
1584 let ops = vec![
1586 Op::Value(Term::Map(
1587 [
1588 (MapKey::Str(1), Term::Integer(0)),
1589 (MapKey::Integer(2), Term::Integer(1)),
1590 ]
1591 .iter()
1592 .cloned()
1593 .collect(),
1594 )),
1595 Op::Value(Term::Str(1)),
1596 Op::Binary(Binary::Get),
1597 ];
1598
1599 let values = HashMap::new();
1600 let e = Expression { ops };
1601 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1602 assert_eq!(res, Ok(Term::Integer(0)));
1603
1604 let ops = vec![
1605 Op::Value(Term::Map(
1606 [
1607 (MapKey::Str(1), Term::Integer(0)),
1608 (MapKey::Integer(2), Term::Integer(1)),
1609 ]
1610 .iter()
1611 .cloned()
1612 .collect(),
1613 )),
1614 Op::Value(Term::Integer(2)),
1615 Op::Binary(Binary::Get),
1616 ];
1617
1618 let values = HashMap::new();
1619 let e = Expression { ops };
1620 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1621 assert_eq!(res, Ok(Term::Integer(1)));
1622
1623 let ops = vec![
1625 Op::Value(Term::Map(
1626 [
1627 (MapKey::Str(1), Term::Integer(0)),
1628 (MapKey::Str(2), Term::Integer(1)),
1629 ]
1630 .iter()
1631 .cloned()
1632 .collect(),
1633 )),
1634 Op::Value(Term::Integer(0)),
1635 Op::Binary(Binary::Get),
1636 ];
1637
1638 let values = HashMap::new();
1639 let e = Expression { ops };
1640 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1641 assert_eq!(res, Ok(Term::Null));
1642
1643 let ops = vec![
1644 Op::Value(Term::Map(
1645 [
1646 (MapKey::Str(1), Term::Integer(0)),
1647 (MapKey::Str(2), Term::Integer(1)),
1648 ]
1649 .iter()
1650 .cloned()
1651 .collect(),
1652 )),
1653 Op::Value(Term::Str(3)),
1654 Op::Binary(Binary::Get),
1655 ];
1656
1657 let values = HashMap::new();
1658 let e = Expression { ops };
1659 let res = e.evaluate(&values, &mut tmp_symbols, &Default::default());
1660 assert_eq!(res, Ok(Term::Null));
1661
1662 let ops1 = vec![
1664 Op::Value(Term::Map(
1665 [
1666 (MapKey::Str(1), Term::Integer(0)),
1667 (MapKey::Str(2), Term::Integer(1)),
1668 ]
1669 .iter()
1670 .cloned()
1671 .collect(),
1672 )),
1673 Op::Closure(
1674 vec![p],
1675 vec![
1676 Op::Value(Term::Variable(p)),
1677 Op::Value(Term::Integer(1)),
1678 Op::Binary(Binary::Get),
1679 Op::Value(Term::Integer(2)),
1680 Op::Binary(Binary::LessThan),
1681 ],
1682 ),
1683 Op::Binary(Binary::All),
1684 ];
1685 let e1 = Expression { ops: ops1 };
1686 println!("{:?}", e1.print(&symbols));
1687
1688 let res1 = e1
1689 .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1690 .unwrap();
1691 assert_eq!(res1, Term::Bool(true));
1692
1693 let ops1 = vec![
1695 Op::Value(Term::Map(
1696 [
1697 (MapKey::Str(1), Term::Integer(0)),
1698 (MapKey::Str(2), Term::Integer(1)),
1699 ]
1700 .iter()
1701 .cloned()
1702 .collect(),
1703 )),
1704 Op::Closure(
1705 vec![p],
1706 vec![
1707 Op::Value(Term::Variable(p)),
1708 Op::Value(Term::Integer(0)),
1709 Op::Binary(Binary::Get),
1710 Op::Value(Term::Str(1)),
1711 Op::Binary(Binary::Equal),
1712 ],
1713 ),
1714 Op::Binary(Binary::Any),
1715 ];
1716 let e1 = Expression { ops: ops1 };
1717 println!("{:?}", e1.print(&symbols));
1718
1719 let res1 = e1
1720 .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1721 .unwrap();
1722 assert_eq!(res1, Term::Bool(true));
1723 }
1724 #[test]
1725 fn ffi() {
1726 let mut symbols = SymbolTable::new();
1727 let i = symbols.insert("test");
1728 let j = symbols.insert("TeSt");
1729 let test_bin = symbols.insert("test_bin");
1730 let test_un = symbols.insert("test_un");
1731 let test_closure = symbols.insert("test_closure");
1732 let test_fn = symbols.insert("test_fn");
1733 let id_fn = symbols.insert("id");
1734 let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1735 let ops = vec![
1736 Op::Value(Term::Integer(60)),
1737 Op::Value(Term::Integer(0)),
1738 Op::Binary(Binary::Ffi(test_bin)),
1739 Op::Value(Term::Str(i)),
1740 Op::Value(Term::Str(j)),
1741 Op::Binary(Binary::Ffi(test_bin)),
1742 Op::Binary(Binary::And),
1743 Op::Value(Term::Integer(42)),
1744 Op::Unary(Unary::Ffi(test_un)),
1745 Op::Binary(Binary::And),
1746 Op::Value(Term::Integer(42)),
1747 Op::Unary(Unary::Ffi(test_closure)),
1748 Op::Binary(Binary::And),
1749 Op::Value(Term::Str(i)),
1750 Op::Unary(Unary::Ffi(test_closure)),
1751 Op::Binary(Binary::And),
1752 Op::Value(Term::Integer(42)),
1753 Op::Unary(Unary::Ffi(test_fn)),
1754 Op::Binary(Binary::And),
1755 Op::Value(Term::Integer(42)),
1756 Op::Unary(Unary::Ffi(id_fn)),
1757 Op::Value(Term::Integer(42)),
1758 Op::Binary(Binary::HeterogeneousEqual),
1759 Op::Binary(Binary::And),
1760 Op::Value(Term::Str(i)),
1761 Op::Unary(Unary::Ffi(id_fn)),
1762 Op::Value(Term::Str(i)),
1763 Op::Binary(Binary::HeterogeneousEqual),
1764 Op::Binary(Binary::And),
1765 Op::Value(Term::Bool(true)),
1766 Op::Unary(Unary::Ffi(id_fn)),
1767 Op::Value(Term::Bool(true)),
1768 Op::Binary(Binary::HeterogeneousEqual),
1769 Op::Binary(Binary::And),
1770 Op::Value(Term::Date(0)),
1771 Op::Unary(Unary::Ffi(id_fn)),
1772 Op::Value(Term::Date(0)),
1773 Op::Binary(Binary::HeterogeneousEqual),
1774 Op::Binary(Binary::And),
1775 Op::Value(Term::Bytes(vec![42])),
1776 Op::Unary(Unary::Ffi(id_fn)),
1777 Op::Value(Term::Bytes(vec![42])),
1778 Op::Binary(Binary::HeterogeneousEqual),
1779 Op::Binary(Binary::And),
1780 Op::Value(Term::Null),
1781 Op::Unary(Unary::Ffi(id_fn)),
1782 Op::Value(Term::Null),
1783 Op::Binary(Binary::HeterogeneousEqual),
1784 Op::Binary(Binary::And),
1785 Op::Value(Term::Array(vec![Term::Null])),
1786 Op::Unary(Unary::Ffi(id_fn)),
1787 Op::Value(Term::Array(vec![Term::Null])),
1788 Op::Binary(Binary::HeterogeneousEqual),
1789 Op::Binary(Binary::And),
1790 Op::Value(Term::Set(BTreeSet::from([Term::Null]))),
1791 Op::Unary(Unary::Ffi(id_fn)),
1792 Op::Value(Term::Set(BTreeSet::from([Term::Null]))),
1793 Op::Binary(Binary::HeterogeneousEqual),
1794 Op::Binary(Binary::And),
1795 Op::Value(Term::Map(BTreeMap::from([
1796 (MapKey::Integer(42), Term::Null),
1797 (MapKey::Str(i), Term::Null),
1798 ]))),
1799 Op::Unary(Unary::Ffi(id_fn)),
1800 Op::Value(Term::Map(BTreeMap::from([
1801 (MapKey::Integer(42), Term::Null),
1802 (MapKey::Str(i), Term::Null),
1803 ]))),
1804 Op::Binary(Binary::HeterogeneousEqual),
1805 Op::Binary(Binary::And),
1806 ];
1807
1808 let values = HashMap::new();
1809 let e = Expression { ops };
1810 let mut extern_funcs: HashMap<String, ExternFunc> = Default::default();
1811 extern_funcs.insert(
1812 "test_bin".to_owned(),
1813 ExternFunc::new(Arc::new(|left, right| match (left, right) {
1814 (builder::Term::Integer(left), Some(builder::Term::Integer(right))) => {
1815 println!("{left} {right}");
1816 Ok(builder::Term::Bool((left % 60) == (right % 60)))
1817 }
1818 (builder::Term::Str(left), Some(builder::Term::Str(right))) => {
1819 println!("{left} {right}");
1820 Ok(builder::Term::Bool(
1821 left.to_lowercase() == right.to_lowercase(),
1822 ))
1823 }
1824 _ => Err("Expected two strings or two integers".to_string()),
1825 })),
1826 );
1827 extern_funcs.insert(
1828 "test_un".to_owned(),
1829 ExternFunc::new(Arc::new(|left, right| match (&left, &right) {
1830 (builder::Term::Integer(left), None) => Ok(builder::boolean(*left == 42)),
1831 _ => {
1832 println!("{left:?}, {right:?}");
1833 Err("expecting a single integer".to_string())
1834 }
1835 })),
1836 );
1837 extern_funcs.insert(
1838 "id".to_string(),
1839 ExternFunc::new(Arc::new(|left, right| match (left, right) {
1840 (a, None) => Ok(a),
1841 _ => Err("expecting a single value".to_string()),
1842 })),
1843 );
1844 let closed_over_int = 42;
1845 let closed_over_string = "test".to_string();
1846 extern_funcs.insert(
1847 "test_closure".to_owned(),
1848 ExternFunc::new(Arc::new(move |left, right| match (&left, &right) {
1849 (builder::Term::Integer(left), None) => {
1850 Ok(builder::boolean(*left == closed_over_int))
1851 }
1852 (builder::Term::Str(left), None) => {
1853 Ok(builder::boolean(left == &closed_over_string))
1854 }
1855 _ => {
1856 println!("{left:?}, {right:?}");
1857 Err("expecting a single integer".to_string())
1858 }
1859 })),
1860 );
1861 extern_funcs.insert("test_fn".to_owned(), ExternFunc::new(Arc::new(toto)));
1862 let res = e.evaluate(&values, &mut tmp_symbols, &extern_funcs);
1863 assert_eq!(res, Ok(Term::Bool(true)));
1864 }
1865
1866 fn toto(_left: builder::Term, _right: Option<builder::Term>) -> Result<builder::Term, String> {
1867 Ok(builder::Term::Bool(true))
1868 }
1869
1870 #[test]
1871 fn try_op() {
1872 let symbols = SymbolTable::new();
1873 let mut tmp_symbols = TemporarySymbolTable::new(&symbols);
1874
1875 let ops1 = vec![
1876 Op::Closure(
1877 vec![],
1878 vec![
1879 Op::Value(Term::Bool(true)),
1880 Op::Value(Term::Integer(0)),
1881 Op::Binary(Binary::GreaterThan),
1882 Op::Unary(Unary::Parens),
1883 ],
1884 ),
1885 Op::Value(Term::Bool(false)),
1886 Op::Binary(Binary::TryOr),
1887 ];
1888 let e1 = Expression { ops: ops1 };
1889 println!("{:?}", e1.print(&symbols));
1890
1891 let res1 = e1
1892 .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1893 .unwrap();
1894 assert_eq!(res1, Term::Bool(false));
1895
1896 let ops2 = vec![
1897 Op::Closure(
1898 vec![],
1899 vec![
1900 Op::Value(Term::Integer(0)),
1901 Op::Value(Term::Integer(0)),
1902 Op::Binary(Binary::Equal),
1903 Op::Unary(Unary::Parens),
1904 ],
1905 ),
1906 Op::Value(Term::Bool(false)),
1907 Op::Binary(Binary::TryOr),
1908 ];
1909 let e2 = Expression { ops: ops2 };
1910 println!("{:?}", e2.print(&symbols));
1911
1912 let res2 = e2
1913 .evaluate(&HashMap::new(), &mut tmp_symbols, &Default::default())
1914 .unwrap();
1915 assert_eq!(res2, Term::Bool(true));
1916 }
1917}