difftreelog
fix(parser) desugar == to std.equals
in: master
4 files changed
crates/jsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth--- a/crates/jsonnet-evaluator/src/evaluate.rs
+++ b/crates/jsonnet-evaluator/src/evaluate.rs
@@ -5,9 +5,8 @@
};
use closure::closure;
use jsonnet_parser::{
- el, Arg, ArgsDesc, AssertStmt, BinaryOpType, BindSpec, CompSpec, Expr, FieldMember,
- ForSpecData, IfSpecData, LiteralType, LocExpr, Member, ObjBody, ParamsDesc, UnaryOpType,
- Visibility,
+ ArgsDesc, AssertStmt, BinaryOpType, BindSpec, CompSpec, Expr, FieldMember, ForSpecData,
+ IfSpecData, LiteralType, LocExpr, Member, ObjBody, ParamsDesc, UnaryOpType, Visibility,
};
use std::{
collections::{BTreeMap, HashMap},
@@ -102,55 +101,20 @@
match (evaluate(context.clone(), &a)?.unwrap_if_lazy()?, op, b) {
(Val::Bool(true), BinaryOpType::Or, _o) => Val::Bool(true),
(Val::Bool(false), BinaryOpType::And, _o) => Val::Bool(false),
- (a, op, eb) => evaluate_binary_op_normal(
- context.clone(),
- &a,
- op,
- &evaluate(context, eb)?.unwrap_if_lazy()?,
- )?,
+ (a, op, eb) => {
+ evaluate_binary_op_normal(&a, op, &evaluate(context, eb)?.unwrap_if_lazy()?)?
+ }
},
)
}
-pub fn evaluate_binary_op_normal(
- context: Context,
- a: &Val,
- op: BinaryOpType,
- b: &Val,
-) -> Result<Val> {
+pub fn evaluate_binary_op_normal(a: &Val, op: BinaryOpType, b: &Val) -> Result<Val> {
Ok(match (a, op, b) {
(a, BinaryOpType::Add, b) => evaluate_add_op(a, b)?,
-
- (Val::Str(v1), BinaryOpType::Eq, Val::Str(v2)) => Val::Bool(v1 == v2),
- (Val::Str(v1), BinaryOpType::Ne, Val::Str(v2)) => Val::Bool(v1 != v2),
(Val::Str(v1), BinaryOpType::Mul, Val::Num(v2)) => Val::Str(v1.repeat(*v2 as usize)),
- (Val::Str(format), BinaryOpType::Mod, args) => evaluate(
- context
- .with_var("__tmp__format__".to_owned(), Val::Str(format.to_owned()))?
- .with_var(
- "__tmp__args__".to_owned(),
- match args {
- Val::Arr(v) => Val::Arr(v.clone()),
- v => Val::Arr(vec![v.clone()]),
- },
- )?,
- &el!(Expr::Apply(
- el!(Expr::Index(
- el!(Expr::Var("std".to_owned())),
- el!(Expr::Str("format".to_owned()))
- )),
- ArgsDesc(vec![
- Arg(None, el!(Expr::Var("__tmp__format__".to_owned()))),
- Arg(None, el!(Expr::Var("__tmp__args__".to_owned())))
- ])
- )),
- )?,
// Bool X Bool
- (Val::Bool(a), BinaryOpType::Eq, Val::Bool(b)) => Val::Bool(a == b),
- (Val::Bool(a), BinaryOpType::Ne, Val::Bool(b)) => Val::Bool(a != b),
-
(Val::Bool(a), BinaryOpType::And, Val::Bool(b)) => Val::Bool(*a && *b),
(Val::Bool(a), BinaryOpType::Or, Val::Bool(b)) => Val::Bool(*a || *b),
@@ -163,7 +127,6 @@
// Num X Num
(Val::Num(v1), BinaryOpType::Mul, Val::Num(v2)) => Val::Num(v1 * v2),
(Val::Num(v1), BinaryOpType::Div, Val::Num(v2)) => Val::Num(v1 / v2),
- (Val::Num(v1), BinaryOpType::Mod, Val::Num(v2)) => Val::Num(v1 % v2),
(Val::Num(v1), BinaryOpType::Sub, Val::Num(v2)) => Val::Num(v1 - v2),
@@ -171,9 +134,6 @@
(Val::Num(v1), BinaryOpType::Gt, Val::Num(v2)) => Val::Bool(v1 > v2),
(Val::Num(v1), BinaryOpType::Lte, Val::Num(v2)) => Val::Bool(v1 <= v2),
(Val::Num(v1), BinaryOpType::Gte, Val::Num(v2)) => Val::Bool(v1 >= v2),
-
- (Val::Num(v1), BinaryOpType::Eq, Val::Num(v2)) => Val::Bool((v1 - v2).abs() < f64::EPSILON),
- (Val::Num(v1), BinaryOpType::Ne, Val::Num(v2)) => Val::Bool((v1 - v2).abs() > f64::EPSILON),
(Val::Num(v1), BinaryOpType::BitAnd, Val::Num(v2)) => {
Val::Num(((*v1 as i32) & (*v2 as i32)) as f64)
@@ -191,28 +151,6 @@
Val::Num(((*v1 as i32) >> (*v2 as i32)) as f64)
}
- // Arr X Arr
- (Val::Arr(a), BinaryOpType::Eq, Val::Arr(b)) => {
- if a.len() != b.len() {
- Val::Bool(false)
- } else {
- for i in 0..a.len() {
- if let Val::Bool(v) = evaluate_binary_op_normal(
- context.clone(),
- &a[i].clone().unwrap_if_lazy()?,
- op,
- &b[i].clone().unwrap_if_lazy()?,
- )? {
- if !v {
- return Ok(Val::Bool(false));
- }
- } else {
- unreachable!()
- }
- }
- return Ok(Val::Bool(true));
- }
- }
_ => panic!("no rules for binary operation: {:?} {:?} {:?}", a, op, b),
})
}
@@ -385,7 +323,7 @@
Index(value, index) => {
match (
evaluate(context.clone(), value)?.unwrap_if_lazy()?,
- evaluate(context.clone(), index)?,
+ evaluate(context, index)?,
) {
(Val::Obj(v), Val::Str(s)) => {
if let Some(v) = v.get(&s)? {
@@ -506,9 +444,17 @@
panic!("bad objectFieldsEx call");
}
}
+ ("std", "primitiveEquals") => {
+ assert_eq!(args.len(), 2);
+ let (a, b) = (
+ evaluate(context.clone(), &args[0].1)?,
+ evaluate(context, &args[1].1)?,
+ );
+ Val::Bool(a == b)
+ }
(ns, name) => panic!("Intristic not found: {}.{}", ns, name),
},
- Val::Func(f) => push(locexpr.clone(), "function call".to_owned(), || {
+ Val::Func(f) => push(locexpr, "function call".to_owned(), || {
f.evaluate(
args.clone()
.into_iter()
@@ -528,10 +474,11 @@
}
Function(params, body) => evaluate_method(context, body, params.clone()),
AssertExpr(AssertStmt(value, msg), returned) => {
- if push(value.clone(), "assertion condition".to_owned(), || {
+ let assertion_result = push(value.clone(), "assertion condition".to_owned(), || {
evaluate(context.clone(), &value)?
.try_cast_bool("assertion condition should be boolean")
- })? {
+ })?;
+ if assertion_result {
push(
returned.clone(),
"assert 'return' branch".to_owned(),
@@ -555,9 +502,10 @@
cond_then,
cond_else,
} => {
- if push(cond.0.clone(), "if condition".to_owned(), || {
+ let condition_result = push(cond.0.clone(), "if condition".to_owned(), || {
evaluate(context.clone(), &cond.0)?.try_cast_bool("if condition should be boolean")
- })? {
+ })?;
+ if condition_result {
push(
cond_then.clone(),
"if condition 'then' branch".to_owned(),
crates/jsonnet-parser/Cargo.tomldiffbeforeafterboth--- a/crates/jsonnet-parser/Cargo.toml
+++ b/crates/jsonnet-parser/Cargo.toml
@@ -7,7 +7,7 @@
[features]
default = []
# Trace peg token parsing
-trace = ["peg/trace"]
+# trace = ["peg/trace"]
# TODO:
# serialize = ["serde"]
crates/jsonnet-parser/src/expr.rsdiffbeforeafterboth--- a/crates/jsonnet-parser/src/expr.rs
+++ b/crates/jsonnet-parser/src/expr.rs
@@ -50,7 +50,7 @@
pub enum BinaryOpType {
Mul,
Div,
- // Mod is desugared to stdlib
+ // Mod is desugared to std.mod
// Mod,
Add,
Sub,
@@ -65,8 +65,9 @@
In,
- Eq,
- Ne,
+ // Eq/Ne is desugared to std.equals
+ // Eq,
+ // Ne,
BitAnd,
BitOr,
crates/jsonnet-parser/src/lib.rsdiffbeforeafterboth230 --230 --231 a:(@) _ "&" _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::BitAnd, b))}231 a:(@) _ "&" _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::BitAnd, b))}232 --232 --233 a:(@) _ "==" _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Eq, b))}233 a:(@) _ "==" _ b:@ {loc_expr_todo!(Expr::Apply(234 el!(Expr::Index(235 el!(Expr::Var("std".to_owned())),236 el!(Expr::Str("equals".to_owned()))237 )), ArgsDesc(vec![Arg(None, a), Arg(None, b)])238 ))}234 a:(@) _ "!=" _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Ne, b))}239 a:(@) _ "!=" _ b:@ {loc_expr_todo!(Expr::UnaryOp(UnaryOpType::Not, el!(Expr::Apply(240 el!(Expr::Index(241 el!(Expr::Var("std".to_owned())),242 el!(Expr::Str("equals".to_owned()))243 )), ArgsDesc(vec![Arg(None, a), Arg(None, b)])244 ))))}235 --245 --236 a:(@) _ "<" _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Lt, b))}246 a:(@) _ "<" _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Lt, b))}237 a:(@) _ ">" _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Gt, b))}247 a:(@) _ ">" _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Gt, b))}389 );399 );390 }400 }391392 #[test]393 fn suffix_comparsion() {394 use Expr::*;395 assert_eq!(396 parse!("std.type(a) == \"string\""),397 el!(BinaryOp(398 el!(Apply(399 el!(Index(400 el!(Var("std".to_owned())),401 el!(Str("type".to_owned()))402 )),403 ArgsDesc(vec![Arg(None, el!(Var("a".to_owned())))])404 )),405 BinaryOpType::Eq,406 el!(Str("string".to_owned()))407 ))408 );409 }410401411 #[test]402 #[test]412 fn array_comp() {403 fn array_comp() {429 )420 )430 }421 }431432 #[test]433 fn array_comp_with_ifs() {434 use Expr::*;435 assert_eq!(436 parse!("[k for k in std.objectFields(patch) if patch[k] == null]"),437 el!(ArrComp(438 el!(Var("k".to_owned())),439 vec![440 CompSpec::ForSpec(ForSpecData(441 "k".to_owned(),442 el!(Apply(443 el!(Index(444 el!(Var("std".to_owned())),445 el!(Str("objectFields".to_owned()))446 )),447 ArgsDesc(vec![Arg(None, el!(Var("patch".to_owned())))])448 ))449 )),450 CompSpec::IfSpec(IfSpecData(el!(BinaryOp(451 el!(Index(452 el!(Var("patch".to_owned())),453 el!(Var("k".to_owned()))454 )),455 BinaryOpType::Eq,456 el!(Literal(LiteralType::Null))457 ))))458 ]459 ))460 );461 }462422463 #[test]423 #[test]464 fn reserved() {424 fn reserved() {