Skip to content

Commit

Permalink
Add support for arbitrary length arguments to And, Or, Concat (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
twizmwazin authored Nov 4, 2024
1 parent c1ff5eb commit 95d336f
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 3 deletions.
12 changes: 11 additions & 1 deletion crates/clarirs_py/src/ast/bv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,17 @@ binop!(LShR, lshr, BV);
binop!(AShR, ashr, BV);
binop!(RotateLeft, rotate_left, BV);
binop!(RotateRight, rotate_right, BV);
binop!(Concat, concat, BV);
binop!(Concat_inner, concat, BV);

#[pyfunction(signature = (*args))]
pub fn Concat(py: Python, args: Vec<Bound<BV>>) -> Result<Py<BV>, ClaripyError> {
let mut args = args.into_iter();
let first = args.next().ok_or(ClaripyError::MissingArgIndex(0))?;
args.try_fold(first, |acc, arg| {
Concat_inner(py, acc.into(), arg.unbind().into()).map(|r| r.bind(py).clone())
})
.map(|r| r.unbind())
}

#[pyfunction]
pub fn Extract(py: Python, base: Bound<BV>, start: u32, end: u32) -> Result<Py<BV>, ClaripyError> {
Expand Down
12 changes: 12 additions & 0 deletions crates/clarirs_py/src/ast/coerce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,18 @@ impl From<CoerceBV> for Py<BV> {
}
}

impl From<Py<BV>> for CoerceBV {
fn from(val: Py<BV>) -> Self {
CoerceBV::new(val)
}
}

impl From<Bound<'_, BV>> for CoerceBV {
fn from(val: Bound<BV>) -> Self {
CoerceBV::new(val.unbind())
}
}

impl From<CoerceBV> for BitVecAst<'static> {
fn from(val: CoerceBV) -> Self {
val.inner.get().inner.clone()
Expand Down
30 changes: 28 additions & 2 deletions crates/clarirs_py/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,36 @@ macro_rules! define_binop {
};
}

define_binop!(And, and);
define_binop!(Or, or);
define_binop!(And_inner, and);
define_binop!(Or_inner, or);
define_binop!(Xor, xor);

// The following ops are reducable and support a variable number of arguments

#[pyfunction(signature = (*args))]
pub fn And(py: Python, args: Vec<Bound<PyAny>>) -> Result<Py<Base>, ClaripyError> {
let mut args = args.into_iter();
let first = args.next().ok_or(ClaripyError::MissingArgIndex(0))?;
Ok(args
.try_fold(first, |acc, arg| {
And_inner(py, acc, arg).map(|b| b.into_any().bind(py).clone())
})?
.downcast_into::<Base>()?
.unbind())
}

#[pyfunction(signature = (*args))]
pub fn Or(py: Python, args: Vec<Bound<PyAny>>) -> Result<Py<Base>, ClaripyError> {
let mut args = args.into_iter();
let first = args.next().ok_or(ClaripyError::MissingArgIndex(0))?;
Ok(args
.try_fold(first, |acc, arg| {
Or_inner(py, acc, arg).map(|b| b.into_any().bind(py).clone())
})?
.downcast_into::<Base>()?
.unbind())
}

#[pyfunction]
#[allow(non_snake_case)]
pub fn If(
Expand Down

0 comments on commit 95d336f

Please sign in to comment.