difftreelog
refactor skip desugaring for in operator
in: master
3 files changed
crates/jrsonnet-evaluator/src/evaluate/operator.rsdiffbeforeafterboth1use crate::{equals, evaluate, Context, Val};2use crate::{error::Error::*, throw, Result};3use jrsonnet_parser::{BinaryOpType, LocExpr, UnaryOpType};45pub fn evaluate_unary_op(op: UnaryOpType, b: &Val) -> Result<Val> {6 use UnaryOpType::*;7 use Val::*;8 Ok(match (op, b) {9 (Not, Bool(v)) => Bool(!v),10 (Minus, Num(n)) => Num(-*n),11 (BitNot, Num(n)) => Num(!(*n as i32) as f64),12 (op, o) => throw!(UnaryOperatorDoesNotOperateOnType(op, o.value_type())),13 })14}1516pub fn evaluate_add_op(a: &Val, b: &Val) -> Result<Val> {17 use Val::*;18 Ok(match (a, b) {19 (Str(v1), Str(v2)) => Str(((**v1).to_owned() + v2).into()),2021 // Can't use generic json serialization way, because it depends on number to string concatenation (std.jsonnet:890)22 (Num(n), Str(o)) => Str(format!("{}{}", n, o).into()),23 (Str(o), Num(n)) => Str(format!("{}{}", o, n).into()),2425 (Str(s), o) => Str(format!("{}{}", s, o.clone().to_string()?).into()),26 (o, Str(s)) => Str(format!("{}{}", o.clone().to_string()?, s).into()),2728 (Obj(v1), Obj(v2)) => Obj(v2.extend_from(v1.clone())),29 (Arr(a), Arr(b)) => {30 let mut out = Vec::with_capacity(a.len() + b.len());31 out.extend(a.iter_lazy());32 out.extend(b.iter_lazy());33 Arr(out.into())34 }35 (Num(v1), Num(v2)) => Val::new_checked_num(v1 + v2)?,36 _ => throw!(BinaryOperatorDoesNotOperateOnValues(37 BinaryOpType::Add,38 a.value_type(),39 b.value_type(),40 )),41 })42}4344pub fn evaluate_binary_op_special(45 context: Context,46 a: &LocExpr,47 op: BinaryOpType,48 b: &LocExpr,49) -> Result<Val> {50 use BinaryOpType::*;51 use Val::*;52 Ok(match (evaluate(context.clone(), a)?, op, b) {53 (Bool(true), Or, _o) => Val::Bool(true),54 (Bool(false), And, _o) => Val::Bool(false),55 (a, op, eb) => evaluate_binary_op_normal(&a, op, &evaluate(context, eb)?)?,56 })57}5859pub fn evaluate_binary_op_normal(a: &Val, op: BinaryOpType, b: &Val) -> Result<Val> {60 use BinaryOpType::*;61 use Val::*;62 Ok(match (a, op, b) {63 (a, Add, b) => evaluate_add_op(a, b)?,6465 (a, Eq, b) => Bool(equals(a, b)?),66 (a, Neq, b) => Bool(!equals(a, b)?),6768 (Str(v1), Mul, Num(v2)) => Str(v1.repeat(*v2 as usize).into()),6970 // Bool X Bool71 (Bool(a), And, Bool(b)) => Bool(*a && *b),72 (Bool(a), Or, Bool(b)) => Bool(*a || *b),7374 // Str X Str75 (Str(v1), Lt, Str(v2)) => Bool(v1 < v2),76 (Str(v1), Gt, Str(v2)) => Bool(v1 > v2),77 (Str(v1), Lte, Str(v2)) => Bool(v1 <= v2),78 (Str(v1), Gte, Str(v2)) => Bool(v1 >= v2),7980 // Num X Num81 (Num(v1), Mul, Num(v2)) => Val::new_checked_num(v1 * v2)?,82 (Num(v1), Div, Num(v2)) => {83 if *v2 <= f64::EPSILON {84 throw!(DivisionByZero)85 }86 Val::new_checked_num(v1 / v2)?87 }8889 (Num(v1), Sub, Num(v2)) => Val::new_checked_num(v1 - v2)?,9091 (Num(v1), Lt, Num(v2)) => Bool(v1 < v2),92 (Num(v1), Gt, Num(v2)) => Bool(v1 > v2),93 (Num(v1), Lte, Num(v2)) => Bool(v1 <= v2),94 (Num(v1), Gte, Num(v2)) => Bool(v1 >= v2),9596 (Num(v1), BitAnd, Num(v2)) => Num(((*v1 as i32) & (*v2 as i32)) as f64),97 (Num(v1), BitOr, Num(v2)) => Num(((*v1 as i32) | (*v2 as i32)) as f64),98 (Num(v1), BitXor, Num(v2)) => Num(((*v1 as i32) ^ (*v2 as i32)) as f64),99 (Num(v1), Lhs, Num(v2)) => {100 if *v2 < 0.0 {101 throw!(RuntimeError("shift by negative exponent".into()))102 }103 Num(((*v1 as i32) << (*v2 as i32)) as f64)104 }105 (Num(v1), Rhs, Num(v2)) => {106 if *v2 < 0.0 {107 throw!(RuntimeError("shift by negative exponent".into()))108 }109 Num(((*v1 as i32) >> (*v2 as i32)) as f64)110 }111112 _ => throw!(BinaryOperatorDoesNotOperateOnValues(113 op,114 a.value_type(),115 b.value_type(),116 )),117 })118}1use crate::{equals, evaluate, Context, Val};2use crate::{error::Error::*, throw, Result};3use jrsonnet_parser::{BinaryOpType, LocExpr, UnaryOpType};45pub fn evaluate_unary_op(op: UnaryOpType, b: &Val) -> Result<Val> {6 use UnaryOpType::*;7 use Val::*;8 Ok(match (op, b) {9 (Not, Bool(v)) => Bool(!v),10 (Minus, Num(n)) => Num(-*n),11 (BitNot, Num(n)) => Num(!(*n as i32) as f64),12 (op, o) => throw!(UnaryOperatorDoesNotOperateOnType(op, o.value_type())),13 })14}1516pub fn evaluate_add_op(a: &Val, b: &Val) -> Result<Val> {17 use Val::*;18 Ok(match (a, b) {19 (Str(v1), Str(v2)) => Str(((**v1).to_owned() + v2).into()),2021 // Can't use generic json serialization way, because it depends on number to string concatenation (std.jsonnet:890)22 (Num(n), Str(o)) => Str(format!("{}{}", n, o).into()),23 (Str(o), Num(n)) => Str(format!("{}{}", o, n).into()),2425 (Str(s), o) => Str(format!("{}{}", s, o.clone().to_string()?).into()),26 (o, Str(s)) => Str(format!("{}{}", o.clone().to_string()?, s).into()),2728 (Obj(v1), Obj(v2)) => Obj(v2.extend_from(v1.clone())),29 (Arr(a), Arr(b)) => {30 let mut out = Vec::with_capacity(a.len() + b.len());31 out.extend(a.iter_lazy());32 out.extend(b.iter_lazy());33 Arr(out.into())34 }35 (Num(v1), Num(v2)) => Val::new_checked_num(v1 + v2)?,36 _ => throw!(BinaryOperatorDoesNotOperateOnValues(37 BinaryOpType::Add,38 a.value_type(),39 b.value_type(),40 )),41 })42}4344pub fn evaluate_binary_op_special(45 context: Context,46 a: &LocExpr,47 op: BinaryOpType,48 b: &LocExpr,49) -> Result<Val> {50 use BinaryOpType::*;51 use Val::*;52 Ok(match (evaluate(context.clone(), a)?, op, b) {53 (Bool(true), Or, _o) => Val::Bool(true),54 (Bool(false), And, _o) => Val::Bool(false),55 (a, op, eb) => evaluate_binary_op_normal(&a, op, &evaluate(context, eb)?)?,56 })57}5859pub fn evaluate_binary_op_normal(a: &Val, op: BinaryOpType, b: &Val) -> Result<Val> {60 use BinaryOpType::*;61 use Val::*;62 Ok(match (a, op, b) {63 (Str(a), In, Obj(obj)) => Bool(obj.has_field_ex(a.clone(), true)),6465 (a, Add, b) => evaluate_add_op(a, b)?,6667 (a, Eq, b) => Bool(equals(a, b)?),68 (a, Neq, b) => Bool(!equals(a, b)?),6970 (Str(v1), Mul, Num(v2)) => Str(v1.repeat(*v2 as usize).into()),7172 // Bool X Bool73 (Bool(a), And, Bool(b)) => Bool(*a && *b),74 (Bool(a), Or, Bool(b)) => Bool(*a || *b),7576 // Str X Str77 (Str(v1), Lt, Str(v2)) => Bool(v1 < v2),78 (Str(v1), Gt, Str(v2)) => Bool(v1 > v2),79 (Str(v1), Lte, Str(v2)) => Bool(v1 <= v2),80 (Str(v1), Gte, Str(v2)) => Bool(v1 >= v2),8182 // Num X Num83 (Num(v1), Mul, Num(v2)) => Val::new_checked_num(v1 * v2)?,84 (Num(v1), Div, Num(v2)) => {85 if *v2 <= f64::EPSILON {86 throw!(DivisionByZero)87 }88 Val::new_checked_num(v1 / v2)?89 }9091 (Num(v1), Sub, Num(v2)) => Val::new_checked_num(v1 - v2)?,9293 (Num(v1), Lt, Num(v2)) => Bool(v1 < v2),94 (Num(v1), Gt, Num(v2)) => Bool(v1 > v2),95 (Num(v1), Lte, Num(v2)) => Bool(v1 <= v2),96 (Num(v1), Gte, Num(v2)) => Bool(v1 >= v2),9798 (Num(v1), BitAnd, Num(v2)) => Num(((*v1 as i32) & (*v2 as i32)) as f64),99 (Num(v1), BitOr, Num(v2)) => Num(((*v1 as i32) | (*v2 as i32)) as f64),100 (Num(v1), BitXor, Num(v2)) => Num(((*v1 as i32) ^ (*v2 as i32)) as f64),101 (Num(v1), Lhs, Num(v2)) => {102 if *v2 < 0.0 {103 throw!(RuntimeError("shift by negative exponent".into()))104 }105 Num(((*v1 as i32) << (*v2 as i32)) as f64)106 }107 (Num(v1), Rhs, Num(v2)) => {108 if *v2 < 0.0 {109 throw!(RuntimeError("shift by negative exponent".into()))110 }111 Num(((*v1 as i32) >> (*v2 as i32)) as f64)112 }113114 _ => throw!(BinaryOperatorDoesNotOperateOnValues(115 op,116 a.value_type(),117 b.value_type(),118 )),119 })120}crates/jrsonnet-parser/src/expr.rsdiffbeforeafterboth--- a/crates/jrsonnet-parser/src/expr.rs
+++ b/crates/jrsonnet-parser/src/expr.rs
@@ -127,6 +127,9 @@
And,
Or,
+
+ // Equialent to std.objectHasEx(a, b, true)
+ In,
}
impl Display for BinaryOpType {
@@ -154,6 +157,7 @@
Neq => "!=",
And => "&&",
Or => "||",
+ In => "in",
}
)
}
crates/jrsonnet-parser/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-parser/src/lib.rs
+++ b/crates/jrsonnet-parser/src/lib.rs
@@ -217,38 +217,37 @@
rule unaryop(x: rule<()>) -> ()
= quiet!{ x() } / expected!("<unary op>")
+
+ use BinaryOpType::*;
rule expr(s: &ParserSettings) -> LocExpr
= start:position!() a:precedence! {
- a:(@) _ binop(<"||">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Or, b))}
+ a:(@) _ binop(<"||">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, Or, b))}
--
- a:(@) _ binop(<"&&">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::And, b))}
+ a:(@) _ binop(<"&&">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, And, b))}
--
- a:(@) _ binop(<"|">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::BitOr, b))}
+ a:(@) _ binop(<"|">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BitOr, b))}
--
- a:@ _ binop(<"^">) _ b:(@) {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::BitXor, b))}
+ a:@ _ binop(<"^">) _ b:(@) {loc_expr_todo!(Expr::BinaryOp(a, BitXor, b))}
--
- a:(@) _ binop(<"&">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::BitAnd, b))}
+ a:(@) _ binop(<"&">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BitAnd, b))}
--
- a:(@) _ binop(<"==">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Eq, b))}
- a:(@) _ binop(<"!=">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Neq, b))}
+ a:(@) _ binop(<"==">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, Eq, b))}
+ a:(@) _ binop(<"!=">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, Neq, b))}
--
- a:(@) _ binop(<"<">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Lt, b))}
- a:(@) _ binop(<">">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Gt, b))}
- a:(@) _ binop(<"<=">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Lte, b))}
- a:(@) _ binop(<">=">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Gte, b))}
- a:(@) _ binop(<keyword("in")>) _ b:@ {loc_expr_todo!(Expr::Apply(
- el!(Expr::Intrinsic("objectHasEx".into())), ArgsDesc(vec![Arg(None, b), Arg(None, a), Arg(None, el!(Expr::Literal(LiteralType::True)))]),
- true
- ))}
+ a:(@) _ binop(<"<">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, Lt, b))}
+ a:(@) _ binop(<">">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, Gt, b))}
+ a:(@) _ binop(<"<=">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, Lte, b))}
+ a:(@) _ binop(<">=">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, Gte, b))}
+ a:(@) _ binop(<keyword("in")>) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, In, b))}
--
- a:(@) _ binop(<"<<">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Lhs, b))}
- a:(@) _ binop(<">>">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Rhs, b))}
+ a:(@) _ binop(<"<<">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, Lhs, b))}
+ a:(@) _ binop(<">>">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, Rhs, b))}
--
- a:(@) _ binop(<"+">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Add, b))}
- a:(@) _ binop(<"-">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Sub, b))}
+ a:(@) _ binop(<"+">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, Add, b))}
+ a:(@) _ binop(<"-">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, Sub, b))}
--
- a:(@) _ binop(<"*">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Mul, b))}
- a:(@) _ binop(<"/">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Div, b))}
+ a:(@) _ binop(<"*">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, Mul, b))}
+ a:(@) _ binop(<"/">) _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, Div, b))}
a:(@) _ binop(<"%">) _ b:@ {loc_expr_todo!(Expr::Apply(
el!(Expr::Intrinsic("mod".into())), ArgsDesc(vec![Arg(None, a), Arg(None, b)]),
false
@@ -306,6 +305,7 @@
use super::{expr::*, parse};
use crate::ParserSettings;
use std::path::PathBuf;
+ use BinaryOpType::*;
macro_rules! parse {
($s:expr) => {
@@ -326,10 +326,10 @@
pub fn basic_math() -> LocExpr {
el!(Expr::BinaryOp(
el!(Expr::Num(2.0)),
- BinaryOpType::Add,
+ Add,
el!(Expr::BinaryOp(
el!(Expr::Num(2.0)),
- BinaryOpType::Mul,
+ Mul,
el!(Expr::Num(2.0)),
)),
))
@@ -417,10 +417,10 @@
parse!("2+2*2"),
el!(Expr::BinaryOp(
el!(Expr::Num(2.0)),
- BinaryOpType::Add,
+ Add,
el!(Expr::BinaryOp(
el!(Expr::Num(2.0)),
- BinaryOpType::Mul,
+ Mul,
el!(Expr::Num(2.0))
))
))
@@ -438,7 +438,7 @@
parse!("2+(2+2*2)"),
el!(Expr::BinaryOp(
el!(Expr::Num(2.0)),
- BinaryOpType::Add,
+ Add,
el!(Expr::Parened(expressions::basic_math())),
))
);
@@ -451,10 +451,10 @@
parse!("2//comment\n+//comment\n3/*test*/*/*test*/4"),
el!(Expr::BinaryOp(
el!(Expr::Num(2.0)),
- BinaryOpType::Add,
+ Add,
el!(Expr::BinaryOp(
el!(Expr::Num(3.0)),
- BinaryOpType::Mul,
+ Mul,
el!(Expr::Num(4.0))
))
))
@@ -468,7 +468,7 @@
parse!("2/*\\*/+*/ - 22"),
el!(Expr::BinaryOp(
el!(Expr::Num(2.0)),
- BinaryOpType::Sub,
+ Sub,
el!(Expr::Num(22.0))
))
);
@@ -520,7 +520,7 @@
parse!("!a && !b"),
el!(BinaryOp(
el!(UnaryOp(UnaryOpType::Not, el!(Var("a".into())))),
- BinaryOpType::And,
+ And,
el!(UnaryOp(UnaryOpType::Not, el!(Var("b".into()))))
))
);
@@ -533,7 +533,7 @@
parse!("!a / !b"),
el!(BinaryOp(
el!(UnaryOp(UnaryOpType::Not, el!(Var("a".into())))),
- BinaryOpType::Div,
+ Div,
el!(UnaryOp(UnaryOpType::Not, el!(Var("b".into()))))
))
);