Merge branch '88_bitwise_operators' into main

# Conflicts:
#	CHANGELOG.md
This commit is contained in:
Sebastian Schmidt 2021-10-12 15:11:56 +03:00
commit 55092ce793
5 changed files with 39 additions and 0 deletions

View File

@ -6,6 +6,7 @@
### Added ### Added
* Bitwise operators as builtin functions `bitand`, `bitor`, `bitxor`, `bitnot` (#88)
* Public immutable and mutable accessor functions to the operator and children of a Node. * Public immutable and mutable accessor functions to the operator and children of a Node.
### Removed ### Removed

View File

@ -373,6 +373,10 @@ This crate offers a set of builtin functions.
| `str::to_uppercase` | 1 | String | Returns the upper-case version of the string | | `str::to_uppercase` | 1 | String | Returns the upper-case version of the string |
| `str::trim` | 1 | String | Strips whitespace from the start and the end of the string | | `str::trim` | 1 | String | Strips whitespace from the start and the end of the string |
| `str::from` | >= 0 | Any | Returns passed value as string | | `str::from` | >= 0 | Any | Returns passed value as string |
| `bitand` | 2 | Int | Computes the bitwise and of the given integers |
| `bitor` | 2 | Int | Computes the bitwise or of the given integers |
| `bitxor` | 2 | Int | Computes the bitwise xor of the given integers |
| `bitnot` | 1 | Int | Computes the bitwise not of the given integer |
The `min` and `max` functions can deal with a mixture of integer and floating point arguments. The `min` and `max` functions can deal with a mixture of integer and floating point arguments.
If the maximum or minimum is an integer, then an integer is returned. If the maximum or minimum is an integer, then an integer is returned.

View File

@ -5,6 +5,7 @@ use crate::{
value::{FloatType, IntType}, value::{FloatType, IntType},
EvalexprError, Function, Value, ValueType, EvalexprError, Function, Value, ValueType,
}; };
use std::ops::{BitAnd, BitOr, BitXor, Not};
macro_rules! simple_math { macro_rules! simple_math {
($func:ident) => { ($func:ident) => {
@ -22,6 +23,22 @@ macro_rules! simple_math {
}; };
} }
macro_rules! int_function {
($func:ident) => {
Some(Function::new(|argument| {
let int = argument.as_int()?;
Ok(Value::Int(int.$func()))
}))
};
($func:ident, 2) => {
Some(Function::new(|argument| {
let tuple = argument.as_fixed_len_tuple(2)?;
let (a, b) = (tuple[0].as_int()?, tuple[1].as_int()?);
Ok(Value::Int(a.$func(b)))
}))
};
}
pub fn builtin_function(identifier: &str) -> Option<Function> { pub fn builtin_function(identifier: &str) -> Option<Function> {
match identifier { match identifier {
// Log // Log
@ -163,6 +180,11 @@ pub fn builtin_function(identifier: &str) -> Option<Function> {
"str::from" => Some(Function::new(|argument| { "str::from" => Some(Function::new(|argument| {
Ok(Value::String(argument.to_string())) Ok(Value::String(argument.to_string()))
})), })),
// Bitwise operators
"bitand" => int_function!(bitand, 2),
"bitor" => int_function!(bitor, 2),
"bitxor" => int_function!(bitxor, 2),
"bitnot" => int_function!(not),
_ => None, _ => None,
} }
} }

View File

@ -356,6 +356,10 @@
//! | `str::to_uppercase` | 1 | String | Returns the upper-case version of the string | //! | `str::to_uppercase` | 1 | String | Returns the upper-case version of the string |
//! | `str::trim` | 1 | String | Strips whitespace from the start and the end of the string | //! | `str::trim` | 1 | String | Strips whitespace from the start and the end of the string |
//! | `str::from` | >= 0 | Any | Returns passed value as string | //! | `str::from` | >= 0 | Any | Returns passed value as string |
//! | `bitand` | 2 | Int | Computes the bitwise and of the given integers |
//! | `bitor` | 2 | Int | Computes the bitwise or of the given integers |
//! | `bitxor` | 2 | Int | Computes the bitwise xor of the given integers |
//! | `bitnot` | 1 | Int | Computes the bitwise not of the given integer |
//! //!
//! The `min` and `max` functions can deal with a mixture of integer and floating point arguments. //! The `min` and `max` functions can deal with a mixture of integer and floating point arguments.
//! If the maximum or minimum is an integer, then an integer is returned. //! If the maximum or minimum is an integer, then an integer is returned.

View File

@ -395,6 +395,14 @@ fn test_builtin_functions() {
Ok(Value::String(String::from("(1, 2, 3)"))) Ok(Value::String(String::from("(1, 2, 3)")))
); );
assert_eq!(eval("str::from()"), Ok(Value::String(String::from("()")))); assert_eq!(eval("str::from()"), Ok(Value::String(String::from("()"))));
assert_eq!(eval("bitand(5, -1)"), Ok(Value::Int(5)));
assert_eq!(eval("bitand(6, 5)"), Ok(Value::Int(4)));
assert_eq!(eval("bitor(5, -1)"), Ok(Value::Int(-1)));
assert_eq!(eval("bitor(6, 5)"), Ok(Value::Int(7)));
assert_eq!(eval("bitxor(5, -1)"), Ok(Value::Int(-6)));
assert_eq!(eval("bitxor(6, 5)"), Ok(Value::Int(3)));
assert_eq!(eval("bitnot(5)"), Ok(Value::Int(-6)));
assert_eq!(eval("bitnot(-1)"), Ok(Value::Int(0)));
} }
#[test] #[test]