Skip to content

Commit 65d8292

Browse files
Evaluate <, <=, > and >= operators (!40)
1 parent b4fe1bf commit 65d8292

File tree

2 files changed

+227
-6
lines changed

2 files changed

+227
-6
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Unreleased
44

5+
* enhance the `compute_expression` rule by processing `<`, `<=`, `>` and `>=` operators ([!40](https://gitlab.com/seaofvoices/darklua/-/merge_requests/40))
56
* enhance the `compute_expression` rule by processing parentheses expressions ([!39](https://gitlab.com/seaofvoices/darklua/-/merge_requests/39))
67
* add rule to convert index expression to field expression ([!36](https://gitlab.com/seaofvoices/darklua/-/merge_requests/36))
78
* add logging to time processing steps ([!35](https://gitlab.com/seaofvoices/darklua/-/merge_requests/35))

src/process/evaluator/mod.rs

+226-6
Original file line numberDiff line numberDiff line change
@@ -209,10 +209,12 @@ impl Evaluator {
209209
_ => LuaValue::Unknown,
210210
}
211211
}
212-
BinaryOperator::LowerThan
213-
| BinaryOperator::LowerOrEqualThan
214-
| BinaryOperator::GreaterThan
215-
| BinaryOperator::GreaterOrEqualThan => LuaValue::Unknown,
212+
BinaryOperator::LowerThan => self.evaluate_relational(expression, |a, b| a < b),
213+
BinaryOperator::LowerOrEqualThan => self.evaluate_relational(expression, |a, b| a <= b),
214+
BinaryOperator::GreaterThan => self.evaluate_relational(expression, |a, b| a > b),
215+
BinaryOperator::GreaterOrEqualThan => {
216+
self.evaluate_relational(expression, |a, b| a >= b)
217+
}
216218
}
217219
}
218220

@@ -249,6 +251,51 @@ impl Evaluator {
249251
}
250252
}
251253

254+
fn evaluate_relational<F>(&self, expression: &BinaryExpression, operation: F) -> LuaValue
255+
where
256+
F: Fn(f64, f64) -> bool,
257+
{
258+
let left = self.evaluate(expression.left());
259+
260+
match left {
261+
LuaValue::Number(left) => {
262+
let right = self.evaluate(expression.right());
263+
264+
if let LuaValue::Number(right) = right {
265+
if operation(left, right) {
266+
LuaValue::True
267+
} else {
268+
LuaValue::False
269+
}
270+
} else {
271+
LuaValue::Unknown
272+
}
273+
}
274+
LuaValue::String(left) => {
275+
let right = self.evaluate(expression.right());
276+
277+
if let LuaValue::String(right) = right {
278+
self.compare_strings(&left, &right, expression.operator())
279+
} else {
280+
LuaValue::Unknown
281+
}
282+
}
283+
_ => LuaValue::Unknown,
284+
}
285+
}
286+
287+
fn compare_strings(&self, left: &str, right: &str, operator: BinaryOperator) -> LuaValue {
288+
LuaValue::from(match operator {
289+
BinaryOperator::Equal => left == right,
290+
BinaryOperator::NotEqual => left != right,
291+
BinaryOperator::LowerThan => left < right,
292+
BinaryOperator::LowerOrEqualThan => left <= right,
293+
BinaryOperator::GreaterThan => left > right,
294+
BinaryOperator::GreaterOrEqualThan => left >= right,
295+
_ => return LuaValue::Unknown,
296+
})
297+
}
298+
252299
fn evaluate_unary(&self, expression: &UnaryExpression) -> LuaValue {
253300
match expression.operator() {
254301
UnaryOperator::Not => self
@@ -504,10 +551,30 @@ mod test {
504551
StringExpression::empty(),
505552
StringExpression::empty()
506553
) => LuaValue::from(""),
554+
number_lower_than_string(
555+
BinaryOperator::LowerThan,
556+
1.0,
557+
StringExpression::empty()
558+
) => LuaValue::Unknown,
559+
number_string_greater_than_number(
560+
BinaryOperator::GreaterThan,
561+
StringExpression::from_value("100"),
562+
1.0
563+
) => LuaValue::Unknown,
564+
number_string_greater_or_equal_than_number(
565+
BinaryOperator::GreaterOrEqualThan,
566+
StringExpression::from_value("100"),
567+
100.0
568+
) => LuaValue::Unknown,
569+
number_lower_or_equal_than_number_string(
570+
BinaryOperator::GreaterOrEqualThan,
571+
100.0,
572+
StringExpression::from_value("100")
573+
) => LuaValue::Unknown,
507574
);
508575

509576
macro_rules! evaluate_equality {
510-
($($name:ident ($left:expr, $right:expr) => $value:expr),*) => {
577+
($($name:ident ($left:expr, $right:expr) => $value:expr),* $(,)?) => {
511578
$(
512579
mod $name {
513580
use super::*;
@@ -580,7 +647,160 @@ mod test {
580647
different_strings(
581648
StringExpression::from_value("foo"),
582649
StringExpression::from_value("bar")
583-
) => LuaValue::False
650+
) => LuaValue::False,
651+
);
652+
653+
macro_rules! evaluate_equality_with_relational_operators {
654+
($($name:ident => $value:expr),* $(,)?) => {
655+
$(
656+
mod $name {
657+
use super::*;
658+
659+
#[test]
660+
fn lower() {
661+
let value: Expression = $value.into();
662+
let binary = BinaryExpression::new(BinaryOperator::LowerThan, value.clone(), value);
663+
assert_eq!(LuaValue::False, Evaluator::default().evaluate(&binary.into()));
664+
}
665+
666+
#[test]
667+
fn lower_or_equal() {
668+
let value: Expression = $value.into();
669+
let binary = BinaryExpression::new(BinaryOperator::LowerOrEqualThan, value.clone(), value);
670+
assert_eq!(LuaValue::True, Evaluator::default().evaluate(&binary.into()));
671+
}
672+
673+
#[test]
674+
fn greater() {
675+
let value: Expression = $value.into();
676+
let binary = BinaryExpression::new(BinaryOperator::GreaterThan, value.clone(), value);
677+
assert_eq!(LuaValue::False, Evaluator::default().evaluate(&binary.into()));
678+
}
679+
680+
#[test]
681+
fn greater_or_equal() {
682+
let value: Expression = $value.into();
683+
let binary = BinaryExpression::new(BinaryOperator::GreaterOrEqualThan, value.clone(), value);
684+
assert_eq!(LuaValue::True, Evaluator::default().evaluate(&binary.into()));
685+
}
686+
}
687+
)*
688+
};
689+
}
690+
691+
evaluate_equality_with_relational_operators!(
692+
zero => 1.0,
693+
one => 1.0,
694+
hundred => 100.0,
695+
string => StringExpression::from_value("var"),
696+
);
697+
698+
macro_rules! evaluate_strict_relational_operators {
699+
($($name_lower:ident($lower:expr) < $name_greater:ident($greater:expr)),* $(,)?) => {
700+
mod lower_or_greater_than {
701+
use super::*;
702+
paste::paste! {
703+
704+
$(
705+
#[test]
706+
fn [<$name_lower _lower_than_ $name_greater>]() {
707+
let binary = BinaryExpression::new(
708+
BinaryOperator::LowerThan,
709+
$lower,
710+
$greater,
711+
);
712+
assert_eq!(LuaValue::True, Evaluator::default().evaluate(&binary.into()));
713+
}
714+
715+
#[test]
716+
fn [<$name_lower _lower_or_equal_than_ $name_greater>]() {
717+
let binary = BinaryExpression::new(
718+
BinaryOperator::LowerOrEqualThan,
719+
$lower,
720+
$greater,
721+
);
722+
assert_eq!(LuaValue::True, Evaluator::default().evaluate(&binary.into()));
723+
}
724+
725+
#[test]
726+
fn [<$name_lower _greater_than_ $name_greater>]() {
727+
let binary = BinaryExpression::new(
728+
BinaryOperator::GreaterThan,
729+
$lower,
730+
$greater,
731+
);
732+
assert_eq!(LuaValue::False, Evaluator::default().evaluate(&binary.into()));
733+
}
734+
735+
#[test]
736+
fn [<$name_lower _greater_or_equal_than_ $name_greater>]() {
737+
let binary = BinaryExpression::new(
738+
BinaryOperator::GreaterOrEqualThan,
739+
$lower,
740+
$greater,
741+
);
742+
assert_eq!(LuaValue::False, Evaluator::default().evaluate(&binary.into()));
743+
}
744+
745+
#[test]
746+
fn [<$name_greater _lower_than_ $name_lower>]() {
747+
let binary = BinaryExpression::new(
748+
BinaryOperator::LowerThan,
749+
$greater,
750+
$lower,
751+
);
752+
assert_eq!(LuaValue::False, Evaluator::default().evaluate(&binary.into()));
753+
}
754+
755+
#[test]
756+
fn [<$name_greater _lower_or_equal_than_ $name_lower>]() {
757+
let binary = BinaryExpression::new(
758+
BinaryOperator::LowerOrEqualThan,
759+
$greater,
760+
$lower,
761+
);
762+
assert_eq!(LuaValue::False, Evaluator::default().evaluate(&binary.into()));
763+
}
764+
765+
#[test]
766+
fn [<$name_greater _greater_than_ $name_lower>]() {
767+
let binary = BinaryExpression::new(
768+
BinaryOperator::GreaterThan,
769+
$greater,
770+
$lower,
771+
);
772+
assert_eq!(LuaValue::True, Evaluator::default().evaluate(&binary.into()));
773+
}
774+
775+
#[test]
776+
fn [<$name_greater _greater_or_equal_than_ $name_lower>]() {
777+
let binary = BinaryExpression::new(
778+
BinaryOperator::GreaterOrEqualThan,
779+
$greater,
780+
$lower,
781+
);
782+
assert_eq!(LuaValue::True, Evaluator::default().evaluate(&binary.into()));
783+
}
784+
)*
785+
786+
}
787+
}
788+
};
789+
}
790+
791+
evaluate_strict_relational_operators!(
792+
one(1.0) < hundred(100.0),
793+
minus_15(-15.0) < minus_2_5(-2.5),
794+
string_a(StringExpression::from_value("a"))
795+
< string_b(StringExpression::from_value("b")),
796+
string_a(StringExpression::from_value("a"))
797+
< string_aa(StringExpression::from_value("aa")),
798+
string_1(StringExpression::from_value("1"))
799+
< string_a(StringExpression::from_value("a")),
800+
string_111(StringExpression::from_value("111"))
801+
< string_a(StringExpression::from_value("a")),
802+
empty_string(StringExpression::from_value(""))
803+
< string_colon(StringExpression::from_value(":")),
584804
);
585805
}
586806

0 commit comments

Comments
 (0)