diff options
-rw-r--r-- | 056shape_shifting_recipe.cc | 46 |
1 files changed, 24 insertions, 22 deletions
diff --git a/056shape_shifting_recipe.cc b/056shape_shifting_recipe.cc index d36bb662..bae60527 100644 --- a/056shape_shifting_recipe.cc +++ b/056shape_shifting_recipe.cc @@ -249,22 +249,26 @@ string insert_new_variant(recipe_ordinal exemplar, const instruction& inst, cons // make a copy assert(contains_key(Recipe, exemplar)); assert(!contains_key(Recipe, new_recipe_ordinal)); - recipe new_recipe = get(Recipe, exemplar); + put(Recipe, new_recipe_ordinal, /*copy*/get(Recipe, exemplar)); + recipe& new_recipe = get(Recipe, new_recipe_ordinal); new_recipe.name = new_name; new_recipe.is_autogenerated = true; trace(9993, "transform") << "switching " << inst.name << " to specialized " << header_label(new_recipe) << end(); - // Replace type ingredients with concrete types in new_recipe. - // - // preprocessing: micro-manage a couple of transforms - // a) perform tangle *before* replacing type ingredients, just in case - // inserted code involves type ingredients - insert_fragments(new_recipe); - // b) do the work of check_or_set_types_by_name (and its prerequisites) - // while supporting type-ingredients - expand_type_abbreviations(new_recipe); + trace(9992, "transform") << "transforming new specialization: " << new_recipe.name << end(); + trace(9992, "transform") << new_recipe.name << ": performing transforms until check_or_set_types_by_name" << end(); + int transform_index = 0; + for (transform_index = 0; transform_index < SIZE(Transform); ++transform_index) { + if (Transform.at(transform_index) == check_or_set_types_by_name) break; + (*Transform.at(transform_index))(new_recipe_ordinal); + } + new_recipe.transformed_until = transform_index-1; + + trace(9992, "transform") << new_recipe.name << ": performing type-ingredient-aware version of transform check_or_set_types_by_name" << end(); compute_type_names(new_recipe); - // that gives enough information to replace type-ingredients with concrete types + new_recipe.transformed_until++; + + trace(9992, "transform") << new_recipe.name << ": replacing type ingredients" << end(); { map<string, const type_tree*> mappings; bool error = false; @@ -276,17 +280,12 @@ string insert_new_variant(recipe_ordinal exemplar, const instruction& inst, cons if (error) return ""; } ensure_all_concrete_types(new_recipe, get(Recipe, exemplar)); - put(Recipe, new_recipe_ordinal, new_recipe); - // record variant before performing transforms, just in case the recipe is recursive + + trace(9992, "transform") << new_recipe.name << ": recording the new variant before recursively calling resolve_ambiguous_calls" << end(); get(Recipe_variants, inst.name).push_back(new_recipe_ordinal); - // perform all transforms on the new specialization - trace(9992, "transform") << "transforming new specialization: " << new_recipe.name << end(); - for (int t = 0; t < SIZE(Transform); ++t) { - // one exception: skip tangle, which has already occurred above - if (Transform.at(t) == /*disambiguate overloading*/static_cast<transform_fn>(insert_fragments)) - continue; - (*Transform.at(t))(new_recipe_ordinal); - } + trace(9992, "transform") << new_recipe.name << ": performing remaining transforms (including resolve_ambiguous_calls)" << end(); + for (/*nada*/; transform_index < SIZE(Transform); ++transform_index) + (*Transform.at(transform_index))(new_recipe_ordinal); new_recipe.transformed_until = SIZE(Transform)-1; return new_recipe.name; } @@ -315,6 +314,9 @@ void save_or_deduce_type_name(reagent& x, map<string, type_tree*>& type, const r trace(9994, "transform") << " deducing type to " << names_to_string(x.type) << end(); return; } + // This is different from check_or_set_types_by_name. + // We've found it useful in the past for tracking down bugs in + // specialization. if (!x.type) { raise << maybe(variant.original_name) << "unknown type for '" << x.original_string << "'" << context << " (check the name for typos)\n" << end(); return; @@ -527,7 +529,7 @@ void ensure_all_concrete_types(/*const*/ recipe& new_recipe, const recipe& exemp void ensure_all_concrete_types(/*const*/ reagent& x, const recipe& exemplar) { if (!x.type || contains_type_ingredient_name(x.type)) { raise << maybe(exemplar.name) << "failed to map a type to " << x.original_string << '\n' << end(); - if (!x.type) x.type = new type_tree("", 0); // just to prevent crashes later + if (!x.type) x.type = new type_tree("added_by_ensure_all_concrete_types", 0); // just to prevent crashes later return; } if (x.type->value == -1) { |