Update #4202: Add shift operator bshl and bshr for integers (#5928)

* Update #4202: Add shift operator bshl and bshr for integers

* Add more tests
This commit is contained in:
Justin Ma
2022-07-02 19:48:43 +08:00
committed by GitHub
parent 3b357e5402
commit 3917fda7ed
8 changed files with 94 additions and 0 deletions

View File

@ -35,6 +35,7 @@ impl Expression {
| Operator::Modulo
| Operator::FloorDivision => 95,
Operator::Plus | Operator::Minus => 90,
Operator::ShiftLeft | Operator::ShiftRight => 85,
Operator::NotRegexMatch
| Operator::RegexMatch
| Operator::StartsWith

View File

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

View File

@ -2240,6 +2240,44 @@ impl Value {
}
}
pub fn bshl(&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::ShiftLeft, 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 bshr(&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::ShiftRight, 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, .. }) => {