mirror of
https://github.com/nushell/nushell
synced 2024-12-27 05:23:11 +00:00
Add shortcircuiting boolean operators (#4668)
This commit is contained in:
parent
4ebbe07d27
commit
7819210037
2 changed files with 96 additions and 19 deletions
|
@ -301,27 +301,94 @@ pub fn eval_expression(
|
||||||
let op_span = op.span;
|
let op_span = op.span;
|
||||||
let lhs = eval_expression(engine_state, stack, lhs)?;
|
let lhs = eval_expression(engine_state, stack, lhs)?;
|
||||||
let op = eval_operator(op)?;
|
let op = eval_operator(op)?;
|
||||||
let rhs = eval_expression(engine_state, stack, rhs)?;
|
|
||||||
|
|
||||||
match op {
|
match op {
|
||||||
Operator::Plus => lhs.add(op_span, &rhs),
|
Operator::And => {
|
||||||
Operator::Minus => lhs.sub(op_span, &rhs),
|
if !lhs.is_true() {
|
||||||
Operator::Multiply => lhs.mul(op_span, &rhs),
|
Ok(Value::Bool {
|
||||||
Operator::Divide => lhs.div(op_span, &rhs),
|
val: false,
|
||||||
Operator::LessThan => lhs.lt(op_span, &rhs),
|
span: expr.span,
|
||||||
Operator::LessThanOrEqual => lhs.lte(op_span, &rhs),
|
})
|
||||||
Operator::GreaterThan => lhs.gt(op_span, &rhs),
|
} else {
|
||||||
Operator::GreaterThanOrEqual => lhs.gte(op_span, &rhs),
|
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||||
Operator::Equal => lhs.eq(op_span, &rhs),
|
lhs.and(op_span, &rhs)
|
||||||
Operator::NotEqual => lhs.ne(op_span, &rhs),
|
}
|
||||||
Operator::In => lhs.r#in(op_span, &rhs),
|
}
|
||||||
Operator::NotIn => lhs.not_in(op_span, &rhs),
|
Operator::Or => {
|
||||||
Operator::Contains => lhs.contains(op_span, &rhs),
|
if lhs.is_true() {
|
||||||
Operator::NotContains => lhs.not_contains(op_span, &rhs),
|
Ok(Value::Bool {
|
||||||
Operator::Modulo => lhs.modulo(op_span, &rhs),
|
val: true,
|
||||||
Operator::And => lhs.and(op_span, &rhs),
|
span: expr.span,
|
||||||
Operator::Or => lhs.or(op_span, &rhs),
|
})
|
||||||
Operator::Pow => lhs.pow(op_span, &rhs),
|
} else {
|
||||||
|
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||||
|
lhs.or(op_span, &rhs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Operator::Plus => {
|
||||||
|
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||||
|
lhs.add(op_span, &rhs)
|
||||||
|
}
|
||||||
|
Operator::Minus => {
|
||||||
|
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||||
|
lhs.sub(op_span, &rhs)
|
||||||
|
}
|
||||||
|
Operator::Multiply => {
|
||||||
|
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||||
|
lhs.mul(op_span, &rhs)
|
||||||
|
}
|
||||||
|
Operator::Divide => {
|
||||||
|
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||||
|
lhs.div(op_span, &rhs)
|
||||||
|
}
|
||||||
|
Operator::LessThan => {
|
||||||
|
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||||
|
lhs.lt(op_span, &rhs)
|
||||||
|
}
|
||||||
|
Operator::LessThanOrEqual => {
|
||||||
|
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||||
|
lhs.lte(op_span, &rhs)
|
||||||
|
}
|
||||||
|
Operator::GreaterThan => {
|
||||||
|
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||||
|
lhs.gt(op_span, &rhs)
|
||||||
|
}
|
||||||
|
Operator::GreaterThanOrEqual => {
|
||||||
|
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||||
|
lhs.gte(op_span, &rhs)
|
||||||
|
}
|
||||||
|
Operator::Equal => {
|
||||||
|
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||||
|
lhs.eq(op_span, &rhs)
|
||||||
|
}
|
||||||
|
Operator::NotEqual => {
|
||||||
|
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||||
|
lhs.ne(op_span, &rhs)
|
||||||
|
}
|
||||||
|
Operator::In => {
|
||||||
|
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||||
|
lhs.r#in(op_span, &rhs)
|
||||||
|
}
|
||||||
|
Operator::NotIn => {
|
||||||
|
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||||
|
lhs.not_in(op_span, &rhs)
|
||||||
|
}
|
||||||
|
Operator::Contains => {
|
||||||
|
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||||
|
lhs.contains(op_span, &rhs)
|
||||||
|
}
|
||||||
|
Operator::NotContains => {
|
||||||
|
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||||
|
lhs.not_contains(op_span, &rhs)
|
||||||
|
}
|
||||||
|
Operator::Modulo => {
|
||||||
|
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||||
|
lhs.modulo(op_span, &rhs)
|
||||||
|
}
|
||||||
|
Operator::Pow => {
|
||||||
|
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||||
|
lhs.pow(op_span, &rhs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expr::Subexpression(block_id) => {
|
Expr::Subexpression(block_id) => {
|
||||||
|
|
|
@ -262,3 +262,13 @@ fn test_redirection_stderr() -> TestResult {
|
||||||
fn datetime_literal() -> TestResult {
|
fn datetime_literal() -> TestResult {
|
||||||
run_test(r#"(date now) - 2019-08-23 > 1hr"#, "true")
|
run_test(r#"(date now) - 2019-08-23 > 1hr"#, "true")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn shortcircuiting_and() -> TestResult {
|
||||||
|
run_test(r#"$false && (5 / 0; $false)"#, "false")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn shortcircuiting_or() -> TestResult {
|
||||||
|
run_test(r#"$true || (5 / 0; $false)"#, "true")
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue