diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index b3cd329ba..eaa6be1f5 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -52,7 +52,7 @@ impl AstNode { operands, } => { println!( - "Node( {} ) at #{} (evaluate -> {:?})", + "Node( {} ) at #{} ( evaluate -> {:?} )", op_type, token_idx, self.evaluate() @@ -155,8 +155,25 @@ impl AstNode { } } pub fn operand_values(&self) -> Result, String> { - if let Self::Node { operands, .. } = self { + if let Self::Node { + operands, op_type, .. + } = self + { 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); + } + } + } + for operand in operands { let value = operand.evaluate()?; out.push(value); diff --git a/tests/by-util/test_expr.rs b/tests/by-util/test_expr.rs index ea5a964d9..4637d51c7 100644 --- a/tests/by-util/test_expr.rs +++ b/tests/by-util/test_expr.rs @@ -123,6 +123,21 @@ fn test_or() { .args(&["-14", "|", "1"]) .succeeds() .stdout_only("-14\n"); + + new_ucmd!() + .args(&["1", "|", "a", "/", "5"]) + .succeeds() + .stdout_only("1\n"); + + new_ucmd!() + .args(&["foo", "|", "a", "/", "5"]) + .succeeds() + .stdout_only("foo\n"); + + new_ucmd!() + .args(&["0", "|", "10", "/", "5"]) + .succeeds() + .stdout_only("2\n"); } #[test]