about summary refs log tree commit diff stats
path: root/033exclusive_container.cc
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-02-14 23:30:59 -0800
committerKartik K. Agaram <vc@akkartik.com>2016-02-15 00:14:34 -0800
commit5ba1c3b9e101b31fc38dae1701b62c373d5ef6f7 (patch)
tree6f0323c262fe7aa0fa917351518cef10d9873b46 /033exclusive_container.cc
parent996a8acd6c2ce1c7d3b13cfbd799269669b0038b (diff)
downloadmu-5ba1c3b9e101b31fc38dae1701b62c373d5ef6f7.tar.gz
2657 - type-checking for 'merge' instructions
Diffstat (limited to '033exclusive_container.cc')
-rw-r--r--033exclusive_container.cc139
1 files changed, 139 insertions, 0 deletions
diff --git a/033exclusive_container.cc b/033exclusive_container.cc
index 46dd2e64..1d63f593 100644
--- a/033exclusive_container.cc
+++ b/033exclusive_container.cc
@@ -145,6 +145,7 @@ const reagent variant_type(const reagent& canonized_base, long long int tag) {
   assert(info.kind == EXCLUSIVE_CONTAINER);
   reagent element;
   element.type = new type_tree(*info.elements.at(tag));
+  element.properties.at(0).second = new string_tree(*info.element_type_names.at(tag));
   // End variant_type Special-cases
   return element;
 }
@@ -195,6 +196,144 @@ recipe main [
 +mem: storing 1 in location 4
 +mem: storing 34 in location 5
 
+//: type-checking for 'merge' on exclusive containers
+
+:(scenario merge_handles_exclusive_container)
+% Hide_errors = true;
+exclusive-container foo [
+  x:number
+  y:bar
+]
+container bar [
+  z:number
+]
+recipe main [
+  1:foo <- merge 0/x, 34
+]
++mem: storing 0 in location 1
++mem: storing 34 in location 2
+$error: 0
+
+:(scenario merge_requires_literal_tag_for_exclusive_container)
+% Hide_errors = true;
+exclusive-container foo [
+  x:number
+  y:bar
+]
+container bar [
+  z:number
+]
+recipe main [
+  local-scope
+  1:number <- copy 0
+  2:foo <- merge 1:number, 34
+]
++error: main: ingredient 0 of 'merge' should be a literal, for the tag of exclusive-container foo
+
+:(before "End valid_merge Cases")
+case EXCLUSIVE_CONTAINER: {
+  assert(state.data.top().container_element_index == 0);
+  trace(9999, "transform") << "checking exclusive container " << debug_string(container) << " vs ingredient " << ingredient_index << end();
+  if (!is_literal(ingredients.at(ingredient_index))) {
+    raise_error << maybe(caller.name) << "ingredient " << ingredient_index << " of 'merge' should be a literal, for the tag of exclusive-container " << container_info.name << '\n' << end();
+    return;
+  }
+  reagent ingredient = ingredients.at(ingredient_index);  // unnecessary copy just to keep this function from modifying caller
+  populate_value(ingredient);
+  if (ingredient.value >= SIZE(container_info.elements)) {
+    raise_error << maybe(caller.name) << "invalid tag at " << ingredient_index << " for " << container_info.name << " in '" << inst.to_string() << '\n' << end();
+    return;
+  }
+  reagent variant = variant_type(container, ingredient.value);
+  trace(9999, "transform") << "tag: " << ingredient.value << end();
+  // replace union with its variant
+  state.data.pop();
+  state.data.push(merge_check_point(variant, 0));
+  ++ingredient_index;
+  break;
+}
+
+:(scenario merge_check_container_containing_exclusive_container)
+% Hide_errors = true;
+container foo [
+  x:number
+  y:bar
+]
+exclusive-container bar [
+  x:number
+  y:number
+]
+recipe main [
+  1:foo <- merge 23, 1/y, 34
+]
++mem: storing 23 in location 1
++mem: storing 1 in location 2
++mem: storing 34 in location 3
+$error: 0
+
+:(scenario merge_check_container_containing_exclusive_container_2)
+% Hide_errors = true;
+container foo [
+  x:number
+  y:bar
+]
+exclusive-container bar [
+  x:number
+  y:number
+]
+recipe main [
+  1:foo <- merge 23, 1/y, 34, 35
+]
++error: main: too many ingredients in '1:foo <- merge 23, 1/y, 34, 35'
+
+:(scenario merge_check_exclusive_container_containing_container)
+% Hide_errors = true;
+exclusive-container foo [
+  x:number
+  y:bar
+]
+container bar [
+  x:number
+  y:number
+]
+recipe main [
+  1:foo <- merge 1/y, 23, 34
+]
++mem: storing 1 in location 1
++mem: storing 23 in location 2
++mem: storing 34 in location 3
+$error: 0
+
+:(scenario merge_check_exclusive_container_containing_container_2)
+% Hide_errors = true;
+exclusive-container foo [
+  x:number
+  y:bar
+]
+container bar [
+  x:number
+  y:number
+]
+recipe main [
+  1:foo <- merge 0/x, 23
+]
+$error: 0
+
+:(scenario merge_check_exclusive_container_containing_container_3)
+% Hide_errors = true;
+exclusive-container foo [
+  x:number
+  y:bar
+]
+container bar [
+  x:number
+  y:number
+]
+recipe main [
+  1:foo <- merge 1/y, 23
+]
++error: main: too few ingredients in '1:foo <- merge 1/y, 23'
+
 //: Since the different variants of an exclusive-container might have
 //: different sizes, relax the size mismatch check for 'merge' instructions.
 :(before "End size_mismatch(x) Cases")