about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--052tangle.cc12
-rw-r--r--054static_dispatch.cc4
-rw-r--r--056shape_shifting_recipe.cc13
3 files changed, 18 insertions, 11 deletions
diff --git a/052tangle.cc b/052tangle.cc
index db1416a8..c3ad4485 100644
--- a/052tangle.cc
+++ b/052tangle.cc
@@ -69,14 +69,18 @@ tangle_done = false;
 
 :(code)
 void insert_fragments(const recipe_ordinal r) {
+  insert_fragments(get(Recipe, r));
+}
+
+void insert_fragments(recipe& r) {
   bool made_progress = true;
   int pass = 0;
   while (made_progress) {
     made_progress = false;
     // create a new vector because insertions invalidate iterators
     vector<instruction> result;
-    for (int i = 0; i < SIZE(get(Recipe, r).steps); ++i) {
-      const instruction& inst = get(Recipe, r).steps.at(i);
+    for (int i = 0; i < SIZE(r.steps); ++i) {
+      const instruction& inst = r.steps.at(i);
       if (!inst.is_label || !is_waypoint(inst.label) || inst.tangle_done) {
         result.push_back(inst);
         continue;
@@ -85,7 +89,7 @@ void insert_fragments(const recipe_ordinal r) {
       made_progress = true;
       Fragments_used.insert(inst.label);
       ostringstream prefix;
-      prefix << '+' << get(Recipe, r).name << '_' << pass << '_' << i;
+      prefix << '+' << r.name << '_' << pass << '_' << i;
       // ok to use contains_key even though Before_fragments uses [],
       // because appending an empty recipe is a noop
       if (contains_key(Before_fragments, inst.label))
@@ -94,7 +98,7 @@ void insert_fragments(const recipe_ordinal r) {
       if (contains_key(After_fragments, inst.label))
         append_fragment(result, After_fragments[inst.label].steps, prefix.str());
     }
-    get(Recipe, r).steps.swap(result);
+    r.steps.swap(result);
     ++pass;
   }
 }
diff --git a/054static_dispatch.cc b/054static_dispatch.cc
index 00503c85..fa0c6c74 100644
--- a/054static_dispatch.cc
+++ b/054static_dispatch.cc
@@ -564,7 +564,9 @@ def foo x:number -> y:number [
 
 :(code)
 string header_label(recipe_ordinal r) {
-  const recipe& caller = get(Recipe, r);
+  return header_label(get(Recipe, r));
+}
+string header_label(const recipe& caller) {
   ostringstream out;
   out << "recipe " << caller.name;
   for (int i = 0; i < SIZE(caller.ingredients); ++i)
diff --git a/056shape_shifting_recipe.cc b/056shape_shifting_recipe.cc
index 3251b5cb..bd804c6f 100644
--- a/056shape_shifting_recipe.cc
+++ b/056shape_shifting_recipe.cc
@@ -62,7 +62,8 @@ if (!candidates.empty()) {
     trace(9992, "transform") << "transforming new specialization: " << variant.name << end();
     for (int t = 0; t < SIZE(Transform); ++t) {
       // one exception: skip tangle, which would have already occurred inside new_variant above
-      if (Transform.at(t) == insert_fragments) continue;
+      if (Transform.at(t) == /*disambiguate overloading*/static_cast<transform_fn>(insert_fragments))
+        continue;
       (*Transform.at(t))(new_recipe_ordinal);
     }
   }
@@ -228,17 +229,16 @@ recipe_ordinal new_variant(recipe_ordinal exemplar, const instruction& inst, con
   // make a copy
   assert(contains_key(Recipe, exemplar));
   assert(!contains_key(Recipe, new_recipe_ordinal));
-  put(Recipe, new_recipe_ordinal, get(Recipe, exemplar));
-  recipe& new_recipe = get(Recipe, new_recipe_ordinal);
+  recipe new_recipe = get(Recipe, exemplar);
   new_recipe.name = new_name;
-  trace(9993, "transform") << "switching " << inst.name << " to specialized " << header_label(new_recipe_ordinal) << end();
+  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_ordinal);
+  insert_fragments(new_recipe);
   // b) do the work of check_types_by_name while supporting type-ingredients
   compute_type_names(new_recipe);
   // that gives enough information to replace type-ingredients with concrete types
@@ -249,9 +249,10 @@ recipe_ordinal new_variant(recipe_ordinal exemplar, const instruction& inst, con
     if (!error) replace_type_ingredients(new_recipe, mappings);
     for (map<string, const type_tree*>::iterator p = mappings.begin(); p != mappings.end(); ++p)
       delete p->second;
-    if (error) return 0;  // todo: delete new_recipe_ordinal from Recipes and other global state
+    if (error) return 0;
   }
   ensure_all_concrete_types(new_recipe, get(Recipe, exemplar));
+  put(Recipe, new_recipe_ordinal, new_recipe);
   return new_recipe_ordinal;
 }