From 5ba1c3b9e101b31fc38dae1701b62c373d5ef6f7 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Sun, 14 Feb 2016 23:30:59 -0800 Subject: 2657 - type-checking for 'merge' instructions --- 033exclusive_container.cc | 139 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) (limited to '033exclusive_container.cc') 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") -- cgit 1.4.1-2-gfad0