diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2017-11-01 02:46:41 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2017-11-01 02:46:41 -0700 |
commit | aae198a93b03ca53a0eb2a661c0a8cc47780573f (patch) | |
tree | 77d8365b53ec06ba8b410dd0b3661c19c82eb745 /046check_type_by_name.cc | |
parent | aa68aeb34e2476af8bfea8ba11e08e3d5f1d19f1 (diff) | |
download | mu-aae198a93b03ca53a0eb2a661c0a8cc47780573f.tar.gz |
4099
Generalize commit 4089 to arbitrary closures, and not just the current 'space' or call frame. Now we should be treating spaces just like any other data structure, and reclaiming all addresses inside them when we need to. The cost: all spaces must now specify what recipe generated them (so they know how to interpret the array of locations) using the /names property. We can probably make this ergonomic with a little 'type inference'. But at least things are safe now.
Diffstat (limited to '046check_type_by_name.cc')
-rw-r--r-- | 046check_type_by_name.cc | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/046check_type_by_name.cc b/046check_type_by_name.cc index 83b80571..3fd3fdd6 100644 --- a/046check_type_by_name.cc +++ b/046check_type_by_name.cc @@ -25,25 +25,34 @@ void check_or_set_types_by_name(const recipe_ordinal r) { for (int i = 0; i < SIZE(caller.steps); ++i) { instruction& inst = caller.steps.at(i); for (int in = 0; in < SIZE(inst.ingredients); ++in) { - deduce_missing_type(known, inst.ingredients.at(in)); + deduce_missing_type(known, inst.ingredients.at(in), caller); check_type(known, inst.ingredients.at(in), caller); } for (int out = 0; out < SIZE(inst.products); ++out) { - deduce_missing_type(known, inst.products.at(out)); + deduce_missing_type(known, inst.products.at(out), caller); check_type(known, inst.products.at(out), caller); } } } -void deduce_missing_type(set<reagent>& known, reagent& x) { +void deduce_missing_type(set<reagent>& known, reagent& x, const recipe& caller) { if (x.type) return; if (is_jump_target(x.name)) { x.type = new type_tree("label"); return; } if (known.find(x) == known.end()) return; - x.type = new type_tree(*known.find(x)->type); + const reagent& exemplar = *known.find(x); + x.type = new type_tree(*exemplar.type); trace(9992, "transform") << x.name << " <= " << names_to_string(x.type) << end(); + // spaces are special; their type includes their /names property + if (is_mu_space(x) && !has_property(x, "names")) { + if (!has_property(exemplar, "names")) { + raise << maybe(caller.name) << "missing /names property for space variable '" << exemplar.name << "'\n" << end(); + return; + } + x.properties.push_back(pair<string, string_tree*>("names", new string_tree(*property(exemplar, "names")))); + } } void check_type(set<reagent>& known, const reagent& x, const recipe& caller) { |