2619 - actually allow coercing booleans to numbers

This uncovered a bug where I've been forgetting the directionality of
arguments to types_coercible().
This commit is contained in:
Kartik K. Agaram 2016-01-30 22:17:36 -08:00
parent 007382e2a9
commit 3bfd75fcf0
2 changed files with 22 additions and 4 deletions

View File

@ -81,11 +81,21 @@ recipe main [
+mem: storing 12 in location 2
$error: 0
:(scenario write_boolean_to_number_allowed)
% Hide_errors = true;
recipe main [
1:boolean <- copy 1/true
2:number <- copy 1:boolean
]
+mem: storing 1 in location 2
$error: 0
:(code)
// types_match with some leniency
bool types_coercible(const reagent& lhs, const reagent& rhs) {
if (types_match(lhs, rhs)) return true;
if (is_mu_address(rhs) && is_mu_number(lhs)) return true;
bool types_coercible(const reagent& to, const reagent& from) {
if (types_match(to, from)) return true;
if (is_mu_address(from) && is_mu_number(to)) return true;
if (is_mu_boolean(from) && is_mu_number(to)) return true;
// End types_coercible Special-cases
return false;
}
@ -152,6 +162,12 @@ bool is_mu_address(reagent r) {
return r.type->value == get(Type_ordinal, "address");
}
bool is_mu_boolean(reagent r) {
if (!r.type) return false;
if (is_literal(r)) return false;
return r.type->value == get(Type_ordinal, "boolean");
}
bool is_mu_number(reagent r) {
if (!r.type) return false;
if (is_literal(r)) {

View File

@ -216,6 +216,7 @@ void check_calls_against_header(const recipe_ordinal r) {
const recipe& callee = get(Recipe, inst.operation);
if (!callee.has_header) continue;
for (long int i = 0; i < min(SIZE(inst.ingredients), SIZE(callee.ingredients)); ++i) {
// ingredients coerced from call to callee
if (!types_coercible(callee.ingredients.at(i), inst.ingredients.at(i)))
raise_error << maybe(caller.name) << "ingredient " << i << " has the wrong type at '" << inst.to_string() << "'\n" << end();
if (is_unique_address(inst.ingredients.at(i)))
@ -223,7 +224,8 @@ void check_calls_against_header(const recipe_ordinal r) {
}
for (long int i = 0; i < min(SIZE(inst.products), SIZE(callee.products)); ++i) {
if (is_dummy(inst.products.at(i))) continue;
if (!types_coercible(callee.products.at(i), inst.products.at(i)))
// products coerced from callee to call
if (!types_coercible(inst.products.at(i), callee.products.at(i)))
raise_error << maybe(caller.name) << "product " << i << " has the wrong type at '" << inst.to_string() << "'\n" << end();
if (is_unique_address(inst.products.at(i)))
raise << maybe(caller.name) << "try to avoid getting non-shared addresses out of calls, like product " << i << " at '" << inst.to_string() << "'\n" << end();