about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2017-12-07 02:01:39 -0800
committerKartik K. Agaram <vc@akkartik.com>2017-12-07 02:01:39 -0800
commitb90121dae804b2b145779cf1ca6e32cd8c7ce77d (patch)
tree09ff248c891345a5c11ac6f9df5fbae52bb800be
parent3cdbcd460d70a69ece3cc49a791692681f6ff65a (diff)
downloadmu-b90121dae804b2b145779cf1ca6e32cd8c7ce77d.tar.gz
4143
-rw-r--r--056shape_shifting_recipe.cc46
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) {