Add band and bor operator for bit operations (#5936)

* Add `band` and `bor` Operator

* Add tests
This commit is contained in:
Justin Ma
2022-07-03 02:03:36 +08:00
committed by GitHub
parent 84caf8859f
commit b82dccf0bd
8 changed files with 91 additions and 17 deletions

View File

@ -48,6 +48,9 @@ impl Expression {
| Operator::NotEqual
| Operator::In
| Operator::NotIn => 80,
Operator::BitAnd => 75,
// Operator::BitXor => 70,
Operator::BitOr => 60,
Operator::And => 50,
Operator::Or => 40,
}

View File

@ -26,6 +26,8 @@ pub enum Operator {
Pow,
StartsWith,
EndsWith,
BitOr,
BitAnd,
ShiftLeft,
ShiftRight,
}
@ -50,6 +52,8 @@ impl Display for Operator {
Operator::And => write!(f, "&&"),
Operator::Or => write!(f, "||"),
Operator::Pow => write!(f, "**"),
Operator::BitOr => write!(f, "bor"),
Operator::BitAnd => write!(f, "band"),
Operator::ShiftLeft => write!(f, "bshl"),
Operator::ShiftRight => write!(f, "bshr"),
Operator::LessThanOrEqual => write!(f, "<="),

View File

@ -2278,6 +2278,44 @@ impl Value {
}
}
pub fn bor(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
match (self, rhs) {
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Int {
span,
val: *lhs | rhs,
}),
(Value::CustomValue { val: lhs, span }, rhs) => {
lhs.operation(*span, Operator::BitOr, op, rhs)
}
_ => Err(ShellError::OperatorMismatch {
op_span: op,
lhs_ty: self.get_type(),
lhs_span: self.span()?,
rhs_ty: rhs.get_type(),
rhs_span: rhs.span()?,
}),
}
}
pub fn band(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
match (self, rhs) {
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Int {
span,
val: *lhs & rhs,
}),
(Value::CustomValue { val: lhs, span }, rhs) => {
lhs.operation(*span, Operator::BitAnd, op, rhs)
}
_ => Err(ShellError::OperatorMismatch {
op_span: op,
lhs_ty: self.get_type(),
lhs_span: self.span()?,
rhs_ty: rhs.get_type(),
rhs_span: rhs.span()?,
}),
}
}
pub fn modulo(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
match (self, rhs) {
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => {