Skip to content

Commit

Permalink
Merge pull request #53 from 4atj/support_errors
Browse files Browse the repository at this point in the history
support errors
  • Loading branch information
4atj authored Jul 13, 2024
2 parents 2088dbb + f58ff2b commit 7d7e497
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ fn find_binary_operators(
.iter()
.zip(er.output.iter())
.enumerate()
.all(|(i, (&ol, &or))| match (op.apply)(ol, or) {
.all(|(i, (&ol, &or))| match op.apply_(ol, or) {
Some(o) => matcher.match_one(i, o),
None => false,
})
Expand Down Expand Up @@ -240,7 +240,7 @@ fn find_unary_operators(
.output
.iter()
.enumerate()
.all(|(i, &or)| matcher.match_one(i, (op.apply)(or)))
.all(|(i, &or)| matcher.match_one(i, op.apply_(or)))
&& matcher.match_final(None, er, op_idx)
{
println!("{op_idx}{er}");
Expand Down
44 changes: 38 additions & 6 deletions src/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::fmt::Display;

use crate::{
expr::{ok_after_keyword, ok_before_keyword, Expr},
params::{Num, BINARY_OPERATORS, UNARY_OPERATORS},
params::{Num, BINARY_OPERATORS, ERROR_VALUE, UNARY_OPERATORS},
vec::Vector,
};

Expand Down Expand Up @@ -55,14 +55,24 @@ pub struct BinaryOp {
pub can_apply: fn(&Expr, &Expr) -> bool,
pub commutative: bool,
pub right_assoc: bool,
pub short_circuit: bool,
}

impl UnaryOp {
pub const PREC: Prec = 12;

#[inline(always)]
pub fn apply_(&self, x: Num) -> Num {
if Some(x) == ERROR_VALUE {
x
} else {
(self.apply)(x)
}
}

#[inline(always)]
pub fn vec_apply(&self, v: Vector) -> Vector {
v.map(self.apply)
v.map(|x| self.apply_(x))
}

#[inline(always)]
Expand All @@ -79,12 +89,22 @@ impl BinaryOp {
can_apply: can_apply_binary_always,
commutative: false,
right_assoc: false,
short_circuit: false,
};

#[inline(always)]
pub fn apply_(&self, l: Num, r: Num) -> Option<Num> {
if Some(l) == ERROR_VALUE || !self.short_circuit && Some(r) == ERROR_VALUE {
ERROR_VALUE
} else {
(self.apply)(l, r).or(ERROR_VALUE)
}
}

#[inline(always)]
pub fn vec_apply(&self, mut vl: Vector, vr: &Vector) -> Option<Vector> {
for (x, y) in vl.iter_mut().zip(vr.iter()) {
*x = (self.apply)(*x, *y)?;
for (l, &r) in vl.iter_mut().zip(vr.iter()) {
*l = self.apply_(*l, r)?;
}
Some(vl)
}
Expand Down Expand Up @@ -119,13 +139,21 @@ pub fn apply_or(l: Num, r: Num) -> Option<Num> {
Some(if l != 0 { l } else { r })
}
pub fn apply_or_logical(l: Num, r: Num) -> Option<Num> {
Some((l != 0 || r != 0) as Num)
if l == 0 && Some(r) == ERROR_VALUE {
ERROR_VALUE
} else {
Some((l != 0 || r != 0) as Num)
}
}
pub fn apply_and(l: Num, r: Num) -> Option<Num> {
Some(if l != 0 { r } else { l })
}
pub fn apply_and_logical(l: Num, r: Num) -> Option<Num> {
Some((l != 0 && r != 0) as Num)
if l != 0 && Some(r) == ERROR_VALUE {
ERROR_VALUE
} else {
Some((l != 0 && r != 0) as Num)
}
}
pub fn apply_lt(l: Num, r: Num) -> Option<Num> {
Some((l < r) as Num)
Expand Down Expand Up @@ -253,6 +281,7 @@ pub const OP_OR: BinaryOp = BinaryOp {
prec: 3,
apply: apply_or,
can_apply: can_apply_keyword,
short_circuit: true,
..BinaryOp::EMPTY
};
pub const OP_SPACE_OR: BinaryOp = BinaryOp {
Expand Down Expand Up @@ -280,13 +309,15 @@ pub const OP_OR_LOGICAL: BinaryOp = BinaryOp {
prec: 3,
apply: apply_or_logical,
commutative: true,
short_circuit: true,
..BinaryOp::EMPTY
};
pub const OP_AND: BinaryOp = BinaryOp {
name: "and",
prec: 4,
apply: apply_and,
can_apply: can_apply_keyword,
short_circuit: true,
..BinaryOp::EMPTY
};
pub const OP_SPACE_AND: BinaryOp = BinaryOp {
Expand Down Expand Up @@ -314,6 +345,7 @@ pub const OP_AND_LOGICAL: BinaryOp = BinaryOp {
prec: 4,
apply: apply_and_logical,
commutative: true,
short_circuit: true,
..BinaryOp::EMPTY
};
pub const OP_LT: BinaryOp = BinaryOp {
Expand Down
4 changes: 4 additions & 0 deletions src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,7 @@ pub const UNARY_OPERATORS: &[UnaryOp] = &[

/// Match leaf expressions 1 output at a time to avoid unnecessary precalculations
pub const MATCH_1BY1: bool = true;

/// If set, e.g. to `Some(-159236)`, this arbitrary number is chosen to represent errors.
/// That is, pysearch will pretend 1/0 = -159236, and -159236 * 2 = -159236, and so on.
pub const ERROR_VALUE: Option<Num> = None;

0 comments on commit 7d7e497

Please sign in to comment.