/** * @file value_bitwise.c * @brief Tests the bitwise operators and their type guards. */ #include #include #include #include "testutil.h" static akbasic_Value A; static akbasic_Value B; static akbasic_Value SCRATCH; static void set_int(akbasic_Value *v, int64_t n) { test_discard_error(akbasic_value_zero(v)); v->valuetype = AKBASIC_TYPE_INTEGER; v->intval = n; } int main(void) { akbasic_Value *out = NULL; TEST_REQUIRE_OK(akbasic_error_register()); set_int(&A, 0x0F); set_int(&B, 0x33); TEST_REQUIRE_OK(akbasic_value_bitwise_and(&A, &B, &SCRATCH, &out)); TEST_REQUIRE_INT(out->intval, 0x03); TEST_REQUIRE_OK(akbasic_value_bitwise_or(&A, &B, &SCRATCH, &out)); TEST_REQUIRE_INT(out->intval, 0x3F); TEST_REQUIRE_OK(akbasic_value_bitwise_xor(&A, &B, &SCRATCH, &out)); TEST_REQUIRE_INT(out->intval, 0x3C); set_int(&A, 1); TEST_REQUIRE_OK(akbasic_value_shift_left(&A, 8, &SCRATCH, &out)); TEST_REQUIRE_INT(out->intval, 256); set_int(&A, 256); TEST_REQUIRE_OK(akbasic_value_shift_right(&A, 8, &SCRATCH, &out)); TEST_REQUIRE_INT(out->intval, 1); set_int(&A, 0); TEST_REQUIRE_OK(akbasic_value_bitwise_not(&A, &SCRATCH, &out)); TEST_REQUIRE_INT(out->intval, -1); /* * Go's shift is defined for any count; C's is not. Refusing an out-of-range * count is a deliberate deviation from the reference, which would have * produced a defined (if useless) answer where C would produce UB. */ set_int(&A, 1); TEST_REQUIRE_STATUS(akbasic_value_shift_left(&A, 64, &SCRATCH, &out), AKBASIC_ERR_VALUE); TEST_REQUIRE_STATUS(akbasic_value_shift_left(&A, -1, &SCRATCH, &out), AKBASIC_ERR_VALUE); TEST_REQUIRE_STATUS(akbasic_value_shift_right(&A, 64, &SCRATCH, &out), AKBASIC_ERR_VALUE); /* Bitwise operations are integers-only. */ test_discard_error(akbasic_value_zero(&A)); A.valuetype = AKBASIC_TYPE_FLOAT; A.floatval = 1.0; set_int(&B, 1); TEST_REQUIRE_STATUS(akbasic_value_bitwise_and(&A, &B, &SCRATCH, &out), AKBASIC_ERR_TYPE); TEST_REQUIRE_STATUS(akbasic_value_bitwise_or(&A, &B, &SCRATCH, &out), AKBASIC_ERR_TYPE); TEST_REQUIRE_STATUS(akbasic_value_bitwise_xor(&A, &B, &SCRATCH, &out), AKBASIC_ERR_TYPE); TEST_REQUIRE_STATUS(akbasic_value_bitwise_not(&A, &SCRATCH, &out), AKBASIC_ERR_TYPE); TEST_REQUIRE_STATUS(akbasic_value_shift_left(&A, 1, &SCRATCH, &out), AKBASIC_ERR_TYPE); return akbasic_test_failures; }