From fb9bcd34bfb65d69af8224cc1f75468a9f23e318 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Tue, 24 May 2016 18:58:23 -0700 Subject: 3001 --- 052tangle.cc | 12 ++++++++---- 054static_dispatch.cc | 4 +++- 056shape_shifting_recipe.cc | 13 +++++++------ 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 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(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::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; } -- cgit 1.4.1-2-gfad0