diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-08-05 15:57:56 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-08-05 15:57:56 -0700 |
commit | ef49f4c6995281d0fc9caafa30defdd1120e54b3 (patch) | |
tree | e13a84947aefe38f90fbfd1c19126dbe83cf2594 | |
parent | 310308ce45ec458c1038cfcf1c7d037160e7bddb (diff) | |
download | mu-ef49f4c6995281d0fc9caafa30defdd1120e54b3.tar.gz |
1939 - allow nested tangling
However, you can't have duplicate labels within a single recipe.
-rw-r--r-- | 052tangle.cc | 79 |
1 files changed, 49 insertions, 30 deletions
diff --git a/052tangle.cc b/052tangle.cc index dd317b42..3b0f75df 100644 --- a/052tangle.cc +++ b/052tangle.cc @@ -50,30 +50,41 @@ else if (command == "after") { :(code) void insert_fragments(const recipe_ordinal r) { // Copy into a new vector because insertions invalidate iterators. - // But this way we can't insert into labels created inside before/after. vector<instruction> result; - for (long long int i = 0; i < SIZE(Recipe[r].steps); ++i) { - const instruction inst = Recipe[r].steps.at(i); - if (!inst.is_label) { - result.push_back(inst); - continue; - } - if (Before_fragments.find(inst.label) != Before_fragments.end()) { -//? cerr << "loading code before " << inst.label << '\n'; //? 1 + set<string /*label*/> fragments_inserted_this_recipe; + long long int fragments_originally_inserted = 0; + while (true) { // repeat passes until convergence (inserted fragments might include more labels) + for (long long int i = 0; i < SIZE(Recipe[r].steps); ++i) { + const instruction inst = Recipe[r].steps.at(i); + if (!inst.is_label) { + result.push_back(inst); + continue; + } + if (fragments_inserted_this_recipe.find(inst.label) != fragments_inserted_this_recipe.end()) { + // already processed in a previous pass; ignore + result.push_back(inst); + continue; + } Fragments_used.insert(inst.label); - result.insert(result.end(), Before_fragments[inst.label].steps.begin(), Before_fragments[inst.label].steps.end()); + fragments_inserted_this_recipe.insert(inst.label); + if (Before_fragments.find(inst.label) != Before_fragments.end()) { +//? cerr << "loading code before " << inst.label << '\n'; //? 1 + result.insert(result.end(), Before_fragments[inst.label].steps.begin(), Before_fragments[inst.label].steps.end()); + } + result.push_back(inst); + if (After_fragments.find(inst.label) != After_fragments.end()) { +//? cerr << "loading code after " << inst.label << '\n'; //? 1 + result.insert(result.end(), After_fragments[inst.label].steps.begin(), After_fragments[inst.label].steps.end()); + } } - result.push_back(inst); - if (After_fragments.find(inst.label) != After_fragments.end()) { -//? cerr << "loading code after " << inst.label << '\n'; //? 1 - Fragments_used.insert(inst.label); - result.insert(result.end(), After_fragments[inst.label].steps.begin(), After_fragments[inst.label].steps.end()); + Recipe[r].steps.swap(result); + if (fragments_originally_inserted == SIZE(fragments_inserted_this_recipe)) { + break; // converged } + // not yet converged; prepare next pass + result.clear(); + fragments_originally_inserted = SIZE(fragments_inserted_this_recipe); } -//? for (long long int i = 0; i < SIZE(result); ++i) { //? 1 -//? cout << result.at(i).to_string() << '\n'; //? 1 -//? } //? 1 - Recipe[r].steps.swap(result); } //: warn about unapplied fragments @@ -202,24 +213,32 @@ $mem: 6 :(scenario tangle_tangles_into_all_labels_with_same_name) recipe main [ - 1:number <- copy 0 + 1:number <- copy 10 +label1 + 4:number <- copy 10 + recipe2 +] +recipe recipe2 [ + 1:number <- copy 11 +label1 - 4:number <- copy 0 + 4:number <- copy 11 ] before +label1 [ - 2:number <- copy 0 + 2:number <- copy 12 ] after +label1 [ - 3:number <- copy 0 + 3:number <- copy 12 ] -+mem: storing 0 in location 1 -+mem: storing 0 in location 2 ++mem: storing 10 in location 1 ++mem: storing 12 in location 2 # label1 -+mem: storing 0 in location 3 -+mem: storing 0 in location 2 ++mem: storing 12 in location 3 ++mem: storing 10 in location 4 +# recipe2 ++mem: storing 11 in location 1 ++mem: storing 12 in location 2 # label1 -+mem: storing 0 in location 3 -+mem: storing 0 in location 4 ++mem: storing 12 in location 3 ++mem: storing 11 in location 4 # nothing else -$mem: 6 +$mem: 8 |