about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-02-19 02:21:37 -0800
committerKartik K. Agaram <vc@akkartik.com>2016-02-19 02:25:13 -0800
commitd4dea9bd5f2f80795bd1bf6871c73b863f0525a1 (patch)
treef51097814539b9b9663c9b0b88511278a22d6083
parent29c7c23c96b616297ac348b12c2cc2578c6ac724 (diff)
downloadmu-d4dea9bd5f2f80795bd1bf6871c73b863f0525a1.tar.gz
2679 - all tests passing again
Still not done, though:

a) There's a few memory leaks to track down, including one in hash from
2668.

b) replace_type_ingredients has gotten *even* uglier. I need to rethink
it.
-rw-r--r--030container.cc13
-rw-r--r--033exclusive_container.cc5
-rw-r--r--058shape_shifting_container.cc101
3 files changed, 55 insertions, 64 deletions
diff --git a/030container.cc b/030container.cc
index a7ae2984..15e6471f 100644
--- a/030container.cc
+++ b/030container.cc
@@ -87,6 +87,10 @@ if (type->value == 0) {
   assert(!type->left && !type->right);
   return 1;
 }
+if (!contains_key(Type, type->value)) {
+  raise_error << "no such type " << type->value << '\n' << end();
+  return 0;
+}
 type_info t = get(Type, type->value);
 if (t.kind == CONTAINER) {
   // size of a container is the sum of the sizes of its elements
@@ -97,8 +101,9 @@ if (t.kind == CONTAINER) {
       raise_error << "container " << t.name << " can't include itself as a member\n" << end();
       return 0;
     }
-    // End size_of(type) Container Cases
-    result += size_of(t.elements.at(i).type);
+    reagent tmp;
+    tmp.type = new type_tree(*type);
+    result += size_of(element_type(tmp, i));
   }
   return result;
 }
