Chained comparison operators

This commit is contained in:
PaddiM8 2022-01-16 01:44:50 +01:00
parent c49e613d52
commit ce22ca63f4
4 changed files with 51 additions and 5 deletions

View File

@ -42,6 +42,7 @@ mod tests {
}
#[test_case("basics")]
#[test_case("comparisons")]
#[test_case("comprehensions")]
#[test_case("derivation")]
#[test_case("functions")]

View File

@ -928,6 +928,9 @@ impl KalkValue {
&& (imaginary.clone() - imaginary_rhs.clone()).abs()
< ACCEPTABLE_COMPARISON_MARGIN,
),
(KalkValue::Boolean(boolean), KalkValue::Boolean(boolean_rhs)) => {
KalkValue::Boolean(boolean == boolean_rhs)
}
(KalkValue::Matrix(rows), KalkValue::Matrix(rows_rhs)) => {
let mut matrices_are_equal = true;
for (row, row_rhs) in rows.iter().zip(rows_rhs) {
@ -969,6 +972,9 @@ impl KalkValue {
|| (imaginary.clone() - imaginary_rhs.clone()).abs()
> ACCEPTABLE_COMPARISON_MARGIN,
),
(KalkValue::Boolean(boolean), KalkValue::Boolean(boolean_rhs)) => {
KalkValue::Boolean(boolean != boolean_rhs)
}
(KalkValue::Vector(_), KalkValue::Vector(_))
| (KalkValue::Matrix(_), KalkValue::Matrix(_)) => {
if let KalkValue::Boolean(boolean) = self.eq_without_unit(rhs) {
@ -1001,7 +1007,7 @@ impl KalkValue {
match (self, rhs) {
(KalkValue::Number(real, _, _), KalkValue::Number(real_rhs, _, _)) => {
KalkValue::Boolean(real.clone() - real_rhs.clone() < ACCEPTABLE_COMPARISON_MARGIN)
KalkValue::Boolean(real.clone() - real_rhs.clone() < -ACCEPTABLE_COMPARISON_MARGIN)
}
_ => KalkValue::nan(),
}

View File

@ -352,7 +352,7 @@ fn parse_or(context: &mut Context) -> Result<Expr, CalcError> {
}
fn parse_and(context: &mut Context) -> Result<Expr, CalcError> {
let left = parse_equality(context)?;
let left = parse_comparison(context)?;
if match_token(context, TokenKind::And) {
let op = advance(context).kind;
@ -364,7 +364,7 @@ fn parse_and(context: &mut Context) -> Result<Expr, CalcError> {
Ok(left)
}
fn parse_equality(context: &mut Context) -> Result<Expr, CalcError> {
fn parse_comparison(context: &mut Context) -> Result<Expr, CalcError> {
let mut left = parse_to(context)?;
// Equality check
@ -380,10 +380,36 @@ fn parse_equality(context: &mut Context) -> Result<Expr, CalcError> {
let right = if op == TokenKind::Equals && match_token(context, TokenKind::OpenBrace) {
parse_piecewise(context)?
} else {
parse_to(context)?
parse_comparison(context)?
};
left = Expr::Binary(Box::new(left), op, Box::new(right));
left = match right {
Expr::Binary(
inner_left,
inner_op
@
(TokenKind::Equals
| TokenKind::NotEquals
| TokenKind::GreaterThan
| TokenKind::LessThan
| TokenKind::GreaterOrEquals
| TokenKind::LessOrEquals),
inner_right,
) => Expr::Binary(
Box::new(Expr::Binary(
Box::new(left),
op,
Box::new(*inner_left.clone()),
)),
TokenKind::And,
Box::new(Expr::Binary(
Box::new(*inner_left),
inner_op,
Box::new(*inner_right),
)),
),
_ => Expr::Binary(Box::new(left), op, Box::new(right)),
}
}
Ok(left)

13
tests/comparisons.kalker Normal file
View File

@ -0,0 +1,13 @@
x = 2
true = (1 = 1)
false = (1 != 1)
(x > 2) = false and
(x < 2) = false and
(x = 2) = true and
(x >= 2) = true and
(x <= 2) = true and
(1 < x < 2) = false and
(x < 3 < 4) = true and
(1 > x > 2) = false and
(x > 3 > 4) = false