mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-31 22:26:57 -06:00
Formulas: compare right operands only after the left spine of a chain matches
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
199e5f8e05
commit
ed48389c46
+23
-18
@@ -315,33 +315,38 @@ impl Clone for Expr {
|
||||
|
||||
impl PartialEq for Expr {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
// Compare the left spines of operator chains in a loop (see [`Expr`]).
|
||||
// Compare the left spines of operator chains in a loop (see [`Expr`]). The right-hand
|
||||
// operands are compared only once the whole spine matches, so a mismatch on the left
|
||||
// returns before any (possibly deep) right operand is walked.
|
||||
let (mut x, mut y) = (self, other);
|
||||
loop {
|
||||
let mut right_operands = Vec::new();
|
||||
let equal = loop {
|
||||
match (x, y) {
|
||||
(Expr::Binary(o1, a1, b1), Expr::Binary(o2, a2, b2)) => {
|
||||
if o1 != o2 || b1 != b2 {
|
||||
if o1 != o2 {
|
||||
return false;
|
||||
}
|
||||
right_operands.push((b1, b2));
|
||||
x = a1;
|
||||
y = a2;
|
||||
}
|
||||
(Expr::Number(a), Expr::Number(b)) => return a == b,
|
||||
(Expr::Text(a), Expr::Text(b)) => return a == b,
|
||||
(Expr::Bool(a), Expr::Bool(b)) => return a == b,
|
||||
(Expr::Error(a), Expr::Error(b)) => return a == b,
|
||||
(Expr::Array(a), Expr::Array(b)) => return a == b,
|
||||
(Expr::Ref(a), Expr::Ref(b)) => return a == b,
|
||||
(Expr::Name(a), Expr::Name(b)) => return a == b,
|
||||
(Expr::Struct(a), Expr::Struct(b)) => return a == b,
|
||||
(Expr::Unary(o1, a), Expr::Unary(o2, b)) => return o1 == o2 && a == b,
|
||||
(Expr::Call(n1, a), Expr::Call(n2, b)) => return n1 == n2 && a == b,
|
||||
(Expr::Invoke(c1, a), Expr::Invoke(c2, b)) => return c1 == c2 && a == b,
|
||||
(Expr::Missing, Expr::Missing) => return true,
|
||||
(Expr::Paren(a), Expr::Paren(b)) => return a == b,
|
||||
_ => return false,
|
||||
(Expr::Number(a), Expr::Number(b)) => break a == b,
|
||||
(Expr::Text(a), Expr::Text(b)) => break a == b,
|
||||
(Expr::Bool(a), Expr::Bool(b)) => break a == b,
|
||||
(Expr::Error(a), Expr::Error(b)) => break a == b,
|
||||
(Expr::Array(a), Expr::Array(b)) => break a == b,
|
||||
(Expr::Ref(a), Expr::Ref(b)) => break a == b,
|
||||
(Expr::Name(a), Expr::Name(b)) => break a == b,
|
||||
(Expr::Struct(a), Expr::Struct(b)) => break a == b,
|
||||
(Expr::Unary(o1, a), Expr::Unary(o2, b)) => break o1 == o2 && a == b,
|
||||
(Expr::Call(n1, a), Expr::Call(n2, b)) => break n1 == n2 && a == b,
|
||||
(Expr::Invoke(c1, a), Expr::Invoke(c2, b)) => break c1 == c2 && a == b,
|
||||
(Expr::Missing, Expr::Missing) => break true,
|
||||
(Expr::Paren(a), Expr::Paren(b)) => break a == b,
|
||||
_ => break false,
|
||||
}
|
||||
}
|
||||
};
|
||||
equal && right_operands.into_iter().rev().all(|(b1, b2)| b1 == b2)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user