about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-11-08 11:46:04 -0800
committerKartik K. Agaram <vc@akkartik.com>2016-11-08 11:52:37 -0800
commitb55b15a920a3f367688579d946a83deb13855df8 (patch)
tree3e449a9732d9e2fbdb4d3703398419298263c428
parent4ecab1821ed7609d35f2c9509cb045dc79606e8c (diff)
downloadmu-b55b15a920a3f367688579d946a83deb13855df8.tar.gz
3654
Follow-up to commit 3321: move get_base_type() more thoroughly to layer
55. The notion of a base_type doesn't really make sense before we
introduce type ingredients and shape-shifting containers, and it
simplifies early layers a *lot* even including the cost of that *ugly*
preamble in layer 55 to retrofit all the places.
-rw-r--r--030container.cc25
-rw-r--r--031merge.cc10
-rw-r--r--036refcount.cc20
-rw-r--r--042name.cc4
-rw-r--r--055shape_shifting_container.cc38
-rw-r--r--069hash.cc4
-rw-r--r--071recipe.cc4
-rw-r--r--073wait.cc4
8 files changed, 68 insertions, 41 deletions
diff --git a/030container.cc b/030container.cc
index 098c38c5..322364c0 100644
--- a/030container.cc
+++ b/030container.cc
@@ -148,25 +148,19 @@ void clear_container_metadata() {
 if (r.metadata.size) return r.metadata.size;
 
 :(before "End size_of(type) Special-cases")
-const type_tree* root = root_type(type);
-if (!contains_key(Type, root->value)) {
-  raise << "no such type " << root->value << '\n' << end();
+const type_tree* base_type = type;
+// Update base_type in size_of(type)
+if (!contains_key(Type, base_type->value)) {
+  raise << "no such type " << base_type->value << '\n' << end();
   return 0;
 }
-type_info t = get(Type, root->value);
+type_info t = get(Type, base_type->value);
 if (t.kind == CONTAINER) {
   // Compute size_of Container
   if (!contains_key(Container_metadata, type)) return 1;  // error raised elsewhere
   return get(Container_metadata, type).size;
 }
 
-:(code)
-const type_tree* root_type(const type_tree* t) {
-  const type_tree* result = t->atom ? t : t->left;
-  assert(result->atom);
-  return result;
-}
-
 //: precompute Container_metadata before we need size_of
 //: also store a copy in each reagent in each instruction in each recipe
 
@@ -421,10 +415,11 @@ case GET: {
 :(code)
 const reagent element_type(const type_tree* type, int offset_value) {
   assert(offset_value >= 0);
-  const type_tree* root = root_type(type);
-  assert(contains_key(Type, root->value));
-  assert(!get(Type, root->value).name.empty());
-  const type_info& info = get(Type, root->value);
+  const type_tree* base_type = type;
+  // Update base_type in element_type
+  assert(contains_key(Type, base_type->value));
+  assert(!get(Type, base_type->value).name.empty());
+  const type_info& info = get(Type, base_type->value);
   assert(info.kind == CONTAINER);
   if (offset_value >= SIZE(info.elements)) return reagent();  // error handled elsewhere
   reagent/*copy*/ element = info.elements.at(offset_value);
diff --git a/031merge.cc b/031merge.cc
index 75dc466b..14999123 100644
--- a/031merge.cc
+++ b/031merge.cc
@@ -166,7 +166,7 @@ void check_merge_call(const vector<reagent>& ingredients, const reagent& product
         if (types_coercible(expected_ingredient, ingredients.at(ingredient_index))) {
           ++ingredient_index;
           ++state.data.top().container_element_index;
-          while (state.data.top().container_element_index >= SIZE(get(Type, root_type(state.data.top().container.type)->value).elements)) {
+          while (state.data.top().container_element_index >= SIZE(get(Type, get_base_type(state.data.top().container.type)->value).elements)) {
             state.data.pop();
             if (state.data.empty()) {
               if (ingredient_index < SIZE(ingredients))
@@ -201,7 +201,7 @@ void check_merge_call(const vector<reagent>& ingredients, const reagent& product
             return;
           }
           ++state.data.top().container_element_index;
-        } while (state.data.top().container_element_index >= SIZE(get(Type, root_type(state.data.top().container.type)->value).elements));
+        } while (state.data.top().container_element_index >= SIZE(get(Type, get_base_type(state.data.top().container.type)->value).elements));
       }
     }
   }
@@ -209,6 +209,12 @@ void check_merge_call(const vector<reagent>& ingredients, const reagent& product
   assert(false);
 }
 
+// replaced in a later layer
+// todo: find some clean way to take this call completely out of this layer
+const type_tree* get_base_type(const type_tree* t) {
+  return t;
+}
+
 :(scenario merge_check_product)
 % Hide_errors = true;
 def main [
diff --git a/036refcount.cc b/036refcount.cc
index 09bb5d30..6822314b 100644
--- a/036refcount.cc
+++ b/036refcount.cc
@@ -321,8 +321,10 @@ void compute_container_address_offsets(const type_tree* type, const string& loca
       compute_container_address_offsets(array_element(type), location_for_error_messages);
     // End compute_container_address_offsets Non-atom Special-cases
   }
-  if (!contains_key(Type, root_type(type)->value)) return;  // error raised elsewhere
-  type_info& info = get(Type, root_type(type)->value);
+  const type_tree* base_type = type;
+  // Update base_type in compute_container_address_offsets
+  if (!contains_key(Type, base_type->value)) return;  // error raised elsewhere
+  type_info& info = get(Type, base_type->value);
   if (info.kind == CONTAINER) {
     compute_container_address_offsets(info, type, location_for_error_messages);
   }
@@ -353,12 +355,13 @@ void append_addresses(int base_offset, const type_tree* type, map<set<tag_condit
     get_or_insert(out, key).insert(address_element_info(base_offset, new type_tree(*type->right)));
     return;
   }
-  const type_tree* root = root_type(type);
-  const type_info& info = get(Type, root->value);
+  const type_tree* base_type = type;
+  // Update base_type in append_container_address_offsets
+  const type_info& info = get(Type, base_type->value);
   if (info.kind == CONTAINER) {
     for (int curr_index = 0, curr_offset = base_offset;  curr_index < SIZE(info.elements);  ++curr_index) {
-      trace(9993, "transform") << "checking container " << root->name << ", element " << curr_index << end();
-      reagent/*copy*/ element = element_type(type, curr_index);  // not root
+      trace(9993, "transform") << "checking container " << base_type->name << ", element " << curr_index << end();
+      reagent/*copy*/ element = element_type(type, curr_index);  // not base_type
       // Compute Container Address Offset(element)
       if (is_mu_address(element)) {
         trace(9993, "transform") << "address at offset " << curr_offset << end();
@@ -379,8 +382,9 @@ void append_addresses(int base_offset, const type_tree* type, map<set<tag_condit
         curr_offset += size_of(element);
       }
       else if (is_mu_exclusive_container(element)) {
-        const type_tree* element_root_type = root_type(element.type);
-        const type_info& element_info = get(Type, element_root_type->value);
+        const type_tree* element_base_type = element.type;
+        // Update element_base_type For Exclusive Container in append_addresses
+        const type_info& element_info = get(Type, element_base_type->value);
         for (int tag = 0;  tag < SIZE(element_info.elements);  ++tag) {
           set<tag_condition_info> new_key = key;
           new_key.insert(tag_condition_info(curr_offset, tag));
diff --git a/042name.cc b/042name.cc
index 6b6d2a74..1fc2f201 100644
--- a/042name.cc
+++ b/042name.cc
@@ -121,7 +121,9 @@ type_ordinal skip_addresses(type_tree* type) {
   while (type && is_compound_type_starting_with(type, "address"))
     type = type->right;
   if (!type) return -1;  // error handled elsewhere
-  return root_type(type)->value;
+  const type_tree* base_type = type;
+  // Update base_type in skip_addresses
+  return base_type->value;
 }
 
 int find_element_name(const type_ordinal t, const string& name, const string& recipe_name) {
diff --git a/055shape_shifting_container.cc b/055shape_shifting_container.cc
index 061cd0ef..dec225dc 100644
--- a/055shape_shifting_container.cc
+++ b/055shape_shifting_container.cc
@@ -4,21 +4,39 @@
 //: atomic types
 :(before "End is_mu_container(type) Special-cases")
 if (!type->atom)
-  return is_mu_container(root_type(type));
+  return is_mu_container(get_base_type(type));
 :(before "End is_mu_exclusive_container(type) Special-cases")
 if (!type->atom)
-  return is_mu_exclusive_container(root_type(type));
-// a few calls to root_type() without the assertion (for better error handling)
+  return is_mu_exclusive_container(get_base_type(type));
 :(after "Update GET base_type in Check")
-if (!base_type->atom) base_type = base_type->left;
+base_type = get_base_type(base_type);
 :(after "Update GET base_type in Run")
-if (!base_type->atom) base_type = base_type->left;
+base_type = get_base_type(base_type);
 :(after "Update PUT base_type in Check")
-if (!base_type->atom) base_type = base_type->left;
+base_type = get_base_type(base_type);
 :(after "Update PUT base_type in Run")
-if (!base_type->atom) base_type = base_type->left;
+base_type = get_base_type(base_type);
 :(after "Update MAYBE_CONVERT base_type in Check")
-if (!base_type->atom) base_type = base_type->left;
+base_type = get_base_type(base_type);
+:(after "Update base_type in size_of(type)")
+base_type = get_base_type(base_type);
+:(after "Update base_type in element_type")
+base_type = get_base_type(base_type);
+:(after "Update base_type in compute_container_address_offsets")
+base_type = get_base_type(base_type);
+:(after "Update base_type in append_container_address_offsets")
+base_type = get_base_type(base_type);
+:(after "Update element_base_type For Exclusive Container in append_addresses")
+element_base_type = get_base_type(element_base_type);
+:(after "Update base_type in skip_addresses")
+base_type = get_base_type(base_type);
+:(replace{} "const type_tree* get_base_type(const type_tree* t)")
+const type_tree* get_base_type(const type_tree* t) {
+  const type_tree* result = t->atom ? t : t->left;
+  if (!result->atom)
+    raise << "invalid type " << to_string(t) << '\n' << end();
+  return result;
+}
 
 :(scenario ill_formed_container)
 % Hide_errors = true;
@@ -498,7 +516,7 @@ def main [
 //: that we need to teach about type ingredients.
 
 :(before "End compute_container_sizes Non-atom Special-cases")
-const type_tree* root = root_type(type);
+const type_tree* root = get_base_type(type);
 type_info& info = get(Type, root->value);
 if (info.kind == CONTAINER) {
   compute_container_sizes(info, type, pending_metadata, location_for_error_messages);
@@ -558,7 +576,7 @@ void test_container_sizes_recursive_shape_shifting_container() {
 }
 
 :(before "End compute_container_address_offsets Non-atom Special-cases")
-const type_tree* root = root_type(type);
+const type_tree* root = get_base_type(type);
 type_info& info = get(Type, root->value);
 if (info.kind == CONTAINER) {
   compute_container_address_offsets(info, type, location_for_error_messages);
diff --git a/069hash.cc b/069hash.cc
index ac301b5c..94cfcda9 100644
--- a/069hash.cc
+++ b/069hash.cc
@@ -89,7 +89,7 @@ size_t hash_mu_array(size_t h, const reagent& r) {
 }
 
 size_t hash_mu_container(size_t h, const reagent& r) {
-  type_info& info = get(Type, root_type(r.type)->value);
+  type_info& info = get(Type, get_base_type(r.type)->value);
   int address = r.value;
   int offset = 0;
   for (int i = 0;  i < SIZE(info.elements);  ++i) {
@@ -104,7 +104,7 @@ size_t hash_mu_container(size_t h, const reagent& r) {
 }
 
 size_t hash_mu_exclusive_container(size_t h, const reagent& r) {
-  const type_tree* type = root_type(r.type);
+  const type_tree* type = get_base_type(r.type);
   assert(type->value);
   int tag = get(Memory, r.value);
   reagent/*copy*/ variant = variant_type(r, tag);
diff --git a/071recipe.cc b/071recipe.cc
index 345057d5..6efb023d 100644
--- a/071recipe.cc
+++ b/071recipe.cc
@@ -205,7 +205,9 @@ recipe from_reagent(const reagent& r) {
     assert(r.type->name == "recipe");
     return result_header;
   }
-  assert(root_type(r.type)->name == "recipe");
+  const type_tree* root_type = r.type->atom ? r.type : r.type->left;
+  assert(root_type->atom);
+  assert(root_type->name == "recipe");
   const type_tree* curr = r.type->right;
   for (/*nada*/;  curr && !curr->atom;  curr = curr->right) {
     if (curr->left->atom && curr->left->name == "->") {
diff --git a/073wait.cc b/073wait.cc
index a243982b..917a7a03 100644
--- a/073wait.cc
+++ b/073wait.cc
@@ -205,9 +205,9 @@ case GET_LOCATION: {
     raise << maybe(current_recipe_name()) << "tried to access location 0 in '" << to_original_string(current_instruction()) << "'\n" << end();
     break;
   }
-  const type_tree* base_root_type = root_type(base.type);
+  const type_tree* base_type = get_base_type(base.type);
   int offset = ingredients.at(1).at(0);
-  if (offset < 0 || offset >= SIZE(get(Type, base_root_type->value).elements)) break;  // copied from Check above
+  if (offset < 0 || offset >= SIZE(get(Type, base_type->value).elements)) break;  // copied from Check above
   int result = base_address;
   for (int i = 0;  i < offset;  ++i)
     result += size_of(element_type(base.type, i));