forked from extern/nushell
added pow operator, and filesize math (#2976)
* added pow operator, and filesize math * removed + and - arms, removed some pow, pow higher precedence * Update value.rs Co-authored-by: Jonathan Turner <jonathandturner@users.noreply.github.com>
This commit is contained in:
parent
47c4b8e88a
commit
b052d524da
@ -257,6 +257,7 @@ fn get_result_shape_of(
|
||||
}
|
||||
}
|
||||
Operator::Modulo => SyntaxShape::Number,
|
||||
Operator::Pow => SyntaxShape::Number,
|
||||
})
|
||||
}
|
||||
|
||||
@ -860,7 +861,7 @@ impl VarSyntaxShapeDeductor {
|
||||
}
|
||||
}
|
||||
}
|
||||
Operator::Multiply | Operator::Divide => {
|
||||
Operator::Multiply | Operator::Divide | Operator::Pow => {
|
||||
if let Some(shape) = self.get_shape_of_binary_arg_or_insert_dependency(
|
||||
(var, expr),
|
||||
bin_spanned,
|
||||
|
@ -8,7 +8,7 @@ use nu_protocol::ShellTypeName;
|
||||
use nu_protocol::{Primitive, Type, UntaggedValue};
|
||||
use nu_source::{DebugDocBuilder, PrettyDebug, Span, Tagged};
|
||||
use nu_table::TextStyle;
|
||||
use num_traits::Zero;
|
||||
use num_traits::{ToPrimitive, Zero};
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub struct Date;
|
||||
@ -119,6 +119,11 @@ pub fn compute_values(
|
||||
}?;
|
||||
Ok(UntaggedValue::Primitive(Primitive::Filesize(result)))
|
||||
}
|
||||
(Primitive::Filesize(x), Primitive::Int(y)) => match operator {
|
||||
Operator::Multiply => Ok(UntaggedValue::Primitive(Primitive::Int(x * y))),
|
||||
Operator::Divide => Ok(UntaggedValue::Primitive(Primitive::Int(x / y))),
|
||||
_ => Err((left.type_name(), right.type_name())),
|
||||
},
|
||||
(Primitive::Int(x), Primitive::Int(y)) => match operator {
|
||||
Operator::Plus => Ok(UntaggedValue::Primitive(Primitive::Int(x + y))),
|
||||
Operator::Minus => Ok(UntaggedValue::Primitive(Primitive::Int(x - y))),
|
||||
@ -142,6 +147,13 @@ pub fn compute_values(
|
||||
Ok(UntaggedValue::Primitive(Primitive::Int(x % y)))
|
||||
}
|
||||
}
|
||||
Operator::Pow => {
|
||||
let prim_u32 = ToPrimitive::to_u32(y);
|
||||
match prim_u32 {
|
||||
Some(num) => Ok(UntaggedValue::Primitive(Primitive::Int(x.pow(num)))),
|
||||
_ => Err((left.type_name(), right.type_name())),
|
||||
}
|
||||
}
|
||||
_ => Err((left.type_name(), right.type_name())),
|
||||
},
|
||||
(Primitive::Decimal(x), Primitive::Int(y)) => {
|
||||
@ -161,6 +173,16 @@ pub fn compute_values(
|
||||
}
|
||||
Ok(x % bigdecimal::BigDecimal::from(y.clone()))
|
||||
}
|
||||
// leaving this here for the hope that bigdecimal will one day support pow/powf/fpow
|
||||
// Operator::Pow => {
|
||||
// let xp = bigdecimal::ToPrimitive::to_f64(x).unwrap_or(0.0);
|
||||
// let yp = bigdecimal::ToPrimitive::to_f64(y).unwrap_or(0.0);
|
||||
// let pow = bigdecimal::FromPrimitive::from_f64(xp.powf(yp));
|
||||
// match pow {
|
||||
// Some(p) => Ok(p),
|
||||
// None => Err((left.type_name(), right.type_name())),
|
||||
// }
|
||||
// }
|
||||
_ => Err((left.type_name(), right.type_name())),
|
||||
}?;
|
||||
Ok(UntaggedValue::Primitive(Primitive::Decimal(result)))
|
||||
@ -182,7 +204,11 @@ pub fn compute_values(
|
||||
}
|
||||
Ok(bigdecimal::BigDecimal::from(x.clone()) % y)
|
||||
}
|
||||
|
||||
// big decimal doesn't support pow yet
|
||||
// Operator::Pow => {
|
||||
// let yp = bigdecimal::ToPrimitive::to_u32(y).unwrap_or(0);
|
||||
// Ok(bigdecimal::BigDecimal::from(x.pow(yp)))
|
||||
// }
|
||||
_ => Err((left.type_name(), right.type_name())),
|
||||
}?;
|
||||
Ok(UntaggedValue::Primitive(Primitive::Decimal(result)))
|
||||
@ -204,7 +230,16 @@ pub fn compute_values(
|
||||
}
|
||||
Ok(x % y)
|
||||
}
|
||||
|
||||
// big decimal doesn't support pow yet
|
||||
// Operator::Pow => {
|
||||
// let xp = bigdecimal::ToPrimitive::to_f64(x).unwrap_or(0.0);
|
||||
// let yp = bigdecimal::ToPrimitive::to_f64(y).unwrap_or(0.0);
|
||||
// let pow = bigdecimal::FromPrimitive::from_f64(xp.powf(yp));
|
||||
// match pow {
|
||||
// Some(p) => Ok(p),
|
||||
// None => Err((left.type_name(), right.type_name())),
|
||||
// }
|
||||
// }
|
||||
_ => Err((left.type_name(), right.type_name())),
|
||||
}?;
|
||||
Ok(UntaggedValue::Primitive(Primitive::Decimal(result)))
|
||||
|
@ -25,6 +25,7 @@ pub fn apply_operator(
|
||||
Operator::Plus => value::compute_values(op, left, right),
|
||||
Operator::Minus => value::compute_values(op, left, right),
|
||||
Operator::Multiply => value::compute_values(op, left, right),
|
||||
Operator::Pow => value::compute_values(op, left, right),
|
||||
Operator::Divide => value::compute_values(op, left, right).map(|res| match res {
|
||||
UntaggedValue::Error(_) => UntaggedValue::Error(ShellError::labeled_error(
|
||||
"Evaluation error",
|
||||
|
@ -307,6 +307,7 @@ fn parse_operator(lite_arg: &Spanned<String>) -> (SpannedExpression, Option<Pars
|
||||
"mod" => Operator::Modulo,
|
||||
"&&" => Operator::And,
|
||||
"||" => Operator::Or,
|
||||
"**" => Operator::Pow,
|
||||
_ => {
|
||||
return (
|
||||
garbage(lite_arg.span),
|
||||
|
@ -656,7 +656,8 @@ impl SpannedExpression {
|
||||
// Higher precedence binds tighter
|
||||
|
||||
match operator {
|
||||
Operator::Multiply | Operator::Divide | Operator::Modulo => 100,
|
||||
Operator::Pow => 100,
|
||||
Operator::Multiply | Operator::Divide | Operator::Modulo => 95,
|
||||
Operator::Plus | Operator::Minus => 90,
|
||||
Operator::NotContains
|
||||
| Operator::Contains
|
||||
@ -848,6 +849,7 @@ pub enum Operator {
|
||||
Modulo,
|
||||
And,
|
||||
Or,
|
||||
Pow,
|
||||
}
|
||||
|
||||
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, Hash, Deserialize, Serialize, new)]
|
||||
|
Loading…
Reference in New Issue
Block a user