mirror of
https://github.com/nushell/nushell.git
synced 2025-08-13 12:37:46 +02:00
Math operators (#1601)
* Add some math operations * WIP for adding compound expressions * precedence parsing * paren expressions * better lhs handling * add compound comparisons and shorthand lefthand parsing * Add or comparison and shorthand paths
This commit is contained in:
@ -31,6 +31,7 @@ pub(crate) fn evaluate_baseline_expr(
|
||||
Expression::Command(_) => evaluate_command(tag, scope),
|
||||
Expression::ExternalCommand(external) => evaluate_external(external, scope),
|
||||
Expression::Binary(binary) => {
|
||||
// TODO: If we want to add short-circuiting, we'll need to move these down
|
||||
let left = evaluate_baseline_expr(&binary.left, registry, scope)?;
|
||||
let right = evaluate_baseline_expr(&binary.right, registry, scope)?;
|
||||
|
||||
@ -103,7 +104,7 @@ pub(crate) fn evaluate_baseline_expr(
|
||||
return Err(ShellError::labeled_error(
|
||||
"Unknown column",
|
||||
format!("did you mean '{}'?", possible_matches[0].1),
|
||||
&tag,
|
||||
&member.span,
|
||||
));
|
||||
} else {
|
||||
return Err(err);
|
||||
|
@ -1,30 +1,43 @@
|
||||
use crate::data::value;
|
||||
use nu_protocol::hir::CompareOperator;
|
||||
use nu_protocol::hir::Operator;
|
||||
use nu_protocol::{Primitive, ShellTypeName, UntaggedValue, Value};
|
||||
use std::ops::Not;
|
||||
|
||||
pub fn apply_operator(
|
||||
op: CompareOperator,
|
||||
op: Operator,
|
||||
left: &Value,
|
||||
right: &Value,
|
||||
) -> Result<UntaggedValue, (&'static str, &'static str)> {
|
||||
match op {
|
||||
CompareOperator::Equal
|
||||
| CompareOperator::NotEqual
|
||||
| CompareOperator::LessThan
|
||||
| CompareOperator::GreaterThan
|
||||
| CompareOperator::LessThanOrEqual
|
||||
| CompareOperator::GreaterThanOrEqual => {
|
||||
Operator::Equal
|
||||
| Operator::NotEqual
|
||||
| Operator::LessThan
|
||||
| Operator::GreaterThan
|
||||
| Operator::LessThanOrEqual
|
||||
| Operator::GreaterThanOrEqual => {
|
||||
value::compare_values(op, left, right).map(UntaggedValue::boolean)
|
||||
}
|
||||
CompareOperator::Contains => contains(left, right).map(UntaggedValue::boolean),
|
||||
CompareOperator::NotContains => contains(left, right)
|
||||
Operator::Contains => string_contains(left, right).map(UntaggedValue::boolean),
|
||||
Operator::NotContains => string_contains(left, right)
|
||||
.map(Not::not)
|
||||
.map(UntaggedValue::boolean),
|
||||
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::Divide => value::compute_values(op, left, right),
|
||||
Operator::In => table_contains(left, right).map(UntaggedValue::boolean),
|
||||
Operator::And => match (left.as_bool(), right.as_bool()) {
|
||||
(Ok(left), Ok(right)) => Ok(UntaggedValue::boolean(left && right)),
|
||||
_ => Err((left.type_name(), right.type_name())),
|
||||
},
|
||||
Operator::Or => match (left.as_bool(), right.as_bool()) {
|
||||
(Ok(left), Ok(right)) => Ok(UntaggedValue::boolean(left || right)),
|
||||
_ => Err((left.type_name(), right.type_name())),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn contains(
|
||||
fn string_contains(
|
||||
left: &UntaggedValue,
|
||||
right: &UntaggedValue,
|
||||
) -> Result<bool, (&'static str, &'static str)> {
|
||||
@ -48,3 +61,14 @@ fn contains(
|
||||
_ => Err((left.type_name(), right.type_name())),
|
||||
}
|
||||
}
|
||||
|
||||
fn table_contains(
|
||||
left: &UntaggedValue,
|
||||
right: &UntaggedValue,
|
||||
) -> Result<bool, (&'static str, &'static str)> {
|
||||
let left = left.clone();
|
||||
match right {
|
||||
UntaggedValue::Table(values) => Ok(values.iter().any(|x| x.value == left)),
|
||||
_ => Err((left.type_name(), right.type_name())),
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user