about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-11-04 13:14:41 -0800
committerKartik K. Agaram <vc@akkartik.com>2015-11-04 13:14:41 -0800
commit5d4a1d3b80066711a00b111a4832eecdb547024f (patch)
treedd1f0aa85a32916c6fae408cf4e34ec15d1e2268
parent4c3e1f0780da52c72be467c6bfd3b2073ce57190 (diff)
downloadmu-5d4a1d3b80066711a00b111a4832eecdb547024f.tar.gz
2354
-rw-r--r--010vm.cc4
-rw-r--r--058generic_container.cc40
2 files changed, 41 insertions, 3 deletions
diff --git a/010vm.cc b/010vm.cc
index 906a2cd1..17f2140c 100644
--- a/010vm.cc
+++ b/010vm.cc
@@ -389,7 +389,7 @@ string dump_types(const reagent& x) {
   return out.str();
 }
 
-void dump_types(type_tree* type, ostream& out) {
+void dump_types(const type_tree* type, ostream& out) {
   // abbreviate a single-node tree to just its contents
   if (!type->left && !type->right) {
     dump_type_name(type->value, out);
@@ -398,7 +398,7 @@ void dump_types(type_tree* type, ostream& out) {
   dump_types_tree(type, out);
 }
 
-void dump_types_tree(type_tree* type, ostream& out) {
+void dump_types_tree(const type_tree* type, ostream& out) {
   out << "<";
   if (type->left)
     dump_types_tree(type->left, out);
diff --git a/058generic_container.cc b/058generic_container.cc
index e36872c4..4ab2a5cd 100644
--- a/058generic_container.cc
+++ b/058generic_container.cc
@@ -75,6 +75,12 @@ if (type->value >= START_TYPE_INGREDIENTS
 :(before "End size_of(type) Container Cases")
 if (t.elements.at(i)->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->right);
+  if (!size) {
+    ostringstream out;
+    dump_types(type, out);
+    raise_error << "illegal type '" << out.str() << "' seems to be missing a type ingredient or three\n" << end();
+  }
   result += size_of_type_ingredient(t.elements.at(i), type->right);
   continue;
 }
@@ -84,10 +90,11 @@ if (t.elements.at(i)->value >= START_TYPE_INGREDIENTS) {
 long long int size_of_type_ingredient(const type_tree* element_template, const type_tree* rest_of_use) {
   long long int type_ingredient_index = element_template->value - START_TYPE_INGREDIENTS;
   const type_tree* curr = rest_of_use;
+  if (!curr) return 0;
   while (type_ingredient_index > 0) {
-    assert(curr);
     --type_ingredient_index;
     curr = curr->right;
+    if (!curr) return 0;
   }
   assert(curr);
   assert(!curr->left);  // unimplemented
@@ -129,6 +136,9 @@ recipe main [
 
 :(before "End element_type Special-cases")
 if (contains_type_ingredient(element)) {
+  if (!canonized_base.type->right) {
+    raise_error << "illegal type '" << dump_types(canonized_base) << "' seems to be missing a type ingredient or three\n" << end();
+  }
   replace_type_ingredients(element.type, canonized_base.type->right);
 }
 
@@ -144,8 +154,15 @@ bool contains_type_ingredient(const type_tree* type) {
 }
 
 void replace_type_ingredients(type_tree* element_type, type_tree* callsite_type) {
+  if (!callsite_type) return;  // error but it's already been raised above
   if (!element_type) return;
   if (element_type->value >= START_TYPE_INGREDIENTS) {
+    if (!has_nth_type(callsite_type, element_type->value-START_TYPE_INGREDIENTS)) {
+      ostringstream out;
+      dump_types(callsite_type, out);
+      raise_error << "illegal type '" << out.str() << "' seems to be missing a type ingredient or three\n" << end();
+      return;
+    }
     element_type->value = nth_type(callsite_type, element_type->value-START_TYPE_INGREDIENTS);
   }
   replace_type_ingredients(element_type->right, callsite_type);
@@ -157,6 +174,27 @@ type_ordinal nth_type(type_tree* base, long long int n) {
   return nth_type(base->right, n-1);
 }
 
+bool has_nth_type(type_tree* base, long long int n) {
+  assert(n >= 0);
+  if (base == NULL) return false;
+  if (n == 0) return true;
+  return has_nth_type(base->right, n-1);
+}
+
+:(scenario get_on_generic_container_error)
+% Hide_errors = true;
+container foo:_t [
+  x:_t
+  y:number
+]
+recipe main [
+  10:foo:point <- merge 14, 15, 16
+  1:number <- get 10:foo, 1:offset
+]
++error: illegal type 'foo' seems to be missing a type ingredient or three
+
+//: get-address similarly
+
 :(scenario get_address_on_generic_container)
 container foo:_t [
   x:_t