--- a/crates/jrsonnet-evaluator/src/evaluate/operator.rs +++ b/crates/jrsonnet-evaluator/src/evaluate/operator.rs @@ -17,9 +17,10 @@ use UnaryOpType::*; use Val::*; Ok(match (op, b) { - (Not, Bool(v)) => Bool(!v), + (Plus, Num(n)) => Num(*n), (Minus, Num(n)) => Num(-*n), - (BitNot, Num(n)) => Num(f64::from(!(*n as i32))), + (Not, Bool(v)) => Bool(!v), + (BitNot, Num(n)) => Num(!(*n as i64) as f64), (op, o) => throw!(UnaryOperatorDoesNotOperateOnType(op, o.value_type())), }) } @@ -29,7 +30,6 @@ Ok(match (a, b) { (Str(v1), Str(v2)) => Str(StrValue::concat(v1.clone(), v2.clone())), - // Can't use generic json serialization way, because it depends on number to string concatenation (std.jsonnet:890) (Num(a), Str(b)) => Str(StrValue::Flat(format!("{a}{b}").into())), (Str(a), Num(b)) => Str(StrValue::Flat(format!("{a}{b}").into())), @@ -166,20 +166,22 @@ (Num(v1), Sub, Num(v2)) => Val::new_checked_num(v1 - v2)?, - (Num(v1), BitAnd, Num(v2)) => Num(f64::from((*v1 as i32) & (*v2 as i32))), - (Num(v1), BitOr, Num(v2)) => Num(f64::from((*v1 as i32) | (*v2 as i32))), - (Num(v1), BitXor, Num(v2)) => Num(f64::from((*v1 as i32) ^ (*v2 as i32))), + (Num(v1), BitAnd, Num(v2)) => Num((*v1 as i64 & *v2 as i64) as f64), + (Num(v1), BitOr, Num(v2)) => Num((*v1 as i64 | *v2 as i64) as f64), + (Num(v1), BitXor, Num(v2)) => Num((*v1 as i64 ^ *v2 as i64) as f64), (Num(v1), Lhs, Num(v2)) => { if *v2 < 0.0 { throw!("shift by negative exponent") } - Num(f64::from((*v1 as i32) << (*v2 as i32))) + let exp = ((*v2 as i64) & 63) as u32; + Num((*v1 as i64).wrapping_shl(exp) as f64) } (Num(v1), Rhs, Num(v2)) => { if *v2 < 0.0 { throw!("shift by negative exponent") } - Num(f64::from((*v1 as i32) >> (*v2 as i32))) + let exp = ((*v2 as i64) & 63) as u32; + Num((*v1 as i64).wrapping_shr(exp) as f64) } // Bigint X Bigint --- a/crates/jrsonnet-parser/src/lib.rs +++ b/crates/jrsonnet-parser/src/lib.rs @@ -332,6 +332,7 @@ a:(@) _ binop(<"/">) _ b:@ {expr_bin!(a Div b)} a:(@) _ binop(<"%">) _ b:@ {expr_bin!(a Mod b)} -- + unaryop(<"+">) _ b:@ {expr_un!(Plus b)} unaryop(<"-">) _ b:@ {expr_un!(Minus b)} unaryop(<"!">) _ b:@ {expr_un!(Not b)} unaryop(<"~">) _ b:@ {expr_un!(BitNot b)} --- /dev/null +++ b/tests/golden/issue126.jsonnet @@ -0,0 +1,4 @@ +{ + int_lhs: 1 << 32, + unary_plus: +1, +} --- /dev/null +++ b/tests/golden/issue126.jsonnet.golden @@ -0,0 +1,4 @@ +{ + "int_lhs": 4294967296, + "unary_plus": 1 +} \ No newline at end of file