@@ -177,7 +182,7 @@ case GET: {
   long long int src = base_address;
   for (long long int i = 0; i < offset; ++i) {
     // End GET field Cases
-    src += size_of(get(Type, base_type).elements.at(i).type);
+    src += size_of(element_type(base, i));
   }
   trace(9998, "run") << "address to copy is " << src << end();
   reagent tmp = element_type(base, offset);
@@ -318,7 +323,7 @@ case GET_ADDRESS: {
   long long int result = base_address;
   for (long long int i = 0; i < offset; ++i) {
     // End GET_ADDRESS field Cases
-    result += size_of(get(Type, base_type).elements.at(i).type);
+    result += size_of(element_type(base, i));
   }
   trace(9998, "run") << "address to copy is " << result << end();
   products.resize(1);
diff --git a/033exclusive_container.cc b/033exclusive_container.cc
index 26169637..ec77e639 100644
--- a/033exclusive_container.cc
+++ b/033exclusive_container.cc
@@ -36,8 +36,9 @@ if (t.kind == EXCLUSIVE_CONTAINER) {
   // (So like containers, it can't contain arrays.)
   long long int result = 0;
   for (long long int i = 0; i < t.size; ++i) {
-    // End size_of(type) Exclusive Container Cases
-    long long int size = size_of(t.elements.at(i).type);
+    reagent tmp;
+    tmp.type = new type_tree(*type);
+    long long int size = size_of(variant_type(tmp, i));
     if (size > result) result = size;
   }
   // ...+1 for its tag.
diff --git a/058shape_shifting_container.cc b/058shape_shifting_container.cc
index 2a970a3f..319f0381 100644
--- a/058shape_shifting_container.cc
+++ b/058shape_shifting_container.cc
@@ -106,16 +106,6 @@ if (type->value >= START_TYPE_INGREDIENTS
     && (type->value - START_TYPE_INGREDIENTS) < SIZE(get(Type, type->value).type_ingredient_names))
   return;
 
-:(before "End size_of(type) Container Cases")
-if (t.elements.at(i).type->value >= START_TYPE_INGREDIENTS) {
-  trace(9999, "type") << "checking size of type ingredient\n" << end();
-  long long int size = size_of_type_ingredient(t.elements.at(i).type, type->right);
-  if (!size)
-    raise_error << "illegal type '" << debug_string(type) << "' seems to be missing a type ingredient or three\n" << end();
-  result += size;
-  continue;
-}
-
 :(scenario size_of_shape_shifting_exclusive_container)
 exclusive-container foo:_t [
   x:_t
@@ -135,16 +125,6 @@ recipe main [
 +mem: storing 23 in location 7
 $mem: 7
 
-:(before "End size_of(type) Exclusive Container Cases")
-if (t.elements.at(i).type->value >= START_TYPE_INGREDIENTS) {
-  trace(9999, "type") << "checking size of type ingredient\n" << end();
-  long long int size = size_of_type_ingredient(t.elements.at(i).type, type->right);
-  if (!size)
-    raise_error << "illegal type '" << debug_string(type) << "' seems to be missing a type ingredient or three\n" << end();
-  if (size > result) result = size;
-  continue;
-}
-
 :(code)
 // shape-shifting version of size_of
 long long int size_of_type_ingredient(const type_tree* element_template, const type_tree* rest_of_use) {
@@ -215,11 +195,26 @@ recipe main [
 ]
 +mem: storing 34 in location 2
 
+:(scenario get_on_shape_shifting_container_inside_container)
+container foo:_t [
+  x:_t
+  y:number
+]
+container bar [
+  x:foo:point
+  y:number
+]
+recipe main [
+  1:bar <- merge 14, 15, 16, 17
+  2:number <- get 1:bar, 1:offset
+]
++mem: storing 17 in location 2
+
 :(before "End element_type Special-cases")
 if (contains_type_ingredient(element)) {
   if (!canonized_base.type->right)
     raise_error << "illegal type '" << debug_string(canonized_base.type) << "' seems to be missing a type ingredient or three\n" << end();
-  replace_type_ingredients(element.type, element.properties.at(0).second, canonized_base.type->right, canonized_base.properties.at(0).second->right, info);
+  replace_type_ingredients(element.type, element.properties.at(0).second, canonized_base.type->right, canonized_base.properties.at(0).second ? canonized_base.properties.at(0).second->right : NULL, info);
 }
 
 :(code)
@@ -269,31 +264,36 @@ void replace_type_ingredients(type_tree* element_type, string_tree* element_type
     }
 
     // analogously update value/left/right of element_type_name
-    const string_tree* replacement_name = NULL;
-    // could compute erase_right again here, but why bother
-    {
-      const string_tree* curr = callsite_type_name;
-      for (long long int i = 0; i < type_ingredient_index; ++i)
-        curr = curr->right;
-      if (curr && curr->left)
-        replacement_name = curr->left;
-      else
-        replacement_name = curr;
+    if (callsite_type_name) {
+      const string_tree* replacement_name = NULL;
+      // could compute erase_right again here, but why bother
+      {
+        const string_tree* curr = callsite_type_name;
+        for (long long int i = 0; i < type_ingredient_index; ++i)
+          curr = curr->right;
+        if (curr && curr->left)
+          replacement_name = curr->left;
+        else
+          replacement_name = curr;
+      }
+      element_type_name->value = replacement_name->value;
+      assert(!element_type_name->left);  // since value is set
+      element_type_name->left = replacement_name->left ? new string_tree(*replacement_name->left) : NULL;
+      string_tree* old_right_name = element_type_name->right;
+      if (!erase_right) {
+        element_type_name->right = replacement_name->right ? new string_tree(*replacement_name->right) : NULL;
+        append(element_type_name->right, old_right_name);
+      }
+
+      replace_type_ingredients(old_right, old_right_name, callsite_type, callsite_type_name, container_info);
     }
-    element_type_name->value = replacement_name->value;
-    assert(!element_type_name->left);  // since value is set
-    element_type_name->left = replacement_name->left ? new string_tree(*replacement_name->left) : NULL;
-    string_tree* old_right_name = element_type_name->right;
-    if (!erase_right) {
-      element_type_name->right = replacement_name->right ? new string_tree(*replacement_name->right) : NULL;
-      append(element_type_name->right, old_right_name);
+    else {
+      replace_type_ingredients(old_right, NULL, callsite_type, callsite_type_name, container_info);
     }
-
-    replace_type_ingredients(old_right, old_right_name, callsite_type, callsite_type_name, container_info);
   }
   else {
-    replace_type_ingredients(element_type->left, element_type_name->left, callsite_type, callsite_type_name, container_info);
-    replace_type_ingredients(element_type->right, element_type_name->right, callsite_type, callsite_type_name, container_info);
+    replace_type_ingredients(element_type->left, element_type_name ? element_type_name->left : NULL, callsite_type, callsite_type_name, container_info);
+    replace_type_ingredients(element_type->right, element_type_name ? element_type_name->right : NULL, callsite_type, callsite_type_name, container_info);
   }
 }
 
@@ -475,21 +475,6 @@ if (type->value >= START_TYPE_INGREDIENTS) {
   continue;
 }
 
-:(scenario get_on_shape_shifting_container_inside_shape_shifting_container)
-container foo:_t [
-  x:_t
-  y:number
-]
-container bar [
-  x:foo:point
-  y:number
-]
-recipe main [
-  1:bar <- merge 14, 15, 16, 17
-  2:number <- get 1:bar, 1:offset
-]
-+mem: storing 17 in location 2
-
 //: 'merge' on shape-shifting containers
 
 :(scenario merge_check_shape_shifting_container_containing_exclusive_container)
@@ -577,5 +562,5 @@ recipe main [
 if (contains_type_ingredient(element)) {
   if (!canonized_base.type->right)
     raise_error << "illegal type '" << debug_string(canonized_base.type) << "' seems to be missing a type ingredient or three\n" << end();
-  replace_type_ingredients(element.type, element.properties.at(0).second, canonized_base.type->right, canonized_base.properties.at(0).second->right, info);
+  replace_type_ingredients(element.type, element.properties.at(0).second, canonized_base.type->right, canonized_base.properties.at(0).second ? canonized_base.properties.at(0).second->right : NULL, info);
 }