forked from extern/nushell
Add bit operator: bit-xor
(#5940)
This commit is contained in:
parent
3a38fb94f0
commit
4e90b478b7
@ -119,6 +119,7 @@ impl CustomValue for ExprDb {
|
||||
| Operator::NotIn
|
||||
| Operator::Pow
|
||||
| Operator::BitOr
|
||||
| Operator::BitXor
|
||||
| Operator::BitAnd
|
||||
| Operator::ShiftLeft
|
||||
| Operator::ShiftRight
|
||||
|
@ -442,6 +442,10 @@ pub fn eval_expression(
|
||||
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||
lhs.bit_or(op_span, &rhs, expr.span)
|
||||
}
|
||||
Operator::BitXor => {
|
||||
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||
lhs.bit_xor(op_span, &rhs, expr.span)
|
||||
}
|
||||
Operator::BitAnd => {
|
||||
let rhs = eval_expression(engine_state, stack, rhs)?;
|
||||
lhs.bit_and(op_span, &rhs, expr.span)
|
||||
|
@ -4107,6 +4107,7 @@ pub fn parse_operator(
|
||||
b"not-in" => Operator::NotIn,
|
||||
b"mod" => Operator::Modulo,
|
||||
b"bit-or" => Operator::BitOr,
|
||||
b"bit-xor" => Operator::BitXor,
|
||||
b"bit-and" => Operator::BitAnd,
|
||||
b"bit-shl" => Operator::ShiftLeft,
|
||||
b"bit-shr" => Operator::ShiftRight,
|
||||
|
@ -492,27 +492,29 @@ pub fn math_result_type(
|
||||
)
|
||||
}
|
||||
},
|
||||
Operator::ShiftLeft | Operator::ShiftRight | Operator::BitAnd | Operator::BitOr => {
|
||||
match (&lhs.ty, &rhs.ty) {
|
||||
(Type::Int, Type::Int) => (Type::Int, None),
|
||||
Operator::ShiftLeft
|
||||
| Operator::ShiftRight
|
||||
| Operator::BitOr
|
||||
| Operator::BitXor
|
||||
| Operator::BitAnd => match (&lhs.ty, &rhs.ty) {
|
||||
(Type::Int, Type::Int) => (Type::Int, None),
|
||||
|
||||
(Type::Any, _) => (Type::Any, None),
|
||||
(_, Type::Any) => (Type::Any, None),
|
||||
_ => {
|
||||
*op = Expression::garbage(op.span);
|
||||
(
|
||||
Type::Any,
|
||||
Some(ParseError::UnsupportedOperation(
|
||||
op.span,
|
||||
lhs.span,
|
||||
lhs.ty.clone(),
|
||||
rhs.span,
|
||||
rhs.ty.clone(),
|
||||
)),
|
||||
)
|
||||
}
|
||||
(Type::Any, _) => (Type::Any, None),
|
||||
(_, Type::Any) => (Type::Any, None),
|
||||
_ => {
|
||||
*op = Expression::garbage(op.span);
|
||||
(
|
||||
Type::Any,
|
||||
Some(ParseError::UnsupportedOperation(
|
||||
op.span,
|
||||
lhs.span,
|
||||
lhs.ty.clone(),
|
||||
rhs.span,
|
||||
rhs.ty.clone(),
|
||||
)),
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
_ => {
|
||||
*op = Expression::garbage(op.span);
|
||||
|
@ -49,7 +49,7 @@ impl Expression {
|
||||
| Operator::In
|
||||
| Operator::NotIn => 80,
|
||||
Operator::BitAnd => 75,
|
||||
// Operator::BitXor => 70,
|
||||
Operator::BitXor => 70,
|
||||
Operator::BitOr => 60,
|
||||
Operator::And => 50,
|
||||
Operator::Or => 40,
|
||||
|
@ -27,6 +27,7 @@ pub enum Operator {
|
||||
StartsWith,
|
||||
EndsWith,
|
||||
BitOr,
|
||||
BitXor,
|
||||
BitAnd,
|
||||
ShiftLeft,
|
||||
ShiftRight,
|
||||
@ -53,6 +54,7 @@ impl Display for Operator {
|
||||
Operator::Or => write!(f, "||"),
|
||||
Operator::Pow => write!(f, "**"),
|
||||
Operator::BitOr => write!(f, "bit-or"),
|
||||
Operator::BitXor => write!(f, "bit-xor"),
|
||||
Operator::BitAnd => write!(f, "bit-and"),
|
||||
Operator::ShiftLeft => write!(f, "bit-shl"),
|
||||
Operator::ShiftRight => write!(f, "bit-shr"),
|
||||
|
@ -2297,6 +2297,25 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bit_xor(&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::BitXor, 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 bit_and(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
match (self, rhs) {
|
||||
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Int {
|
||||
|
@ -55,6 +55,16 @@ fn or() -> TestResult {
|
||||
run_test("true || false", "true")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bit_xor() -> TestResult {
|
||||
run_test("4 bit-xor 4", "0")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bit_xor_add() -> TestResult {
|
||||
run_test("4 bit-xor 2 + 2", "0")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bit_and() -> TestResult {
|
||||
run_test("2 bit-and 4", "0")
|
||||
|
Loading…
Reference in New Issue
Block a user