diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-02-26 13:27:23 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-02-26 13:27:23 -0800 |
commit | bff0fa450814fcadc4b35e3e740e8d9ee6370d11 (patch) | |
tree | f996ec84ec64e4e5305bb84f8b1160620a18ccf7 | |
parent | 1b76245c6326c1d60494e102ed0141c7927a640f (diff) | |
download | mu-bff0fa450814fcadc4b35e3e740e8d9ee6370d11.tar.gz |
2713 - require booleans for boolean operations
Thanks Ella Couch for finding this bug. It's helped me find errors in mu's code itself.
-rw-r--r-- | 023boolean.cc | 23 | ||||
-rw-r--r-- | 025compare.cc | 48 | ||||
-rw-r--r-- | 031address.cc | 2 | ||||
-rw-r--r-- | 077hash.cc | 2 |
4 files changed, 70 insertions, 5 deletions
diff --git a/023boolean.cc b/023boolean.cc index 40ce068e..558421a5 100644 --- a/023boolean.cc +++ b/023boolean.cc @@ -12,6 +12,14 @@ case AND: { goto finish_checking_instruction; } } + if (SIZE(inst.products) > 1) { + raise << maybe(get(Recipe, r).name) << "'and' yields exactly one product in '" << to_string(inst) << "'\n" << end(); + break; + } + if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_boolean(inst.products.at(0))) { + raise << maybe(get(Recipe, r).name) << "'and' should yield a boolean, but got " << inst.products.at(0).original_string << '\n' << end(); + break; + } break; } :(before "End Primitive Recipe Implementations") @@ -62,6 +70,14 @@ case OR: { goto finish_checking_instruction; } } + if (SIZE(inst.products) > 1) { + raise << maybe(get(Recipe, r).name) << "'or' yields exactly one product in '" << to_string(inst) << "'\n" << end(); + break; + } + if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_boolean(inst.products.at(0))) { + raise << maybe(get(Recipe, r).name) << "'or' should yield a boolean, but got " << inst.products.at(0).original_string << '\n' << end(); + break; + } break; } :(before "End Primitive Recipe Implementations") @@ -116,6 +132,13 @@ case NOT: { goto finish_checking_instruction; } } + for (long long int i = 0; i < SIZE(inst.products); ++i) { + if (is_dummy(inst.products.at(i))) continue; + if (!is_mu_boolean(inst.products.at(i))) { + raise << maybe(get(Recipe, r).name) << "'not' should yield a boolean, but got " << inst.products.at(i).original_string << '\n' << end(); + goto finish_checking_instruction; + } + } break; } :(before "End Primitive Recipe Implementations") diff --git a/025compare.cc b/025compare.cc index 59eb55b1..509e27fe 100644 --- a/025compare.cc +++ b/025compare.cc @@ -10,6 +10,14 @@ case EQUAL: { raise << maybe(get(Recipe, r).name) << "'equal' needs at least two ingredients to compare in '" << to_string(inst) << "'\n" << end(); break; } + if (SIZE(inst.products) > 1) { + raise << maybe(get(Recipe, r).name) << "'equal' yields exactly one product in '" << to_string(inst) << "'\n" << end(); + break; + } + if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_boolean(inst.products.at(0))) { + raise << maybe(get(Recipe, r).name) << "'equal' should yield a boolean, but got " << inst.products.at(0).original_string << '\n' << end(); + break; + } break; } :(before "End Primitive Recipe Implementations") @@ -31,7 +39,7 @@ case EQUAL: { recipe main [ 1:number <- copy 34 2:number <- copy 33 - 3:number <- equal 1:number, 2:number + 3:boolean <- equal 1:number, 2:number ] +mem: location 1 is 34 +mem: location 2 is 33 @@ -41,7 +49,7 @@ recipe main [ recipe main [ 1:number <- copy 34 2:number <- copy 34 - 3:number <- equal 1:number, 2:number + 3:boolean <- equal 1:number, 2:number ] +mem: location 1 is 34 +mem: location 2 is 34 @@ -49,13 +57,13 @@ recipe main [ :(scenario equal_multiple) recipe main [ - 1:number <- equal 34, 34, 34 + 1:boolean <- equal 34, 34, 34 ] +mem: storing 1 in location 1 :(scenario equal_multiple_2) recipe main [ - 1:number <- equal 34, 34, 35 + 1:boolean <- equal 34, 34, 35 ] +mem: storing 0 in location 1 @@ -75,6 +83,14 @@ case GREATER_THAN: { goto finish_checking_instruction; } } + if (SIZE(inst.products) > 1) { + raise << maybe(get(Recipe, r).name) << "'greater-than' yields exactly one product in '" << to_string(inst) << "'\n" << end(); + break; + } + if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_boolean(inst.products.at(0))) { + raise << maybe(get(Recipe, r).name) << "'greater-than' should yield a boolean, but got " << inst.products.at(0).original_string << '\n' << end(); + break; + } break; } :(before "End Primitive Recipe Implementations") @@ -134,6 +150,14 @@ case LESSER_THAN: { goto finish_checking_instruction; } } + if (SIZE(inst.products) > 1) { + raise << maybe(get(Recipe, r).name) << "'lesser-than' yields exactly one product in '" << to_string(inst) << "'\n" << end(); + break; + } + if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_boolean(inst.products.at(0))) { + raise << maybe(get(Recipe, r).name) << "'lesser-than' should yield a boolean, but got " << inst.products.at(0).original_string << '\n' << end(); + break; + } break; } :(before "End Primitive Recipe Implementations") @@ -193,6 +217,14 @@ case GREATER_OR_EQUAL: { goto finish_checking_instruction; } } + if (SIZE(inst.products) > 1) { + raise << maybe(get(Recipe, r).name) << "'greater-or-equal' yields exactly one product in '" << to_string(inst) << "'\n" << end(); + break; + } + if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_boolean(inst.products.at(0))) { + raise << maybe(get(Recipe, r).name) << "'greater-or-equal' should yield a boolean, but got " << inst.products.at(0).original_string << '\n' << end(); + break; + } break; } :(before "End Primitive Recipe Implementations") @@ -260,6 +292,14 @@ case LESSER_OR_EQUAL: { goto finish_checking_instruction; } } + if (SIZE(inst.products) > 1) { + raise << maybe(get(Recipe, r).name) << "'greater-or-equal' yields exactly one product in '" << to_string(inst) << "'\n" << end(); + break; + } + if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_boolean(inst.products.at(0))) { + raise << maybe(get(Recipe, r).name) << "'greater-or-equal' should yield a boolean, but got " << inst.products.at(0).original_string << '\n' << end(); + break; + } break; } :(before "End Primitive Recipe Implementations") diff --git a/031address.cc b/031address.cc index 0d3f79f6..0577422d 100644 --- a/031address.cc +++ b/031address.cc @@ -83,6 +83,8 @@ recipe foo [ :(after "bool is_mu_number(reagent r)") if (!canonize_type(r)) return false; +:(after "bool is_mu_boolean(reagent r)") + if (!canonize_type(r)) return false; :(after "Update product While Type-checking Merge") if (!canonize_type(product)) continue; diff --git a/077hash.cc b/077hash.cc index 23f31ad0..682232dd 100644 --- a/077hash.cc +++ b/077hash.cc @@ -351,7 +351,7 @@ recipe main [ 1:address:shared:array:character <- new [abc] 2:number <- hash 1:address:shared:array:character 3:number <- hash_old 1:address:shared:array:character - 4:number <- equal 2:number, 3:number + 4:boolean <- equal 2:number, 3:number ] +mem: storing 1 in location 4 |