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::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(
|
if let Some(shape) = self.get_shape_of_binary_arg_or_insert_dependency(
|
||||||
(var, expr),
|
(var, expr),
|
||||||
bin_spanned,
|
bin_spanned,
|
||||||
|
@ -8,7 +8,7 @@ use nu_protocol::ShellTypeName;
|
|||||||
use nu_protocol::{Primitive, Type, UntaggedValue};
|
use nu_protocol::{Primitive, Type, UntaggedValue};
|
||||||
use nu_source::{DebugDocBuilder, PrettyDebug, Span, Tagged};
|
use nu_source::{DebugDocBuilder, PrettyDebug, Span, Tagged};
|
||||||
use nu_table::TextStyle;
|
use nu_table::TextStyle;
|
||||||
use num_traits::Zero;
|
use num_traits::{ToPrimitive, Zero};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub struct Date;
|
pub struct Date;
|
||||||
@ -119,6 +119,11 @@ pub fn compute_values(
|
|||||||
}?;
|
}?;
|
||||||
Ok(UntaggedValue::Primitive(Primitive::Filesize(result)))
|
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 {
|
(Primitive::Int(x), Primitive::Int(y)) => match operator {
|
||||||
Operator::Plus => Ok(UntaggedValue::Primitive(Primitive::Int(x + y))),
|
Operator::Plus => Ok(UntaggedValue::Primitive(Primitive::Int(x + y))),
|
||||||
Operator::Minus => 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)))
|
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())),
|
_ => Err((left.type_name(), right.type_name())),
|
||||||
},
|
},
|
||||||
(Primitive::Decimal(x), Primitive::Int(y)) => {
|
(Primitive::Decimal(x), Primitive::Int(y)) => {
|
||||||
@ -161,6 +173,16 @@ pub fn compute_values(
|
|||||||
}
|
}
|
||||||
Ok(x % bigdecimal::BigDecimal::from(y.clone()))
|
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())),
|
_ => Err((left.type_name(), right.type_name())),
|
||||||
}?;
|
}?;
|
||||||
Ok(UntaggedValue::Primitive(Primitive::Decimal(result)))
|
Ok(UntaggedValue::Primitive(Primitive::Decimal(result)))
|
||||||
@ -182,7 +204,11 @@ pub fn compute_values(
|
|||||||
}
|
}
|
||||||
Ok(bigdecimal::BigDecimal::from(x.clone()) % y)
|
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())),
|
_ => Err((left.type_name(), right.type_name())),
|
||||||
}?;
|
}?;
|
||||||
Ok(UntaggedValue::Primitive(Primitive::Decimal(result)))
|
Ok(UntaggedValue::Primitive(Primitive::Decimal(result)))
|
||||||
@ -204,7 +230,16 @@ pub fn compute_values(
|
|||||||
}
|
}
|
||||||
Ok(x % y)
|
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())),
|
_ => Err((left.type_name(), right.type_name())),
|
||||||
}?;
|
}?;
|
||||||
Ok(UntaggedValue::Primitive(Primitive::Decimal(result)))
|
Ok(UntaggedValue::Primitive(Primitive::Decimal(result)))
|
||||||
|
@ -25,6 +25,7 @@ pub fn apply_operator(
|
|||||||
Operator::Plus => value::compute_values(op, left, right),
|
Operator::Plus => value::compute_values(op, left, right),
|
||||||
Operator::Minus => value::compute_values(op, left, right),
|
Operator::Minus => value::compute_values(op, left, right),
|
||||||
Operator::Multiply => 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 {
|
Operator::Divide => value::compute_values(op, left, right).map(|res| match res {
|
||||||
UntaggedValue::Error(_) => UntaggedValue::Error(ShellError::labeled_error(
|
UntaggedValue::Error(_) => UntaggedValue::Error(ShellError::labeled_error(
|
||||||
"Evaluation error",
|
"Evaluation error",
|
||||||
|
@ -307,6 +307,7 @@ fn parse_operator(lite_arg: &Spanned<String>) -> (SpannedExpression, Option<Pars
|
|||||||
"mod" => Operator::Modulo,
|
"mod" => Operator::Modulo,
|
||||||
"&&" => Operator::And,
|
"&&" => Operator::And,
|
||||||
"||" => Operator::Or,
|
"||" => Operator::Or,
|
||||||
|
"**" => Operator::Pow,
|
||||||
_ => {
|
_ => {
|
||||||
return (
|
return (
|
||||||
garbage(lite_arg.span),
|
garbage(lite_arg.span),
|
||||||
|
@ -656,7 +656,8 @@ impl SpannedExpression {
|
|||||||
// Higher precedence binds tighter
|
// Higher precedence binds tighter
|
||||||
|
|
||||||
match operator {
|
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::Plus | Operator::Minus => 90,
|
||||||
Operator::NotContains
|
Operator::NotContains
|
||||||
| Operator::Contains
|
| Operator::Contains
|
||||||
@ -848,6 +849,7 @@ pub enum Operator {
|
|||||||
Modulo,
|
Modulo,
|
||||||
And,
|
And,
|
||||||
Or,
|
Or,
|
||||||
|
Pow,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, Hash, Deserialize, Serialize, new)]
|
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, Hash, Deserialize, Serialize, new)]
|
||||||
|
Loading…
Reference in New Issue
Block a user