diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-02-14 23:30:59 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-02-15 00:14:34 -0800 |
commit | 5ba1c3b9e101b31fc38dae1701b62c373d5ef6f7 (patch) | |
tree | 6f0323c262fe7aa0fa917351518cef10d9873b46 /033exclusive_container.cc | |
parent | 996a8acd6c2ce1c7d3b13cfbd799269669b0038b (diff) | |
download | mu-5ba1c3b9e101b31fc38dae1701b62c373d5ef6f7.tar.gz |
2657 - type-checking for 'merge' instructions
Diffstat (limited to '033exclusive_container.cc')
-rw-r--r-- | 033exclusive_container.cc | 139 |
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") |