about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-10-05 17:02:32 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-10-05 17:02:32 -0700
commitfb85b3b46d3e655f529e13b477fadf2782e63d94 (patch)
tree21ac118e2e20e37c2027dffa48f288887cd09f36
parentfb5470bc5a25960a0ee1b0757bffe59131978e56 (diff)
downloadmu-fb85b3b46d3e655f529e13b477fadf2782e63d94.tar.gz
2242
-rw-r--r--030container.cc2
-rw-r--r--032array.cc55
2 files changed, 54 insertions, 3 deletions
diff --git a/030container.cc b/030container.cc
index 529ec7c3..817a8c47 100644
--- a/030container.cc
+++ b/030container.cc
@@ -157,6 +157,7 @@ case GET: {
   element.types = Type[base_type].elements.at(offset_value);
   if (!types_match(product, element)) {
     raise << maybe(Recipe[r].name) << "'get' " << offset.original_string << " (" << offset_value << ") on " << Type[base_type].name << " can't be saved in " << product.original_string << "; type should be " << dump_types(element) << '\n' << end();
+    break;
   }
   break;
 }
@@ -285,6 +286,7 @@ case GET_ADDRESS: {
   element.types.insert(element.types.begin(), Type_ordinal["address"]);
   if (!types_match(product, element)) {
     raise << maybe(Recipe[r].name) << "'get-address' " << offset.original_string << " (" << offset_value << ") on " << Type[base_type].name << " can't be saved in " << product.original_string << "; type should be " << dump_types(element) << '\n' << end();
+    break;
   }
   break;
 }
diff --git a/032array.cc b/032array.cc
index e81686dd..f8df003f 100644
--- a/032array.cc
+++ b/032array.cc
@@ -154,6 +154,15 @@ case INDEX: {
     raise << maybe(Recipe[r].name) << "'index' on a non-array " << base.original_string << '\n' << end();
     break;
   }
+  if (inst.products.empty()) break;
+  reagent product = inst.products.at(0);
+  canonize_type(product);
+  reagent element;
+  element.types = array_element(base.types);
+  if (!types_match(product, element)) {
+    raise << maybe(Recipe[r].name) << "'index' on " << base.original_string << " can't be saved in " << product.original_string << "; type should be " << dump_types(element) << '\n' << end();
+    break;
+  }
   break;
 }
 :(before "End Primitive Recipe Implementations")
@@ -222,11 +231,26 @@ recipe main [
   5:number <- copy 14
   6:number <- copy 15
   7:number <- copy 16
-  8:address:array:point <- copy 1
+  8:address:array:point <- copy 1/raw
   index *8:address:array:point, -1
 ]
 +warn: main: invalid index -1
 
+:(scenario index_product_type_mismatch)
+% Hide_warnings = true;
+recipe main [
+  1:array:point:3 <- create-array
+  2:number <- copy 14
+  3:number <- copy 15
+  4:number <- copy 16
+  5:number <- copy 14
+  6:number <- copy 15
+  7:number <- copy 16
+  8:address:array:point <- copy 1/raw
+  9:number <- index *8:address:array:point, 0
+]
++warn: main: 'index' on *8:address:array:point can't be saved in 9:number; type should be point
+
 //:: To write to elements of containers, you need their address.
 
 :(scenario index_address)
@@ -235,7 +259,7 @@ recipe main [
   2:number <- copy 14
   3:number <- copy 15
   4:number <- copy 16
-  5:number <- index-address 1:array:number, 0
+  5:address:number <- index-address 1:array:number, 0
 ]
 +mem: storing 2 in location 5
 
@@ -255,6 +279,16 @@ case INDEX_ADDRESS: {
     raise << current_recipe_name () << "'index-address' on a non-array " << base.original_string << '\n' << end();
     break;
   }
+  if (inst.products.empty()) break;
+  reagent product = inst.products.at(0);
+  canonize_type(product);
+  reagent element;
+  element.types = array_element(base.types);
+  element.types.insert(element.types.begin(), Type_ordinal["address"]);
+  if (!types_match(product, element)) {
+    raise << maybe(Recipe[r].name) << "'index' on " << base.original_string << " can't be saved in " << product.original_string << "; type should be " << dump_types(element) << '\n' << end();
+    break;
+  }
   break;
 }
 :(before "End Primitive Recipe Implementations")
@@ -303,11 +337,26 @@ recipe main [
   5:number <- copy 14
   6:number <- copy 15
   7:number <- copy 16
-  8:address:array:point <- copy 1  # unsafe
+  8:address:array:point <- copy 1/raw
   index-address *8:address:array:point, -1
 ]
 +warn: main: invalid index -1
 
+:(scenario index_address_product_type_mismatch)
+% Hide_warnings = true;
+recipe main [
+  1:array:point:3 <- create-array
+  2:number <- copy 14
+  3:number <- copy 15
+  4:number <- copy 16
+  5:number <- copy 14
+  6:number <- copy 15
+  7:number <- copy 16
+  8:address:array:point <- copy 1/raw
+  9:address:number <- index-address *8:address:array:point, 0
+]
++warn: main: 'index' on *8:address:array:point can't be saved in 9:address:number; type should be address:point
+
 //:: compute the length of an array
 
 :(scenario array_length)