diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-11-15 00:37:29 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-11-15 00:37:29 -0800 |
commit | ef96f57ce264c8e0bd98f6e8622d1c1e2eceafb2 (patch) | |
tree | f2113d385fde9c4b9579521402eab5ec9c1f208d /059shape_shifting_recipe.cc | |
parent | 7ecb3374340c02cc2c54abf4a5d4a617f362b4c4 (diff) | |
download | mu-ef96f57ce264c8e0bd98f6e8622d1c1e2eceafb2.tar.gz |
2441 - never miss any specializations
I was failing to specialize calls containing literals. And then I had to deal with whether literals should map to numbers or characters. (Answer: both.) One of the issues that still remains: shape-shifting recipes can't be called with literals for addresses, even if it's 0.
Diffstat (limited to '059shape_shifting_recipe.cc')
-rw-r--r-- | 059shape_shifting_recipe.cc | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/059shape_shifting_recipe.cc b/059shape_shifting_recipe.cc index bc63d616..feffd410 100644 --- a/059shape_shifting_recipe.cc +++ b/059shape_shifting_recipe.cc @@ -34,6 +34,11 @@ if (Current_routine->calls.front().running_step_index == 0 raise_error << "ran into unspecialized shape-shifting recipe " << current_recipe_name() << '\n' << end(); } +//: Make sure we don't match up literals with type ingredients without +//: specialization. +:(before "End valid_type_for_literal Special-cases") +if (contains_type_ingredient_name(r)) return false; + //: We'll be creating recipes without loading them from anywhere by //: *specializing* existing recipes, so make sure we don't clear any of those //: when we start running tests. @@ -202,14 +207,16 @@ void save_or_deduce_type_name(reagent& x, map<string, string_tree*>& type_name) } void compute_type_ingredient_mappings(const recipe& exemplar, const instruction& inst, map<string, const string_tree*>& mappings, const recipe& caller_recipe, bool* error) { - for (long long int i = 0; i < SIZE(exemplar.ingredients); ++i) { + long long int limit = min(SIZE(inst.ingredients), SIZE(exemplar.ingredients)); + for (long long int i = 0; i < limit; ++i) { const reagent& exemplar_reagent = exemplar.ingredients.at(i); reagent ingredient = inst.ingredients.at(i); assert(ingredient.properties.at(0).second); canonize_type(ingredient); accumulate_type_ingredients(exemplar_reagent, ingredient, mappings, exemplar, inst, caller_recipe, error); } - for (long long int i = 0; i < SIZE(exemplar.products); ++i) { + limit = min(SIZE(inst.products), SIZE(exemplar.products)); + for (long long int i = 0; i < limit; ++i) { const reagent& exemplar_reagent = exemplar.products.at(i); reagent product = inst.products.at(i); assert(product.properties.at(0).second); @@ -218,6 +225,10 @@ void compute_type_ingredient_mappings(const recipe& exemplar, const instruction& } } +inline long long int min(long long int a, long long int b) { + return (a < b) ? a : b; +} + void accumulate_type_ingredients(const reagent& exemplar_reagent, reagent& refinement, map<string, const string_tree*>& mappings, const recipe& exemplar, const instruction& call_instruction, const recipe& caller_recipe, bool* error) { assert(refinement.properties.at(0).second); accumulate_type_ingredients(exemplar_reagent.properties.at(0).second, refinement.properties.at(0).second, mappings, exemplar, exemplar_reagent, call_instruction, caller_recipe, error); @@ -237,10 +248,13 @@ void accumulate_type_ingredients(const string_tree* exemplar_type, const string_ } if (!contains_key(mappings, exemplar_type->value)) { trace(9993, "transform") << "adding mapping from " << exemplar_type->value << " to " << debug_string(refinement_type) << end(); - put(mappings, exemplar_type->value, new string_tree(*refinement_type)); + if (refinement_type->value == "literal") + put(mappings, exemplar_type->value, new string_tree("number")); + else + put(mappings, exemplar_type->value, new string_tree(*refinement_type)); } else { - if (!deeply_equal(get(mappings, exemplar_type->value), refinement_type)) { + if (!deeply_equal_types(get(mappings, exemplar_type->value), refinement_type)) { raise_error << maybe(caller_recipe.name) << "no call found for '" << call_instruction.to_string() << "'\n" << end(); *error = true; return; @@ -467,3 +481,29 @@ recipe bar x:_elem -> y:_elem [ y <- add x, 1 ] +mem: storing 4 in location 1 + +:(scenario specialize_with_literal) +recipe main [ + local-scope + # permit literal to map to number + 1:number/raw <- foo 3 +] +recipe foo x:_elem -> y:_elem [ + local-scope + load-ingredients + y <- add x, 1 +] ++mem: storing 4 in location 1 + +:(scenario specialize_with_literal_2) +recipe main [ + local-scope + # permit literal to map to character + 1:character/raw <- foo 3 +] +recipe foo x:_elem -> y:_elem [ + local-scope + load-ingredients + y <- add x, 1 +] ++mem: storing 4 in location 1 |