2475 - allow addresses to be converted to numbers

It's just the other direction we want to avoid.
This commit is contained in:
Kartik K. Agaram 2015-11-27 10:32:34 -08:00
parent c193f23217
commit bb7142dbc4
5 changed files with 33 additions and 14 deletions

View File

@ -27,7 +27,7 @@ void check_instruction(const recipe_ordinal r) {
break;
}
for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
if (!types_match(inst.products.at(i), inst.ingredients.at(i))) {
if (!types_coercible(inst.products.at(i), inst.ingredients.at(i))) {
raise_error << maybe(get(Recipe, r).name) << "can't copy " << inst.ingredients.at(i).original_string << " to " << inst.products.at(i).original_string << "; types don't match\n" << end();
goto finish_checking_instruction;
}
@ -72,6 +72,15 @@ recipe main [
]
+error: main: can't copy 34 to 1:address:number; types don't match
:(scenario write_address_to_number_allowed)
% Hide_errors = true;
recipe main [
1:address:number <- copy 12/unsafe
2:number <- copy 1:address:number
]
+mem: storing 12 in location 2
$error: 0
:(code)
// copy arguments because later layers will want to make changes to them
// without perturbing the caller
@ -86,6 +95,14 @@ bool types_match(reagent lhs, reagent rhs) {
return types_match(lhs.type, rhs.type);
}
// types_match with some special-cases
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;
// End types_coercible Special-cases
return false;
}
bool valid_type_for_literal(const reagent& lhs, const reagent& literal_rhs) {
if (is_mu_array(lhs)) return false;
// End valid_type_for_literal Special-cases

View File

@ -83,9 +83,8 @@ string print_mu(const reagent& r, const vector<double>& data) {
return r.name+' ';
// End print Special-cases(reagent r, data)
ostringstream out;
for (long long i = 0; i < SIZE(data); ++i) {
for (long long i = 0; i < SIZE(data); ++i)
out << no_scientific(data.at(i)) << ' ';
}
return out.str();
}

View File

@ -160,7 +160,7 @@ case GET: {
reagent product = inst.products.at(0);
// Update GET product in Check
const reagent element = element_type(base, offset_value);
if (!types_match(product, element)) {
if (!types_coercible(product, element)) {
raise_error << maybe(get(Recipe, r).name) << "'get " << base.original_string << ", " << offset.original_string << "' should write to " << debug_string(element.type) << " but " << product.name << " has type " << debug_string(product.type) << '\n' << end();
break;
}
@ -302,7 +302,7 @@ case GET_ADDRESS: {
reagent element = element_type(base, offset_value);
// ..except for an address at the start
element.type = new type_tree(get(Type_ordinal, "address"), element.type);
if (!types_match(product, element)) {
if (!types_coercible(product, element)) {
raise_error << maybe(get(Recipe, r).name) << "'get-address " << base.original_string << ", " << offset.original_string << "' should write to " << debug_string(element.type) << " but " << product.name << " has type " << debug_string(product.type) << '\n' << end();
break;
}
@ -353,13 +353,16 @@ recipe main [
:(scenario get_address_product_type_mismatch)
% Hide_errors = true;
recipe main [
12:number <- copy 34
13:number <- copy 35
14:number <- copy 36
15:number <- get-address 12:point-number/raw, 1:offset
container boolbool [
x:boolean
y:boolean
]
+error: main: 'get-address 12:point-number/raw, 1:offset' should write to <address : <number : <>>> but 15 has type number
recipe main [
12:boolean <- copy 1
13:boolean <- copy 0
15:boolean <- get-address 12:boolbool, 1:offset
]
+error: main: 'get-address 12:boolbool, 1:offset' should write to <address : <boolean : <>>> but 15 has type boolean
//:: Allow containers to be defined in mu code.

View File

@ -160,7 +160,7 @@ case INDEX: {
canonize_type(product);
reagent element;
element.type = new type_tree(*array_element(base.type));
if (!types_match(product, element)) {
if (!types_coercible(product, element)) {
raise_error << maybe(get(Recipe, r).name) << "'index' on " << base.original_string << " can't be saved in " << product.original_string << "; type should be " << debug_string(element.type) << '\n' << end();
break;
}
@ -300,7 +300,7 @@ case INDEX_ADDRESS: {
reagent element;
element.type = new type_tree(*array_element(base.type));
element.type = new type_tree(get(Type_ordinal, "address"), element.type);
if (!types_match(product, element)) {
if (!types_coercible(product, element)) {
raise_error << maybe(get(Recipe, r).name) << "'index' on " << base.original_string << " can't be saved in " << product.original_string << "; type should be " << debug_string(element.type) << '\n' << end();
break;
}

View File

@ -40,7 +40,7 @@ case REPLY: {
break;
}
for (long long int i = 0; i < SIZE(caller_instruction.products); ++i) {
if (!types_match(caller_instruction.products.at(i), reply_inst.ingredients.at(i))) {
if (!types_coercible(caller_instruction.products.at(i), reply_inst.ingredients.at(i))) {
raise_error << maybe(callee) << "reply ingredient " << reply_inst.ingredients.at(i).original_string << " can't be saved in " << caller_instruction.products.at(i).original_string << '\n' << end();
reagent lhs = reply_inst.ingredients.at(i);
canonize_type(lhs);