Skip to content

Commit

Permalink
Implement bitwise operators as builtin functions.
Browse files Browse the repository at this point in the history
Relates to #88
  • Loading branch information
ISibboI committed Oct 12, 2021
1 parent e0d4ef2 commit b3be7f6
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

### Added

* Bitwise operators as builtin functions `bitand`, `bitor`, `bitxor`, `bitnot` (#88)

### Removed

### Changed
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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::trim` | 1 | String | Strips whitespace from the start and the end of the 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.
If the maximum or minimum is an integer, then an integer is returned.
Expand Down
22 changes: 22 additions & 0 deletions src/function/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::{
value::{FloatType, IntType},
EvalexprError, Function, Value, ValueType,
};
use std::ops::{BitAnd, BitOr, BitXor, Not};

macro_rules! simple_math {
($func:ident) => {
Expand All @@ -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> {
match identifier {
// Log
Expand Down Expand Up @@ -163,6 +180,11 @@ pub fn builtin_function(identifier: &str) -> Option<Function> {
"str::from" => Some(Function::new(|argument| {
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,
}
}
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,10 @@
//! | `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::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.
//! If the maximum or minimum is an integer, then an integer is returned.
Expand Down
8 changes: 8 additions & 0 deletions tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,14 @@ fn test_builtin_functions() {
Ok(Value::String(String::from("(1, 2, 3)")))
);
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]
Expand Down

0 comments on commit b3be7f6

Please sign in to comment.