From ae1c4ccfd21e5b1c8541462c8afeac5c0f5fde05 Mon Sep 17 00:00:00 2001 From: Zhuoxun Yang Date: Sat, 14 Oct 2023 01:56:38 +0800 Subject: [PATCH] expr: short-circuit evaluation for `&` --- src/uu/expr/src/syntax_tree.rs | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index 4ca723a4d..e0e786b3a 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -166,16 +166,26 @@ impl AstNode { { let mut out = Vec::with_capacity(operands.len()); let mut operands = operands.iter(); - // check the first value before `|`, stop evaluate and return directly if it is true. - // push dummy to pass the check of `len() == 2` - if op_type == "|" { - if let Some(value) = operands.next() { - let value = value.evaluate()?; - out.push(value.clone()); - if value_as_bool(&value) { - out.push(String::from("dummy")); - return Ok(out); + + if let Some(value) = operands.next() { + let value = value.evaluate()?; + out.push(value.clone()); + // short-circuit evaluation for `|` and `&` + // push dummy to pass `assert!(values.len() == 2);` + match op_type.as_ref() { + "|" => { + if value_as_bool(&value) { + out.push(String::from("dummy")); + return Ok(out); + } } + "&" => { + if !value_as_bool(&value) { + out.push(String::from("dummy")); + return Ok(out); + } + } + _ => {} } }