diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-02-04 09:37:56 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-02-04 09:37:56 -0800 |
commit | 74bba68f37f7d621bb9830bbbcef35cef04a6322 (patch) | |
tree | 19f0412f48f2ffa843b919eb6819c4cf14121610 /022arithmetic.cc | |
parent | 8bd4d8dd7c1241b73a7473cd35fae00b664bda05 (diff) | |
download | mu-74bba68f37f7d621bb9830bbbcef35cef04a6322.tar.gz |
2627 - bitwise operators
Diffstat (limited to '022arithmetic.cc')
-rw-r--r-- | 022arithmetic.cc | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/022arithmetic.cc b/022arithmetic.cc index badd298a..5f158517 100644 --- a/022arithmetic.cc +++ b/022arithmetic.cc @@ -363,6 +363,38 @@ case SHIFT_LEFT: { break; } +:(scenario shift_left_by_zero) +recipe main [ + 1:number <- shift-left 1, 0 +] ++mem: storing 1 in location 1 + +:(scenario shift_left_1) +recipe main [ + 1:number <- shift-left 1, 4 +] ++mem: storing 16 in location 1 + +:(scenario shift_left_2) +recipe main [ + 1:number <- shift-left 3, 2 +] ++mem: storing 12 in location 1 + +:(scenario shift_left_by_negative) +% Hide_errors = true; +recipe main [ + 1:number <- shift-left 3, -1 +] ++error: main: second ingredient can't be negative in '1:number <- shift-left 3, -1' + +:(scenario shift_left_ignores_fractional_part) +recipe main [ + 1:number <- divide 3, 2 + 2:number <- shift-left 1:number, 1 +] ++mem: storing 2 in location 2 + :(before "End Primitive Recipe Declarations") SHIFT_RIGHT, :(before "End Primitive Recipe Numbers") @@ -401,3 +433,254 @@ case SHIFT_RIGHT: { products.at(0).push_back(a>>b); break; } + +:(scenario shift_right_by_zero) +recipe main [ + 1:number <- shift-right 1, 0 +] ++mem: storing 1 in location 1 + +:(scenario shift_right_1) +recipe main [ + 1:number <- shift-right 1024, 1 +] ++mem: storing 512 in location 1 + +:(scenario shift_right_2) +recipe main [ + 1:number <- shift-right 3, 1 +] ++mem: storing 1 in location 1 + +:(scenario shift_right_by_negative) +% Hide_errors = true; +recipe main [ + 1:number <- shift-right 4, -1 +] ++error: main: second ingredient can't be negative in '1:number <- shift-right 4, -1' + +:(scenario shift_right_ignores_fractional_part) +recipe main [ + 1:number <- divide 3, 2 + 2:number <- shift-right 1:number, 1 +] ++mem: storing 0 in location 2 + +:(before "End Primitive Recipe Declarations") +AND_BITS, +:(before "End Primitive Recipe Numbers") +put(Recipe_ordinal, "and-bits", AND_BITS); +:(before "End Primitive Recipe Checks") +case AND_BITS: { + if (SIZE(inst.ingredients) != 2) { + raise_error << maybe(get(Recipe, r).name) << "'and-bits' requires exactly two ingredients, but got '" << inst.to_string() << "'\n" << end(); + break; + } + if (!is_mu_number(inst.ingredients.at(0)) || !is_mu_number(inst.ingredients.at(1))) { + raise_error << maybe(get(Recipe, r).name) << "'and-bits' requires number ingredients, but got '" << inst.to_string() << "'\n" << end(); + break; + } + if (SIZE(inst.products) > 1) { + raise_error << maybe(get(Recipe, r).name) << "'and-bits' yields one product in '" << inst.to_string() << "'\n" << end(); + break; + } + if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) { + raise_error << maybe(get(Recipe, r).name) << "'and-bits' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end(); + goto finish_checking_instruction; + } + break; +} +:(before "End Primitive Recipe Implementations") +case AND_BITS: { + // ingredients must be integers + long long int a = static_cast<long long int>(ingredients.at(0).at(0)); + long long int b = static_cast<long long int>(ingredients.at(1).at(0)); + products.resize(1); + products.at(0).push_back(a&b); + break; +} + +:(scenario and_bits_1) +recipe main [ + 1:number <- and-bits 8, 3 +] ++mem: storing 0 in location 1 + +:(scenario and_bits_2) +recipe main [ + 1:number <- and-bits 3, 2 +] ++mem: storing 2 in location 1 + +:(scenario and_bits_3) +recipe main [ + 1:number <- and-bits 14, 3 +] ++mem: storing 2 in location 1 + +:(scenario and_bits_negative) +recipe main [ + 1:number <- and-bits -3, 4 +] ++mem: storing 4 in location 1 + +:(before "End Primitive Recipe Declarations") +OR_BITS, +:(before "End Primitive Recipe Numbers") +put(Recipe_ordinal, "or-bits", OR_BITS); +:(before "End Primitive Recipe Checks") +case OR_BITS: { + if (SIZE(inst.ingredients) != 2) { + raise_error << maybe(get(Recipe, r).name) << "'or-bits' requires exactly two ingredients, but got '" << inst.to_string() << "'\n" << end(); + break; + } + if (!is_mu_number(inst.ingredients.at(0)) || !is_mu_number(inst.ingredients.at(1))) { + raise_error << maybe(get(Recipe, r).name) << "'or-bits' requires number ingredients, but got '" << inst.to_string() << "'\n" << end(); + break; + } + if (SIZE(inst.products) > 1) { + raise_error << maybe(get(Recipe, r).name) << "'or-bits' yields one product in '" << inst.to_string() << "'\n" << end(); + break; + } + if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) { + raise_error << maybe(get(Recipe, r).name) << "'or-bits' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end(); + goto finish_checking_instruction; + } + break; +} +:(before "End Primitive Recipe Implementations") +case OR_BITS: { + // ingredients must be integers + long long int a = static_cast<long long int>(ingredients.at(0).at(0)); + long long int b = static_cast<long long int>(ingredients.at(1).at(0)); + products.resize(1); + products.at(0).push_back(a|b); + break; +} + +:(scenario or_bits_1) +recipe main [ + 1:number <- or-bits 3, 8 +] ++mem: storing 11 in location 1 + +:(scenario or_bits_2) +recipe main [ + 1:number <- or-bits 3, 10 +] ++mem: storing 11 in location 1 + +:(scenario or_bits_3) +recipe main [ + 1:number <- or-bits 4, 6 +] ++mem: storing 6 in location 1 + +:(before "End Primitive Recipe Declarations") +XOR_BITS, +:(before "End Primitive Recipe Numbers") +put(Recipe_ordinal, "xor-bits", XOR_BITS); +:(before "End Primitive Recipe Checks") +case XOR_BITS: { + if (SIZE(inst.ingredients) != 2) { + raise_error << maybe(get(Recipe, r).name) << "'xor-bits' requires exactly two ingredients, but got '" << inst.to_string() << "'\n" << end(); + break; + } + if (!is_mu_number(inst.ingredients.at(0)) || !is_mu_number(inst.ingredients.at(1))) { + raise_error << maybe(get(Recipe, r).name) << "'xor-bits' requires number ingredients, but got '" << inst.to_string() << "'\n" << end(); + break; + } + if (SIZE(inst.products) > 1) { + raise_error << maybe(get(Recipe, r).name) << "'xor-bits' yields one product in '" << inst.to_string() << "'\n" << end(); + break; + } + if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) { + raise_error << maybe(get(Recipe, r).name) << "'xor-bits' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end(); + goto finish_checking_instruction; + } + break; +} +:(before "End Primitive Recipe Implementations") +case XOR_BITS: { + // ingredients must be integers + long long int a = static_cast<long long int>(ingredients.at(0).at(0)); + long long int b = static_cast<long long int>(ingredients.at(1).at(0)); + products.resize(1); + products.at(0).push_back(a^b); + break; +} + +:(scenario xor_bits_1) +recipe main [ + 1:number <- xor-bits 3, 8 +] ++mem: storing 11 in location 1 + +:(scenario xor_bits_2) +recipe main [ + 1:number <- xor-bits 3, 10 +] ++mem: storing 9 in location 1 + +:(scenario xor_bits_3) +recipe main [ + 1:number <- xor-bits 4, 6 +] ++mem: storing 2 in location 1 + +:(before "End Primitive Recipe Declarations") +FLIP_BITS, +:(before "End Primitive Recipe Numbers") +put(Recipe_ordinal, "flip-bits", FLIP_BITS); +:(before "End Primitive Recipe Checks") +case FLIP_BITS: { + if (SIZE(inst.ingredients) != 1) { + raise_error << maybe(get(Recipe, r).name) << "'flip-bits' requires exactly one ingredient, but got '" << inst.to_string() << "'\n" << end(); + break; + } + if (!is_mu_number(inst.ingredients.at(0))) { + raise_error << maybe(get(Recipe, r).name) << "'flip-bits' requires a number ingredient, but got '" << inst.to_string() << "'\n" << end(); + break; + } + if (SIZE(inst.products) > 1) { + raise_error << maybe(get(Recipe, r).name) << "'flip-bits' yields one product in '" << inst.to_string() << "'\n" << end(); + break; + } + if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) { + raise_error << maybe(get(Recipe, r).name) << "'flip-bits' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end(); + goto finish_checking_instruction; + } + break; +} +:(before "End Primitive Recipe Implementations") +case FLIP_BITS: { + // ingredient must be integer + long long int a = static_cast<long long int>(ingredients.at(0).at(0)); + products.resize(1); + products.at(0).push_back(~a); + break; +} + +:(scenario flip_bits_zero) +recipe main [ + 1:number <- flip-bits 0 +] ++mem: storing -1 in location 1 + +:(scenario flip_bits_negative) +recipe main [ + 1:number <- flip-bits -1 +] ++mem: storing 0 in location 1 + +:(scenario flip_bits_1) +recipe main [ + 1:number <- flip-bits 3 +] ++mem: storing -4 in location 1 + +:(scenario flip_bits_2) +recipe main [ + 1:number <- flip-bits 12 +] ++mem: storing -13 in location 1 |