Merge remote-tracking branch 'origin/master' into cleanup-wip

This commit is contained in:
Yehuda Katz
2019-11-25 19:25:12 -08:00
15 changed files with 788 additions and 536 deletions

View File

@ -1,5 +1,6 @@
use crate::data::base::Block;
use crate::errors::ArgumentError;
use crate::evaluate::operator::apply_operator;
use crate::parser::hir::path::{ColumnPath, UnspannedPathMember};
use crate::parser::{
hir::{self, Expression, RawExpression},
@ -71,8 +72,8 @@ pub(crate) fn evaluate_baseline_expr(
trace!("left={:?} right={:?}", left.value, right.value);
match left.compare(binary.op(), &right) {
Ok(result) => Ok(UntaggedValue::boolean(result).into_value(tag)),
match apply_operator(binary.op(), &left, &right) {
Ok(result) => Ok(result.into_value(tag)),
Err((left_type, right_type)) => Err(ShellError::coerce_error(
left_type.spanned(binary.left().span),
right_type.spanned(binary.right().span),

View File

@ -1,3 +1,4 @@
pub(crate) mod evaluator;
pub(crate) mod operator;
pub(crate) use evaluator::{evaluate_baseline_expr, Scope};

39
src/evaluate/operator.rs Normal file
View File

@ -0,0 +1,39 @@
use crate::data::base::{Primitive, UntaggedValue, Value};
use crate::parser::Operator;
use crate::traits::ShellTypeName;
use std::ops::Not;
pub fn apply_operator(
op: &Operator,
left: &Value,
right: &Value,
) -> Result<UntaggedValue, (&'static str, &'static str)> {
match *op {
Operator::Equal
| Operator::NotEqual
| Operator::LessThan
| Operator::GreaterThan
| Operator::LessThanOrEqual
| Operator::GreaterThanOrEqual => left.compare(op, right).map(UntaggedValue::boolean),
Operator::Dot => Ok(UntaggedValue::boolean(false)),
Operator::Contains => contains(left, right).map(UntaggedValue::boolean),
Operator::NotContains => contains(left, right)
.map(Not::not)
.map(UntaggedValue::boolean),
}
}
fn contains(
left: &UntaggedValue,
right: &UntaggedValue,
) -> Result<bool, (&'static str, &'static str)> {
if let (
UntaggedValue::Primitive(Primitive::String(l)),
UntaggedValue::Primitive(Primitive::String(r)),
) = (left, right)
{
Ok(l.contains(r))
} else {
Err((left.type_name(), right.type_name()))
}
}