diff --git a/doc/manual/rl-next/bit-shift-builtins.md b/doc/manual/rl-next/bit-shift-builtins.md new file mode 100644 index 00000000000..ede755bb1bc --- /dev/null +++ b/doc/manual/rl-next/bit-shift-builtins.md @@ -0,0 +1,6 @@ +--- +synopsis: Add bit shifting built-ins +issues: [13000] +--- + +Added left and right bit shifting built-ins. diff --git a/src/libexpr-tests/primops.cc b/src/libexpr-tests/primops.cc index c3e50863d89..d3fb3b67835 100644 --- a/src/libexpr-tests/primops.cc +++ b/src/libexpr-tests/primops.cc @@ -513,6 +513,16 @@ namespace nix { ASSERT_THAT(v, IsIntEq(1)); } + TEST_F(PrimOpTest, bitShiftLeft) { + auto v = eval("builtins.bitShiftLeft 3 2"); + ASSERT_THAT(v, IsIntEq(12)); + } + + TEST_F(PrimOpTest, bitShiftRight) { + auto v = eval("builtins.bitShiftRight 17 3"); + ASSERT_THAT(v, IsIntEq(2)); + } + TEST_F(PrimOpTest, lessThanFalse) { auto v = eval("builtins.lessThan 3 1"); ASSERT_THAT(v, IsFalse()); diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 5e331f84d7d..d19d2e43e65 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -4007,6 +4007,40 @@ static RegisterPrimOp primop_bitXor({ .fun = prim_bitXor, }); +static void prim_bitShiftLeft(EvalState & state, const PosIdx pos, Value * * args, Value & v) +{ + auto i1 = state.forceInt(*args[0], pos, "while evaluating the first argument passed to builtins.bitShiftLeft"); + auto i2 = state.forceInt(*args[1], pos, "while evaluating the second argument passed to builtins.bitShiftLeft"); + + v.mkInt(i1.value << i2.value); +} + +static RegisterPrimOp primop_bitShiftLeft({ + .name = "__bitShiftLeft", + .args = {"e1", "e2"}, + .doc = R"( + Return the integer *e1* shifted left by *e2*. + )", + .fun = prim_bitShiftLeft, +}); + +static void prim_bitShiftRight(EvalState & state, const PosIdx pos, Value * * args, Value & v) +{ + auto i1 = state.forceInt(*args[0], pos, "while evaluating the first argument passed to builtins.bitShiftRight"); + auto i2 = state.forceInt(*args[1], pos, "while evaluating the second argument passed to builtins.bitShiftRight"); + + v.mkInt(i1.value >> i2.value); +} + +static RegisterPrimOp primop_bitShiftRight({ + .name = "__bitShiftRight", + .args = {"e1", "e2"}, + .doc = R"( + Return the integer *e1* shifted right by *e2*. + )", + .fun = prim_bitShiftRight, +}); + static void prim_lessThan(EvalState & state, const PosIdx pos, Value * * args, Value & v) { state.forceValue(*args[0], pos);