about summary refs log tree commit diff stats
path: root/059generic_recipe.cc
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-11-08 00:10:56 -0800
committerKartik K. Agaram <vc@akkartik.com>2015-11-08 00:10:56 -0800
commitfa8eda45947ca4d4e394441203c0e871251ec121 (patch)
tree162a570658911c5657fa8a2d2636ba7ee79c4da0 /059generic_recipe.cc
parent45f75796d6fa56afe269748bac12519508886376 (diff)
downloadmu-fa8eda45947ca4d4e394441203c0e871251ec121.tar.gz
2396 - edit working again!!
Still some spurious warnings.

This was an insane experience building out generics. Time to reflect.
Where did I go wrong? How did I end up writing no tests? Let's take some
time and go over the last 50 commits with a fine-tooth comb.

Generics seems to be the feature that has moved mu from a VM project to
a compiler project.
Diffstat (limited to '059generic_recipe.cc')
-rw-r--r--059generic_recipe.cc38
1 files changed, 26 insertions, 12 deletions
diff --git a/059generic_recipe.cc b/059generic_recipe.cc
index 5ca134a2..dd6eb94a 100644
--- a/059generic_recipe.cc
+++ b/059generic_recipe.cc
@@ -136,7 +136,7 @@ recipe_ordinal new_variant(recipe_ordinal exemplar, const instruction& inst) {
   compute_type_names(new_recipe);
   // that gives enough information to replace type-ingredients with concrete types
   new_recipe.name = new_name;
-  map<string, string> mappings;
+  map<string, const string_tree*> mappings;
   compute_type_ingredient_mappings(get(Recipe, exemplar), inst, mappings);
   replace_type_ingredients(new_recipe, mappings);
   ensure_all_concrete_types(new_recipe);
@@ -184,7 +184,7 @@ void save_or_deduce_type_name(reagent& x, map<string, string_tree*>& type_name)
   trace(9993, "transform") << "type of " << x.name << " is " << type_name_buf.str() << end();
 }
 
-void compute_type_ingredient_mappings(const recipe& exemplar, const instruction& inst, map<string, string>& mappings) {
+void compute_type_ingredient_mappings(const recipe& exemplar, const instruction& inst, map<string, const string_tree*>& mappings) {
   for (long long int i = 0; i < SIZE(exemplar.ingredients); ++i) {
     const reagent& base = exemplar.ingredients.at(i);
     reagent ingredient = inst.ingredients.at(i);
@@ -201,12 +201,12 @@ void compute_type_ingredient_mappings(const recipe& exemplar, const instruction&
   }
 }
 
-void accumulate_type_ingredients(const reagent& base, reagent& refinement, map<string, string>& mappings, const recipe& exemplar) {
+void accumulate_type_ingredients(const reagent& base, reagent& refinement, map<string, const string_tree*>& mappings, const recipe& exemplar) {
   assert(refinement.properties.at(0).second);
   accumulate_type_ingredients(base.properties.at(0).second, refinement.properties.at(0).second, mappings, exemplar, base);
 }
 
-void accumulate_type_ingredients(const string_tree* base, const string_tree* refinement, map<string, string>& mappings, const recipe& exemplar, const reagent& r) {
+void accumulate_type_ingredients(const string_tree* base, const string_tree* refinement, map<string, const string_tree*>& mappings, const recipe& exemplar, const reagent& r) {
   if (!base) return;
   if (!refinement) {
     raise_error << maybe(exemplar.name) << "missing type ingredient in " << r.original_string << '\n' << end();
@@ -214,12 +214,18 @@ void accumulate_type_ingredients(const string_tree* base, const string_tree* ref
   }
   if (!base->value.empty() && base->value.at(0) == '_') {
     assert(!refinement->value.empty());
+    if (base->right) {
+      raise_error << "type_ingredients in non-last position not currently supported\n" << end();
+      return;
+    }
     if (!contains_key(mappings, base->value)) {
-      trace(9993, "transform") << "adding mapping from " << base->value << " to " << refinement->value << end();
-      put(mappings, base->value, refinement->value);
+      ostringstream tmp;
+      dump_property(refinement, tmp);
+      trace(9993, "transform") << "adding mapping from " << base->value << " to " << tmp.str() << end();
+      put(mappings, base->value, new string_tree(*refinement));
     }
     else {
-      assert(get(mappings, base->value) == refinement->value);
+      assert(deeply_equal(get(mappings, base->value), refinement));
     }
   }
   else {
@@ -228,7 +234,7 @@ void accumulate_type_ingredients(const string_tree* base, const string_tree* ref
   accumulate_type_ingredients(base->right, refinement->right, mappings, exemplar, r);
 }
 
-void replace_type_ingredients(recipe& new_recipe, const map<string, string>& mappings) {
+void replace_type_ingredients(recipe& new_recipe, const map<string, const string_tree*>& mappings) {
   // update its header
   if (mappings.empty()) return;
   trace(9993, "transform") << "replacing in recipe header ingredients" << end();
@@ -281,7 +287,7 @@ void simple_string(string_tree* x, ostream& out) {
   out << ')';
 }
 
-void replace_type_ingredients(reagent& x, const map<string, string>& mappings) {
+void replace_type_ingredients(reagent& x, const map<string, const string_tree*>& mappings) {
   trace(9993, "transform") << "replacing in ingredient " << x.original_string << end();
   // replace properties
   assert(x.properties.at(0).second);
@@ -293,11 +299,19 @@ void replace_type_ingredients(reagent& x, const map<string, string>& mappings) {
     trace(9993, "transform") << "  after: " << dump_types(x) << end();
 }
 
-void replace_type_ingredients(string_tree* type, const map<string, string>& mappings) {
+void replace_type_ingredients(string_tree* type, const map<string, const string_tree*>& mappings) {
   if (!type) return;
   if (is_type_ingredient_name(type->value) && contains_key(mappings, type->value)) {
-    trace(9993, "transform") << type->value << " => " << mappings.find(type->value)->second << end();
-    type->value = mappings.find(type->value)->second;
+    const string_tree* replacement = get(mappings, type->value);
+    ostringstream tmp;
+    dump_property(replacement, tmp);
+    trace(9993, "transform") << type->value << " => " << tmp.str() << end();
+    type->value = replacement->value;
+    if (replacement->left) type->left = new string_tree(*replacement->left);
+    if (replacement->right) type->right = new string_tree(*replacement->right);
+    ostringstream tmp2;
+    dump_property(type, tmp2);
+    trace(9993, "transform") << " ===> " << tmp2.str() << end();
   }
   replace_type_ingredients(type->left, mappings);
   replace_type_ingredients(type->right, mappings);