forked from extern/nushell
Attempts to add //
math operator (#5759)
* attempts to add `div` math operator * allows `//` to be used too * fmt: * clippy issue * returns appropriate type * returns appropriate type 2 * fmt * ensure consistency; rename to `fdiv` * Update parser.rs
This commit is contained in:
@ -30,7 +30,10 @@ impl Expression {
|
||||
|
||||
match operator {
|
||||
Operator::Pow => 100,
|
||||
Operator::Multiply | Operator::Divide | Operator::Modulo => 95,
|
||||
Operator::Multiply
|
||||
| Operator::Divide
|
||||
| Operator::Modulo
|
||||
| Operator::FloorDivision => 95,
|
||||
Operator::Plus | Operator::Minus => 90,
|
||||
Operator::NotRegexMatch
|
||||
| Operator::RegexMatch
|
||||
|
@ -20,6 +20,7 @@ pub enum Operator {
|
||||
In,
|
||||
NotIn,
|
||||
Modulo,
|
||||
FloorDivision,
|
||||
And,
|
||||
Or,
|
||||
Pow,
|
||||
@ -43,6 +44,7 @@ impl Display for Operator {
|
||||
Operator::In => write!(f, "in"),
|
||||
Operator::NotIn => write!(f, "not-in"),
|
||||
Operator::Modulo => write!(f, "mod"),
|
||||
Operator::FloorDivision => write!(f, "fdiv"),
|
||||
Operator::And => write!(f, "&&"),
|
||||
Operator::Or => write!(f, "||"),
|
||||
Operator::Pow => write!(f, "**"),
|
||||
|
@ -1769,6 +1769,119 @@ impl Value {
|
||||
}),
|
||||
}
|
||||
}
|
||||
pub fn floor_div(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
match (self, rhs) {
|
||||
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
|
||||
if *rhs != 0 {
|
||||
Ok(Value::Int {
|
||||
val: (*lhs as f64 / *rhs as f64)
|
||||
.max(std::i64::MIN as f64)
|
||||
.min(std::i64::MAX as f64)
|
||||
.floor() as i64,
|
||||
span,
|
||||
})
|
||||
} else {
|
||||
Err(ShellError::DivisionByZero(op))
|
||||
}
|
||||
}
|
||||
(Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => {
|
||||
if *rhs != 0.0 {
|
||||
Ok(Value::Int {
|
||||
val: (*lhs as f64 / *rhs)
|
||||
.max(std::i64::MIN as f64)
|
||||
.min(std::i64::MAX as f64)
|
||||
.floor() as i64,
|
||||
span,
|
||||
})
|
||||
} else {
|
||||
Err(ShellError::DivisionByZero(op))
|
||||
}
|
||||
}
|
||||
(Value::Float { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
|
||||
if *rhs != 0 {
|
||||
Ok(Value::Int {
|
||||
val: (*lhs / *rhs as f64)
|
||||
.max(std::i64::MIN as f64)
|
||||
.min(std::i64::MAX as f64)
|
||||
.floor() as i64,
|
||||
span,
|
||||
})
|
||||
} else {
|
||||
Err(ShellError::DivisionByZero(op))
|
||||
}
|
||||
}
|
||||
(Value::Float { val: lhs, .. }, Value::Float { val: rhs, .. }) => {
|
||||
if *rhs != 0.0 {
|
||||
Ok(Value::Int {
|
||||
val: (lhs / rhs)
|
||||
.max(std::i64::MIN as f64)
|
||||
.min(std::i64::MAX as f64)
|
||||
.floor() as i64,
|
||||
span,
|
||||
})
|
||||
} else {
|
||||
Err(ShellError::DivisionByZero(op))
|
||||
}
|
||||
}
|
||||
(Value::Filesize { val: lhs, .. }, Value::Filesize { val: rhs, .. }) => {
|
||||
if *rhs != 0 {
|
||||
Ok(Value::Int {
|
||||
val: (*lhs as f64 / *rhs as f64)
|
||||
.max(std::i64::MIN as f64)
|
||||
.min(std::i64::MAX as f64)
|
||||
.floor() as i64,
|
||||
span,
|
||||
})
|
||||
} else {
|
||||
Err(ShellError::DivisionByZero(op))
|
||||
}
|
||||
}
|
||||
(Value::Duration { val: lhs, .. }, Value::Duration { val: rhs, .. }) => {
|
||||
if *rhs != 0 {
|
||||
Ok(Value::Int {
|
||||
val: (*lhs as f64 / *rhs as f64)
|
||||
.max(std::i64::MIN as f64)
|
||||
.min(std::i64::MAX as f64)
|
||||
.floor() as i64,
|
||||
span,
|
||||
})
|
||||
} else {
|
||||
Err(ShellError::DivisionByZero(op))
|
||||
}
|
||||
}
|
||||
(Value::Filesize { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
|
||||
if *rhs != 0 {
|
||||
Ok(Value::Filesize {
|
||||
val: lhs / rhs,
|
||||
span,
|
||||
})
|
||||
} else {
|
||||
Err(ShellError::DivisionByZero(op))
|
||||
}
|
||||
}
|
||||
(Value::Duration { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
|
||||
if *rhs != 0 {
|
||||
Ok(Value::Duration {
|
||||
val: lhs / rhs,
|
||||
span,
|
||||
})
|
||||
} else {
|
||||
Err(ShellError::DivisionByZero(op))
|
||||
}
|
||||
}
|
||||
(Value::CustomValue { val: lhs, span }, rhs) => {
|
||||
lhs.operation(*span, Operator::Divide, 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 lt(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
if let (Value::CustomValue { val: lhs, span }, rhs) = (self, rhs) {
|
||||
return lhs.operation(*span, Operator::LessThan, op, rhs);
|
||||
|
Reference in New Issue
Block a user