mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 19:47:45 +00:00
Merge pull request #762 from ebfe/expr-and-or
expr: implement '|' and '&'
This commit is contained in:
commit
9339bbe50d
3 changed files with 83 additions and 1 deletions
1
Makefile
1
Makefile
|
@ -125,6 +125,7 @@ TEST_PROGS := \
|
||||||
dirname \
|
dirname \
|
||||||
echo \
|
echo \
|
||||||
env \
|
env \
|
||||||
|
expr \
|
||||||
factor \
|
factor \
|
||||||
false \
|
false \
|
||||||
fold \
|
fold \
|
||||||
|
|
|
@ -103,6 +103,8 @@ impl ASTNode {
|
||||||
|a: &String, b: &String| Ok( bool_as_string(a >= b) ),
|
|a: &String, b: &String| Ok( bool_as_string(a >= b) ),
|
||||||
&operand_values
|
&operand_values
|
||||||
),
|
),
|
||||||
|
"|" => infix_operator_or(&operand_values),
|
||||||
|
"&" => infix_operator_and(&operand_values),
|
||||||
"length" => prefix_operator_length( &operand_values ),
|
"length" => prefix_operator_length( &operand_values ),
|
||||||
"index" => prefix_operator_index( &operand_values ),
|
"index" => prefix_operator_index( &operand_values ),
|
||||||
"substr" => prefix_operator_substr( &operand_values ),
|
"substr" => prefix_operator_substr( &operand_values ),
|
||||||
|
@ -331,6 +333,23 @@ fn infix_operator_two_ints_or_two_strings<FI, FS>( fi: FI, fs: FS, values: &Vec<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn infix_operator_or( values: &Vec<String> ) -> Result<String, String> {
|
||||||
|
assert!(values.len() == 2);
|
||||||
|
if value_as_bool(&values[0]) {
|
||||||
|
Ok(values[0].clone())
|
||||||
|
} else {
|
||||||
|
Ok(values[1].clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn infix_operator_and( values: &Vec<String> ) -> Result<String, String> {
|
||||||
|
if value_as_bool(&values[0]) && value_as_bool(&values[1]) {
|
||||||
|
Ok(values[0].clone())
|
||||||
|
} else {
|
||||||
|
Ok(0.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn prefix_operator_length( values: &Vec<String> ) -> Result<String, String> {
|
fn prefix_operator_length( values: &Vec<String> ) -> Result<String, String> {
|
||||||
assert!( values.len() == 1 );
|
assert!( values.len() == 1 );
|
||||||
Ok( values[0].len().to_string() )
|
Ok( values[0].len().to_string() )
|
||||||
|
@ -383,4 +402,12 @@ fn prefix_operator_substr( values: &Vec<String> ) -> Result<String, String> {
|
||||||
|
|
||||||
fn bool_as_int( b: bool ) -> i64 { if b { 1 } else { 0 } }
|
fn bool_as_int( b: bool ) -> i64 { if b { 1 } else { 0 } }
|
||||||
fn bool_as_string( b: bool ) -> String { if b { "1".to_string() } else { "0".to_string() } }
|
fn bool_as_string( b: bool ) -> String { if b { "1".to_string() } else { "0".to_string() } }
|
||||||
|
fn value_as_bool( s: &str ) -> bool {
|
||||||
|
if s.len() == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
match s.parse::<i64>() {
|
||||||
|
Ok(n) => n != 0,
|
||||||
|
Err(_) => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
54
tests/expr.rs
Normal file
54
tests/expr.rs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#[macro_use]
|
||||||
|
mod common;
|
||||||
|
|
||||||
|
use common::util::*;
|
||||||
|
|
||||||
|
static UTIL_NAME: &'static str = "expr";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_simple_arithmetic() {
|
||||||
|
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||||
|
let out = ucmd.args(&["1", "+", "1"]).run().stdout;
|
||||||
|
assert_eq!(out, "2\n");
|
||||||
|
|
||||||
|
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||||
|
let out = ucmd.args(&["1", "-", "1"]).run().stdout;
|
||||||
|
assert_eq!(out, "0\n");
|
||||||
|
|
||||||
|
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||||
|
let out = ucmd.args(&["3", "*", "2"]).run().stdout;
|
||||||
|
assert_eq!(out, "6\n");
|
||||||
|
|
||||||
|
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||||
|
let out = ucmd.args(&["4", "/", "2"]).run().stdout;
|
||||||
|
assert_eq!(out, "2\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parenthesis() {
|
||||||
|
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||||
|
let out = ucmd.args(&["(", "1", "+", "1", ")", "*", "2"]).run().stdout;
|
||||||
|
assert_eq!(out, "4\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_or() {
|
||||||
|
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||||
|
let out = ucmd.args(&["0", "|", "foo"]).run().stdout;
|
||||||
|
assert_eq!(out, "foo\n");
|
||||||
|
|
||||||
|
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||||
|
let out = ucmd.args(&["foo", "|", "bar"]).run().stdout;
|
||||||
|
assert_eq!(out, "foo\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_and() {
|
||||||
|
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||||
|
let out = ucmd.args(&["foo", "&", "1"]).run().stdout;
|
||||||
|
assert_eq!(out, "foo\n");
|
||||||
|
|
||||||
|
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||||
|
let out = ucmd.args(&["", "&", "1"]).run().stdout;
|
||||||
|
assert_eq!(out, "0\n");
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue