difftreelog
fix(parser) desugar == to std.equals
in: master
4 files changed
crates/jsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth5};5};6use closure::closure;6use closure::closure;7use jsonnet_parser::{7use jsonnet_parser::{8 el, Arg, ArgsDesc, AssertStmt, BinaryOpType, BindSpec, CompSpec, Expr, FieldMember,8 ArgsDesc, AssertStmt, BinaryOpType, BindSpec, CompSpec, Expr, FieldMember, ForSpecData,9 ForSpecData, IfSpecData, LiteralType, LocExpr, Member, ObjBody, ParamsDesc, UnaryOpType,9 IfSpecData, LiteralType, LocExpr, Member, ObjBody, ParamsDesc, UnaryOpType, Visibility,10 Visibility,11};10};102 match (evaluate(context.clone(), &a)?.unwrap_if_lazy()?, op, b) {101 match (evaluate(context.clone(), &a)?.unwrap_if_lazy()?, op, b) {103 (Val::Bool(true), BinaryOpType::Or, _o) => Val::Bool(true),102 (Val::Bool(true), BinaryOpType::Or, _o) => Val::Bool(true),104 (Val::Bool(false), BinaryOpType::And, _o) => Val::Bool(false),103 (Val::Bool(false), BinaryOpType::And, _o) => Val::Bool(false),105 (a, op, eb) => evaluate_binary_op_normal(104 (a, op, eb) => {106 context.clone(),107 &a,105 evaluate_binary_op_normal(&a, op, &evaluate(context, eb)?.unwrap_if_lazy()?)?108 op,106 }109 &evaluate(context, eb)?.unwrap_if_lazy()?,110 )?,111 },107 },112 )108 )113}109}114110115pub fn evaluate_binary_op_normal(111pub fn evaluate_binary_op_normal(a: &Val, op: BinaryOpType, b: &Val) -> Result<Val> {116 context: Context,117 a: &Val,118 op: BinaryOpType,119 b: &Val,120) -> Result<Val> {121 Ok(match (a, op, b) {112 Ok(match (a, op, b) {122 (a, BinaryOpType::Add, b) => evaluate_add_op(a, b)?,113 (a, BinaryOpType::Add, b) => evaluate_add_op(a, b)?,123124 (Val::Str(v1), BinaryOpType::Eq, Val::Str(v2)) => Val::Bool(v1 == v2),125 (Val::Str(v1), BinaryOpType::Ne, Val::Str(v2)) => Val::Bool(v1 != v2),126114127 (Val::Str(v1), BinaryOpType::Mul, Val::Num(v2)) => Val::Str(v1.repeat(*v2 as usize)),115 (Val::Str(v1), BinaryOpType::Mul, Val::Num(v2)) => Val::Str(v1.repeat(*v2 as usize)),128 (Val::Str(format), BinaryOpType::Mod, args) => evaluate(129 context130 .with_var("__tmp__format__".to_owned(), Val::Str(format.to_owned()))?131 .with_var(132 "__tmp__args__".to_owned(),133 match args {134 Val::Arr(v) => Val::Arr(v.clone()),135 v => Val::Arr(vec![v.clone()]),136 },137 )?,138 &el!(Expr::Apply(139 el!(Expr::Index(140 el!(Expr::Var("std".to_owned())),141 el!(Expr::Str("format".to_owned()))142 )),143 ArgsDesc(vec![144 Arg(None, el!(Expr::Var("__tmp__format__".to_owned()))),145 Arg(None, el!(Expr::Var("__tmp__args__".to_owned())))146 ])147 )),148 )?,149116150 // Bool X Bool117 // Bool X Bool151 (Val::Bool(a), BinaryOpType::Eq, Val::Bool(b)) => Val::Bool(a == b),152 (Val::Bool(a), BinaryOpType::Ne, Val::Bool(b)) => Val::Bool(a != b),153154 (Val::Bool(a), BinaryOpType::And, Val::Bool(b)) => Val::Bool(*a && *b),118 (Val::Bool(a), BinaryOpType::And, Val::Bool(b)) => Val::Bool(*a && *b),155 (Val::Bool(a), BinaryOpType::Or, Val::Bool(b)) => Val::Bool(*a || *b),119 (Val::Bool(a), BinaryOpType::Or, Val::Bool(b)) => Val::Bool(*a || *b),163 // Num X Num127 // Num X Num164 (Val::Num(v1), BinaryOpType::Mul, Val::Num(v2)) => Val::Num(v1 * v2),128 (Val::Num(v1), BinaryOpType::Mul, Val::Num(v2)) => Val::Num(v1 * v2),165 (Val::Num(v1), BinaryOpType::Div, Val::Num(v2)) => Val::Num(v1 / v2),129 (Val::Num(v1), BinaryOpType::Div, Val::Num(v2)) => Val::Num(v1 / v2),166 (Val::Num(v1), BinaryOpType::Mod, Val::Num(v2)) => Val::Num(v1 % v2),167130168 (Val::Num(v1), BinaryOpType::Sub, Val::Num(v2)) => Val::Num(v1 - v2),131 (Val::Num(v1), BinaryOpType::Sub, Val::Num(v2)) => Val::Num(v1 - v2),169132172 (Val::Num(v1), BinaryOpType::Lte, Val::Num(v2)) => Val::Bool(v1 <= v2),135 (Val::Num(v1), BinaryOpType::Lte, Val::Num(v2)) => Val::Bool(v1 <= v2),173 (Val::Num(v1), BinaryOpType::Gte, Val::Num(v2)) => Val::Bool(v1 >= v2),136 (Val::Num(v1), BinaryOpType::Gte, Val::Num(v2)) => Val::Bool(v1 >= v2),174175 (Val::Num(v1), BinaryOpType::Eq, Val::Num(v2)) => Val::Bool((v1 - v2).abs() < f64::EPSILON),176 (Val::Num(v1), BinaryOpType::Ne, Val::Num(v2)) => Val::Bool((v1 - v2).abs() > f64::EPSILON),177137178 (Val::Num(v1), BinaryOpType::BitAnd, Val::Num(v2)) => {138 (Val::Num(v1), BinaryOpType::BitAnd, Val::Num(v2)) => {179 Val::Num(((*v1 as i32) & (*v2 as i32)) as f64)139 Val::Num(((*v1 as i32) & (*v2 as i32)) as f64)191 Val::Num(((*v1 as i32) >> (*v2 as i32)) as f64)151 Val::Num(((*v1 as i32) >> (*v2 as i32)) as f64)192 }152 }193153194 // Arr X Arr195 (Val::Arr(a), BinaryOpType::Eq, Val::Arr(b)) => {196 if a.len() != b.len() {197 Val::Bool(false)198 } else {199 for i in 0..a.len() {200 if let Val::Bool(v) = evaluate_binary_op_normal(201 context.clone(),202 &a[i].clone().unwrap_if_lazy()?,203 op,204 &b[i].clone().unwrap_if_lazy()?,205 )? {206 if !v {207 return Ok(Val::Bool(false));208 }209 } else {210 unreachable!()211 }212 }213 return Ok(Val::Bool(true));214 }215 }216 _ => panic!("no rules for binary operation: {:?} {:?} {:?}", a, op, b),154 _ => panic!("no rules for binary operation: {:?} {:?} {:?}", a, op, b),217 })155 })218}156}385 Index(value, index) => {323 Index(value, index) => {386 match (324 match (387 evaluate(context.clone(), value)?.unwrap_if_lazy()?,325 evaluate(context.clone(), value)?.unwrap_if_lazy()?,388 evaluate(context.clone(), index)?,326 evaluate(context, index)?,389 ) {327 ) {390 (Val::Obj(v), Val::Str(s)) => {328 (Val::Obj(v), Val::Str(s)) => {391 if let Some(v) = v.get(&s)? {329 if let Some(v) = v.get(&s)? {506 panic!("bad objectFieldsEx call");444 panic!("bad objectFieldsEx call");507 }445 }508 }446 }447 ("std", "primitiveEquals") => {448 assert_eq!(args.len(), 2);449 let (a, b) = (450 evaluate(context.clone(), &args[0].1)?,451 evaluate(context, &args[1].1)?,452 );453 Val::Bool(a == b)454 }509 (ns, name) => panic!("Intristic not found: {}.{}", ns, name),455 (ns, name) => panic!("Intristic not found: {}.{}", ns, name),510 },456 },511 Val::Func(f) => push(locexpr.clone(), "function call".to_owned(), || {457 Val::Func(f) => push(locexpr, "function call".to_owned(), || {512 f.evaluate(458 f.evaluate(513 args.clone()459 args.clone()514 .into_iter()460 .into_iter()528 }474 }529 Function(params, body) => evaluate_method(context, body, params.clone()),475 Function(params, body) => evaluate_method(context, body, params.clone()),530 AssertExpr(AssertStmt(value, msg), returned) => {476 AssertExpr(AssertStmt(value, msg), returned) => {531 if push(value.clone(), "assertion condition".to_owned(), || {477 let assertion_result = push(value.clone(), "assertion condition".to_owned(), || {532 evaluate(context.clone(), &value)?478 evaluate(context.clone(), &value)?533 .try_cast_bool("assertion condition should be boolean")479 .try_cast_bool("assertion condition should be boolean")534 })? {480 })?;481 if assertion_result {535 push(482 push(536 returned.clone(),483 returned.clone(),537 "assert 'return' branch".to_owned(),484 "assert 'return' branch".to_owned(),555 cond_then,502 cond_then,556 cond_else,503 cond_else,557 } => {504 } => {558 if push(cond.0.clone(), "if condition".to_owned(), || {505 let condition_result = push(cond.0.clone(), "if condition".to_owned(), || {559 evaluate(context.clone(), &cond.0)?.try_cast_bool("if condition should be boolean")506 evaluate(context.clone(), &cond.0)?.try_cast_bool("if condition should be boolean")560 })? {507 })?;508 if condition_result {561 push(509 push(562 cond_then.clone(),510 cond_then.clone(),563 "if condition 'then' branch".to_owned(),511 "if condition 'then' branch".to_owned(),crates/jsonnet-parser/Cargo.tomldiffbeforeafterboth7[features]7[features]8default = []8default = []9# Trace peg token parsing9# Trace peg token parsing10trace = ["peg/trace"]10# trace = ["peg/trace"]11# TODO:11# TODO:12# serialize = ["serde"]12# serialize = ["serde"]1313crates/jsonnet-parser/src/expr.rsdiffbeforeafterboth50pub enum BinaryOpType {50pub enum BinaryOpType {51 Mul,51 Mul,52 Div,52 Div,53 // Mod is desugared to stdlib53 // Mod is desugared to std.mod54 // Mod,54 // Mod,55 Add,55 Add,56 Sub,56 Sub,656566 In,66 In,676768 Eq,68 // Eq/Ne is desugared to std.equals69 Ne,69 // Eq,70 // Ne,707171 BitAnd,72 BitAnd,72 BitOr,73 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() {