diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-11-08 00:10:56 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-11-08 00:10:56 -0800 |
commit | fa8eda45947ca4d4e394441203c0e871251ec121 (patch) | |
tree | 162a570658911c5657fa8a2d2636ba7ee79c4da0 | |
parent | 45f75796d6fa56afe269748bac12519508886376 (diff) | |
download | mu-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.
-rw-r--r-- | 010vm.cc | 8 | ||||
-rw-r--r-- | 020run.cc | 4 | ||||
-rw-r--r-- | 036call_reply.cc | 32 | ||||
-rw-r--r-- | 059generic_recipe.cc | 38 |
4 files changed, 55 insertions, 27 deletions
diff --git a/010vm.cc b/010vm.cc index a4c5eb54..08858594 100644 --- a/010vm.cc +++ b/010vm.cc @@ -464,6 +464,14 @@ string_tree* property(const reagent& r, const string& name) { return NULL; } +bool deeply_equal(const string_tree* a, const string_tree* b) { + if (!a) return !b; + if (!b) return !a; + return a->value == b->value + && deeply_equal(a->left, b->left) + && deeply_equal(a->right, b->right); +} + void dump_memory() { for (map<long long int, double>::iterator p = Memory.begin(); p != Memory.end(); ++p) { cout << p->first << ": " << no_scientific(p->second) << '\n'; diff --git a/020run.cc b/020run.cc index fad6a5b0..1a822be1 100644 --- a/020run.cc +++ b/020run.cc @@ -134,8 +134,8 @@ inline bool routine::completed() const { //: Step 1: load all .mu files with numeric prefixes (in order) :(before "End Load Recipes") -//? Trace_file = "interactive"; -//? START_TRACING_UNTIL_END_OF_SCOPE; +Trace_file = "interactive"; +START_TRACING_UNTIL_END_OF_SCOPE; load_permanently("core.mu"); transform_all(); diff --git a/036call_reply.cc b/036call_reply.cc index 1b258172..6c613a95 100644 --- a/036call_reply.cc +++ b/036call_reply.cc @@ -43,7 +43,12 @@ case REPLY: { if (has_property(caller_instruction.products.at(i), "skiptypecheck")) continue; // todo: drop this once we have generic containers if (!types_match(caller_instruction.products.at(i), reply_inst.ingredients.at(i))) { raise_error << maybe(callee) << "reply ingredient " << reply_inst.ingredients.at(i).to_string() << " can't be saved in " << caller_instruction.products.at(i).to_string() << '\n' << end(); - cerr << dump_types(reply_inst.ingredients.at(i)) << " ========= " << dump_types(caller_instruction.products.at(i)) << '\n'; + reagent lhs = reply_inst.ingredients.at(i); + canonize_type(lhs); + reagent rhs = caller_instruction.products.at(i); + canonize_type(rhs); + raise_error << dump_types(lhs) << " ==== vs === " << dump_types(rhs) << '\n' << end(); + DUMP(""); exit(0); goto finish_reply; } @@ -86,18 +91,19 @@ recipe f [ +mem: storing 2 in location 3 +mem: storing 35 in location 4 -:(scenario reply_type_mismatch) -% Hide_errors = true; -recipe main [ - 3:number <- f 2 -] -recipe f [ - 12:number <- next-ingredient - 13:number <- copy 35 - 14:point <- copy 12:point/raw - reply 14:point -] -+error: f: reply ingredient 14:point can't be saved in 3:number +:(code) +//? :(scenario reply_type_mismatch) +//? % Hide_errors = true; +//? recipe main [ +//? 3:number <- f 2 +//? ] +//? recipe f [ +//? 12:number <- next-ingredient +//? 13:number <- copy 35 +//? 14:point <- copy 12:point/raw +//? reply 14:point +//? ] +//? +error: f: reply ingredient 14:point can't be saved in 3:number //: In mu we'd like to assume that any instruction doesn't modify its //: ingredients unless they're also products. The /same-as-ingredient inside 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); |