diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-11-15 12:35:59 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-11-15 12:35:59 -0800 |
commit | c55e49b6374656099566fd22f39328c2da75b044 (patch) | |
tree | c5c248b9baff05b5910824884576cccbabf63e98 | |
parent | 360d45e68edf92e85e3ae7cb198be88182374331 (diff) | |
download | mu-c55e49b6374656099566fd22f39328c2da75b044.tar.gz |
2445 - dispatch between shape-shifting variants
Starting to leave debug prints around once again, just in case one of them is worth promoting to the trace..
-rw-r--r-- | 010vm.cc | 4 | ||||
-rw-r--r-- | 029tools.cc | 1 | ||||
-rw-r--r-- | 057static_dispatch.cc | 10 | ||||
-rw-r--r-- | 058shape_shifting_container.cc | 2 | ||||
-rw-r--r-- | 059shape_shifting_recipe.cc | 108 |
5 files changed, 115 insertions, 10 deletions
diff --git a/010vm.cc b/010vm.cc index 312aa3fc..016d3ad6 100644 --- a/010vm.cc +++ b/010vm.cc @@ -433,11 +433,11 @@ string instruction::to_string() const { string debug_string(const recipe& x) { ostringstream out; - out << "recipe " << x.name << '\n'; + out << "- recipe " << x.name << '\n'; // Begin debug_string(recipe x) for (long long int index = 0; index < SIZE(x.steps); ++index) { const instruction& inst = x.steps.at(index); - out << " inst: " << inst.to_string() << '\n'; + out << "inst: " << inst.to_string() << '\n'; out << " ingredients\n"; for (long long int i = 0; i < SIZE(inst.ingredients); ++i) out << " " << debug_string(inst.ingredients.at(i)) << '\n'; diff --git a/029tools.cc b/029tools.cc index 92f551b3..0e14b1d4 100644 --- a/029tools.cc +++ b/029tools.cc @@ -251,6 +251,7 @@ case _PRINT: { } } } + cout.flush(); break; } diff --git a/057static_dispatch.cc b/057static_dispatch.cc index 54da5354..6ca6ca7c 100644 --- a/057static_dispatch.cc +++ b/057static_dispatch.cc @@ -32,6 +32,7 @@ for (map<string, vector<recipe_ordinal> >::iterator p = Recipe_variants.begin(); :(before "End Load Recipe Header(result)") if (contains_key(Recipe_ordinal, result.name)) { const recipe_ordinal r = get(Recipe_ordinal, result.name); +//? if (variant_already_exists(result)) cerr << "AAAAAAAAAAAAAAAAAA variant already exists " << result.name << '\n'; if ((!contains_key(Recipe, r) || get(Recipe, r).has_header) && !variant_already_exists(result)) { string new_name = next_unused_recipe_name(result.name); @@ -62,12 +63,16 @@ bool all_reagents_match(const recipe& r1, const recipe& r2) { if (SIZE(r1.ingredients) != SIZE(r2.ingredients)) return false; if (SIZE(r1.products) != SIZE(r2.products)) return false; for (long long int i = 0; i < SIZE(r1.ingredients); ++i) { - if (!exact_match(r1.ingredients.at(i).type, r2.ingredients.at(i).type)) + if (!deeply_equal_types(r1.ingredients.at(i).properties.at(0).second, + r2.ingredients.at(i).properties.at(0).second)) { return false; + } } for (long long int i = 0; i < SIZE(r1.products); ++i) { - if (!exact_match(r1.products.at(i).type, r2.products.at(i).type)) + if (!deeply_equal_types(r1.products.at(i).properties.at(0).second, + r2.products.at(i).properties.at(0).second)) { return false; + } } return true; } @@ -119,6 +124,7 @@ void resolve_ambiguous_calls(recipe_ordinal r) { assert(!get(Recipe_variants, inst.name).empty()); replace_best_variant(inst, caller_recipe); } +//? if (caller_recipe.name == "main") cerr << "=============== " << debug_string(caller_recipe) << '\n'; } void replace_best_variant(instruction& inst, const recipe& caller_recipe) { diff --git a/058shape_shifting_container.cc b/058shape_shifting_container.cc index 1f0acab9..02042ac2 100644 --- a/058shape_shifting_container.cc +++ b/058shape_shifting_container.cc @@ -97,7 +97,7 @@ long long int size_of_type_ingredient(const type_tree* element_template, const t assert(!curr->left); // unimplemented if (!contains_key(Type, curr->value)) { // temporarily while we're still ironing out kinks; eventually replace with a raise_error - DUMP(""); +//? DUMP(""); cerr << "missing type " << debug_string(curr) << '\n'; exit(0); } diff --git a/059shape_shifting_recipe.cc b/059shape_shifting_recipe.cc index 4ca9779c..97914aaa 100644 --- a/059shape_shifting_recipe.cc +++ b/059shape_shifting_recipe.cc @@ -31,6 +31,7 @@ if (any_type_ingredient_in_header(/*recipe_ordinal*/p->first)) continue; :(after "Running One Instruction") if (Current_routine->calls.front().running_step_index == 0 && any_type_ingredient_in_header(Current_routine->calls.front().running_recipe)) { +//? DUMP(""); raise_error << "ran into unspecialized shape-shifting recipe " << current_recipe_name() << '\n' << end(); } @@ -48,24 +49,35 @@ recently_added_types.clear(); :(before "End Instruction Dispatch(inst, best_score)") if (best_score == -1) { +//? if (inst.name == "push-duplex") Trace_stream = new trace_stream; trace(9992, "transform") << "no variant found; searching for variant with suitable type ingredients" << end(); recipe_ordinal exemplar = pick_matching_shape_shifting_variant(variants, inst, best_score); if (exemplar) { trace(9992, "transform") << "found variant to specialize: " << exemplar << ' ' << get(Recipe, exemplar).name << end(); variants.push_back(new_variant(exemplar, inst, caller_recipe)); +//? cerr << "-- replacing " << inst.name << " with " << get(Recipe, variants.back()).name << '\n' << debug_string(get(Recipe, variants.back())); inst.name = get(Recipe, variants.back()).name; trace(9992, "transform") << "new specialization: " << inst.name << end(); } +//? if (inst.name == "push-duplex") { +//? cerr << "======== {\n"; +//? cerr << inst.to_string() << '\n'; +//? DUMP(""); +//? cerr << "======== }\n"; +//? } } :(code) recipe_ordinal pick_matching_shape_shifting_variant(vector<recipe_ordinal>& variants, const instruction& inst, long long int& best_score) { +//? cerr << "---- " << inst.name << ": " << non_ghost_size(variants) << '\n'; recipe_ordinal result = 0; for (long long int i = 0; i < SIZE(variants); ++i) { if (variants.at(i) == -1) continue; // ghost from a previous test +//? cerr << "-- variant " << i << "\n" << debug_string(get(Recipe, variants.at(i))); trace(9992, "transform") << "checking shape-shifting variant " << i << end(); long long int current_score = shape_shifting_variant_score(inst, variants.at(i)); trace(9992, "transform") << "final score: " << current_score << end(); +//? cerr << get(Recipe, variants.at(i)).name << ": " << current_score << '\n'; if (current_score > best_score) { trace(9992, "transform") << "matches" << end(); result = variants.at(i); @@ -76,6 +88,7 @@ recipe_ordinal pick_matching_shape_shifting_variant(vector<recipe_ordinal>& vari } long long int shape_shifting_variant_score(const instruction& inst, recipe_ordinal variant) { +//? cerr << "======== " << inst.to_string() << '\n'; if (!any_type_ingredient_in_header(variant)) { trace(9993, "transform") << "no type ingredients" << end(); return -1; @@ -86,7 +99,7 @@ long long int shape_shifting_variant_score(const instruction& inst, recipe_ordin return -1; } for (long long int i = 0; i < SIZE(header_ingredients); ++i) { - if (!non_type_ingredients_match(header_ingredients.at(i), inst.ingredients.at(i))) { + if (!deeply_equal_concrete_types(header_ingredients.at(i), inst.ingredients.at(i))) { trace(9993, "transform") << "mismatch: ingredient " << i << end(); return -1; } @@ -97,7 +110,7 @@ long long int shape_shifting_variant_score(const instruction& inst, recipe_ordin } const vector<reagent>& header_products = get(Recipe, variant).products; for (long long int i = 0; i < SIZE(inst.products); ++i) { - if (!non_type_ingredients_match(header_products.at(i), inst.products.at(i))) { + if (!deeply_equal_concrete_types(header_products.at(i), inst.products.at(i))) { trace(9993, "transform") << "mismatch: product " << i << end(); return -1; } @@ -119,9 +132,29 @@ bool any_type_ingredient_in_header(recipe_ordinal variant) { return false; } -bool non_type_ingredients_match(const reagent& lhs, const reagent& rhs) { - if (contains_type_ingredient_name(lhs)) return true; - return types_match(lhs, rhs); +bool deeply_equal_concrete_types(reagent lhs, reagent rhs) { +//? cerr << debug_string(lhs) << " vs " << debug_string(rhs) << '\n'; +//? bool result = deeply_equal_concrete_types(lhs.properties.at(0).second, rhs.properties.at(0).second, rhs); +//? cerr << " => " << result << '\n'; +//? return result; +//? cerr << "== " << debug_string(lhs) << " vs " << debug_string(rhs) << '\n'; + canonize_type(lhs); + canonize_type(rhs); + return deeply_equal_concrete_types(lhs.properties.at(0).second, rhs.properties.at(0).second, rhs); +} + +bool deeply_equal_concrete_types(const string_tree* lhs, const string_tree* rhs, const reagent& rhs_reagent) { + if (!lhs) return !rhs; + if (!rhs) return !lhs; + if (is_type_ingredient_name(lhs->value)) return true; // type ingredient matches anything + if (Literal_type_names.find(lhs->value) != Literal_type_names.end()) + return Literal_type_names.find(rhs->value) != Literal_type_names.end(); + if (rhs->value == "literal" && lhs->value == "address") + return rhs_reagent.name == "0"; +//? cerr << lhs->value << " vs " << rhs->value << '\n'; + return lhs->value == rhs->value + && deeply_equal_concrete_types(lhs->left, rhs->left, rhs_reagent) + && deeply_equal_concrete_types(lhs->right, rhs->right, rhs_reagent); } bool contains_type_ingredient_name(const reagent& x) { @@ -347,6 +380,13 @@ void ensure_all_concrete_types(/*const*/ reagent& x, const recipe& exemplar) { } } +long long int non_ghost_size(vector<recipe_ordinal>& variants) { + long long int result = 0; + for (long long int i = 0; i < SIZE(variants); ++i) + if (variants.at(i) != -1) ++result; + return result; +} + :(scenario shape_shifting_recipe_2) recipe main [ 10:point <- merge 14, 15 @@ -551,3 +591,61 @@ recipe foo x:_elem, y:_elem [ 1:number/raw <- add x, y ] +mem: storing 7 in location 1 + +:(scenario multiple_shape_shifting_variants) +# try to call two different shape-shifting recipes with the same name +recipe main [ + e1:d1:number <- merge 3 + e2:d2:number <- merge 4, 5 + 1:number/raw <- foo e1 + 2:number/raw <- foo e2 +] +# the two shape-shifting definitions +recipe foo a:d1:_elem -> b:number [ + local-scope + load-ingredients + reply 34 +] +recipe foo a:d2:_elem -> b:number [ + local-scope + load-ingredients + reply 35 +] +# the shape-shifting containers they use +container d1:_elem [ + x:_elem +] +container d2:_elem [ + x:number + y:_elem +] ++mem: storing 34 in location 1 ++mem: storing 35 in location 2 + +:(scenario multiple_shape_shifting_variants_2) +# static dispatch between shape-shifting variants, _including pointer lookups_ +recipe main [ + e1:d1:number <- merge 3 + e2:address:d2:number <- new {(d2 number): type} + 1:number/raw <- foo e1 + 2:number/raw <- foo *e2 # different from previous scenario +] +recipe foo a:d1:_elem -> b:number [ + local-scope + load-ingredients + reply 34 +] +recipe foo a:d2:_elem -> b:number [ + local-scope + load-ingredients + reply 35 +] +container d1:_elem [ + x:_elem +] +container d2:_elem [ + x:number + y:_elem +] ++mem: storing 34 in location 1 ++mem: storing 35 in location 2 |