diff options
Diffstat (limited to '055shape_shifting_container.cc')
-rw-r--r-- | 055shape_shifting_container.cc | 682 |
1 files changed, 391 insertions, 291 deletions
diff --git a/055shape_shifting_container.cc b/055shape_shifting_container.cc index 1fb5f176..909e6fc5 100644 --- a/055shape_shifting_container.cc +++ b/055shape_shifting_container.cc @@ -24,93 +24,122 @@ const type_tree* get_base_type(const type_tree* t) { return result; } -:(scenario ill_formed_container) -% Hide_errors = true; -def main [ - {1: ((foo) num)} <- copy 0 -] -# no crash +:(code) +void test_ill_formed_container() { + Hide_errors = true; + run( + "def main [\n" + " {1: ((foo) num)} <- copy 0\n" + "]\n" + ); + // no crash +} //: update size_of to handle non-atom container types -:(scenario size_of_shape_shifting_container) -container foo:_t [ - x:_t - y:num -] -def main [ - 1:foo:num <- merge 12, 13 - 3:foo:point <- merge 14, 15, 16 -] -+mem: storing 12 in location 1 -+mem: storing 13 in location 2 -+mem: storing 14 in location 3 -+mem: storing 15 in location 4 -+mem: storing 16 in location 5 - -:(scenario size_of_shape_shifting_container_2) -# multiple type ingredients -container foo:_a:_b [ - x:_a - y:_b -] -def main [ - 1:foo:num:bool <- merge 34, true -] -$error: 0 - -:(scenario size_of_shape_shifting_container_3) -container foo:_a:_b [ - x:_a - y:_b -] -def main [ - 1:text <- new [abc] - # compound types for type ingredients - {3: (foo number (address array character))} <- merge 34/x, 1:text/y -] -$error: 0 - -:(scenario size_of_shape_shifting_container_4) -container foo:_a:_b [ - x:_a - y:_b -] -container bar:_a:_b [ - # dilated element - {data: (foo _a (address _b))} -] -def main [ - 1:text <- new [abc] - 3:bar:num:@:char <- merge 34/x, 1:text/y -] -$error: 0 - -:(scenario shape_shifting_container_extend) -container foo:_a [ - x:_a -] -container foo:_a [ - y:_a -] -$error: 0 - -:(scenario shape_shifting_container_extend_error) -% Hide_errors = true; -container foo:_a [ - x:_a -] -container foo:_b [ - y:_b -] -+error: headers of container 'foo' must use identical type ingredients - -:(scenario type_ingredient_must_start_with_underscore) -% Hide_errors = true; -container foo:t [ - x:num -] -+error: foo: type ingredient 't' must begin with an underscore +void test_size_of_shape_shifting_container() { + run( + "container foo:_t [\n" + " x:_t\n" + " y:num\n" + "]\n" + "def main [\n" + " 1:foo:num <- merge 12, 13\n" + " 3:foo:point <- merge 14, 15, 16\n" + "]\n" + ); + CHECK_TRACE_CONTENTS( + "mem: storing 12 in location 1\n" + "mem: storing 13 in location 2\n" + "mem: storing 14 in location 3\n" + "mem: storing 15 in location 4\n" + "mem: storing 16 in location 5\n" + ); +} +void test_size_of_shape_shifting_container_2() { + run( + // multiple type ingredients + "container foo:_a:_b [\n" + " x:_a\n" + " y:_b\n" + "]\n" + "def main [\n" + " 1:foo:num:bool <- merge 34, true\n" + "]\n" + ); + CHECK_TRACE_COUNT("error", 0); +} +void test_size_of_shape_shifting_container_3() { + run( + "container foo:_a:_b [\n" + " x:_a\n" + " y:_b\n" + "]\n" + "def main [\n" + " 1:text <- new [abc]\n" + // compound types for type ingredients + " {3: (foo number (address array character))} <- merge 34/x, 1:text/y\n" + "]\n" + ); + CHECK_TRACE_COUNT("error", 0); +} + +void test_size_of_shape_shifting_container_4() { + run( + "container foo:_a:_b [\n" + " x:_a\n" + " y:_b\n" + "]\n" + "container bar:_a:_b [\n" + // dilated element + " {data: (foo _a (address _b))}\n" + "]\n" + "def main [\n" + " 1:text <- new [abc]\n" + " 3:bar:num:@:char <- merge 34/x, 1:text/y\n" + "]\n" + ); + CHECK_TRACE_COUNT("error", 0); +} + +void test_shape_shifting_container_extend() { + run( + "container foo:_a [\n" + " x:_a\n" + "]\n" + "container foo:_a [\n" + " y:_a\n" + "]\n" + ); + CHECK_TRACE_COUNT("error", 0); +} + +void test_shape_shifting_container_extend_error() { + Hide_errors = true; + run( + "container foo:_a [\n" + " x:_a\n" + "]\n" + "container foo:_b [\n" + " y:_b\n" + "]\n" + ); + CHECK_TRACE_CONTENTS( + "error: headers of container 'foo' must use identical type ingredients\n" + ); +} + +void test_type_ingredient_must_start_with_underscore() { + Hide_errors = true; + run( + "container foo:t [\n" + " x:num\n" + "]\n" + ); + CHECK_TRACE_CONTENTS( + "error: foo: type ingredient 't' must begin with an underscore\n" + ); +} :(before "End Globals") // We'll use large type ordinals to mean "the following type of the variable". @@ -212,97 +241,129 @@ if (type->value >= START_TYPE_INGREDIENTS && (type->value - START_TYPE_INGREDIENTS) < SIZE(get(Type, type->value).type_ingredient_names)) return; -:(scenario size_of_shape_shifting_exclusive_container) -exclusive-container foo:_t [ - x:_t - y:num -] -def main [ - 1:foo:num <- merge 0/x, 34 - 3:foo:point <- merge 0/x, 15, 16 - 6:foo:point <- merge 1/y, 23 -] -+run: {1: ("foo" "number")} <- merge {0: "literal", "x": ()}, {34: "literal"} -+mem: storing 0 in location 1 -+mem: storing 34 in location 2 -+run: {3: ("foo" "point")} <- merge {0: "literal", "x": ()}, {15: "literal"}, {16: "literal"} -+mem: storing 0 in location 3 -+mem: storing 15 in location 4 -+mem: storing 16 in location 5 -+run: {6: ("foo" "point")} <- merge {1: "literal", "y": ()}, {23: "literal"} -+mem: storing 1 in location 6 -+mem: storing 23 in location 7 -+run: return -# no other stores -% CHECK_EQ(trace_count_prefix("mem", "storing"), 7); +:(code) +void test_size_of_shape_shifting_exclusive_container() { + run( + "exclusive-container foo:_t [\n" + " x:_t\n" + " y:num\n" + "]\n" + "def main [\n" + " 1:foo:num <- merge 0/x, 34\n" + " 3:foo:point <- merge 0/x, 15, 16\n" + " 6:foo:point <- merge 1/y, 23\n" + "]\n" + ); + CHECK_TRACE_CONTENTS( + "run: {1: (\"foo\" \"number\")} <- merge {0: \"literal\", \"x\": ()}, {34: \"literal\"}\n" + "mem: storing 0 in location 1\n" + "mem: storing 34 in location 2\n" + "run: {3: (\"foo\" \"point\")} <- merge {0: \"literal\", \"x\": ()}, {15: \"literal\"}, {16: \"literal\"}\n" + "mem: storing 0 in location 3\n" + "mem: storing 15 in location 4\n" + "mem: storing 16 in location 5\n" + "run: {6: (\"foo\" \"point\")} <- merge {1: \"literal\", \"y\": ()}, {23: \"literal\"}\n" + "mem: storing 1 in location 6\n" + "mem: storing 23 in location 7\n" + "run: return\n" + ); + // no other stores + CHECK_EQ(trace_count_prefix("mem", "storing"), 7); +} :(before "End variant_type Special-cases") if (contains_type_ingredient(element)) replace_type_ingredients(element.type, type->right, info, " while computing variant type of exclusive-container"); -:(scenario get_on_shape_shifting_container) -container foo:_t [ - x:_t - y:num -] -def main [ - 1:foo:point <- merge 14, 15, 16 - 4:num <- get 1:foo:point, y:offset -] -+mem: storing 16 in location 4 - -:(scenario get_on_shape_shifting_container_2) -container foo:_t [ - x:_t - y:num -] -def main [ - 1:foo:point <- merge 14, 15, 16 - 4:point <- get 1:foo:point, x:offset -] -+mem: storing 14 in location 4 -+mem: storing 15 in location 5 - -:(scenario get_on_shape_shifting_container_3) -container foo:_t [ - x:_t - y:num -] -def main [ - 1:num/alloc-id, 2:num <- copy 0, 34 - 3:foo:&:point <- merge 1:&:point, 48 - 6:&:point <- get 1:foo:&:point, x:offset -] -+mem: storing 0 in location 6 -+mem: storing 34 in location 7 - -:(scenario get_on_shape_shifting_container_inside_container) -container foo:_t [ - x:_t - y:num -] -container bar [ - x:foo:point - y:num -] -def main [ - 1:bar <- merge 14, 15, 16, 17 - 5:num <- get 1:bar, 1:offset -] -+mem: storing 17 in location 5 - -:(scenario get_on_complex_shape_shifting_container) -container foo:_a:_b [ - x:_a - y:_b -] -def main [ - 1:text <- new [abc] - {3: (foo number (address array character))} <- merge 34/x, 1:text/y - 6:text <- get {3: (foo number (address array character))}, y:offset - 8:bool <- equal 1:text, 6:text -] -+mem: storing 1 in location 8 +:(code) +void test_get_on_shape_shifting_container() { + run( + "container foo:_t [\n" + " x:_t\n" + " y:num\n" + "]\n" + "def main [\n" + " 1:foo:point <- merge 14, 15, 16\n" + " 4:num <- get 1:foo:point, y:offset\n" + "]\n" + ); + CHECK_TRACE_CONTENTS( + "mem: storing 16 in location 4\n" + ); +} + +void test_get_on_shape_shifting_container_2() { + run( + "container foo:_t [\n" + " x:_t\n" + " y:num\n" + "]\n" + "def main [\n" + " 1:foo:point <- merge 14, 15, 16\n" + " 4:point <- get 1:foo:point, x:offset\n" + "]\n" + ); + CHECK_TRACE_CONTENTS( + "mem: storing 14 in location 4\n" + "mem: storing 15 in location 5\n" + ); +} + +void test_get_on_shape_shifting_container_3() { + run( + "container foo:_t [\n" + " x:_t\n" + " y:num\n" + "]\n" + "def main [\n" + " 1:num/alloc-id, 2:num <- copy 0, 34\n" + " 3:foo:&:point <- merge 1:&:point, 48\n" + " 6:&:point <- get 1:foo:&:point, x:offset\n" + "]\n" + ); + CHECK_TRACE_CONTENTS( + "mem: storing 0 in location 6\n" + "mem: storing 34 in location 7\n" + ); +} + +void test_get_on_shape_shifting_container_inside_container() { + run( + "container foo:_t [\n" + " x:_t\n" + " y:num\n" + "]\n" + "container bar [\n" + " x:foo:point\n" + " y:num\n" + "]\n" + "def main [\n" + " 1:bar <- merge 14, 15, 16, 17\n" + " 5:num <- get 1:bar, 1:offset\n" + "]\n" + ); + CHECK_TRACE_CONTENTS( + "mem: storing 17 in location 5\n" + ); +} + +void test_get_on_complex_shape_shifting_container() { + run( + "container foo:_a:_b [\n" + " x:_a\n" + " y:_b\n" + "]\n" + "def main [\n" + " 1:text <- new [abc]\n" + " {3: (foo number (address array character))} <- merge 34/x, 1:text/y\n" + " 6:text <- get {3: (foo number (address array character))}, y:offset\n" + " 8:bool <- equal 1:text, 6:text\n" + "]\n" + ); + CHECK_TRACE_CONTENTS( + "mem: storing 1 in location 8\n" + ); +} :(before "End element_type Special-cases") replace_type_ingredients(element, type, info, " while computing element type of container"); @@ -341,20 +402,25 @@ if (t.kind == EXCLUSIVE_CONTAINER) { return result+1; } -:(scenario complex_shape_shifting_exclusive_container) -exclusive-container foo:_a [ - x:_a - y:num -] -def main [ - 1:text <- new [abc] - 3:foo:point <- merge 0/variant, 34/xx, 35/xy - 10:point, 20:bool <- maybe-convert 3:foo:point, 0/variant -] -+mem: storing 1 in location 20 -+mem: storing 35 in location 11 - :(code) +void test_complex_shape_shifting_exclusive_container() { + run( + "exclusive-container foo:_a [\n" + " x:_a\n" + " y:num\n" + "]\n" + "def main [\n" + " 1:text <- new [abc]\n" + " 3:foo:point <- merge 0/variant, 34/xx, 35/xy\n" + " 10:point, 20:bool <- maybe-convert 3:foo:point, 0/variant\n" + "]\n" + ); + CHECK_TRACE_CONTENTS( + "mem: storing 1 in location 20\n" + "mem: storing 35 in location 11\n" + ); +} + bool contains_type_ingredient(const reagent& x) { return contains_type_ingredient(x.type); } @@ -560,114 +626,148 @@ bool has_nth_type(const type_tree* base, int n) { return has_nth_type(base->right, n-1); } -:(scenario get_on_shape_shifting_container_error) -% Hide_errors = true; -container foo:_t [ - x:_t - y:num -] -def main [ - 1:foo:point <- merge 14, 15, 16 - 10:num <- get 1:foo, 1:offset -] -# todo: improve error message -+error: illegal type "foo" seems to be missing a type ingredient or three while computing element type of container - -:(scenario typos_in_container_definitions) -% Hide_errors = true; -container foo:_t [ - x:adress:_t # typo -] -def main [ - local-scope - x:address:foo:num <- new {(foo num): type} -] -# no crash - -:(scenario typos_in_recipes) -% Hide_errors = true; -def foo [ - local-scope - x:adress:array:number <- copy null # typo -] -# shouldn't crash +void test_get_on_shape_shifting_container_error() { + Hide_errors = true; + run( + "container foo:_t [\n" + " x:_t\n" + " y:num\n" + "]\n" + "def main [\n" + " 1:foo:point <- merge 14, 15, 16\n" + " 10:num <- get 1:foo, 1:offset\n" + "]\n" + ); + CHECK_TRACE_CONTENTS( + "error: illegal type \"foo\" seems to be missing a type ingredient or three while computing element type of container\n" + ); + // todo: improve error message +} + +void test_typos_in_container_definitions() { + Hide_errors = true; + run( + "container foo:_t [\n" + " x:adress:_t # typo\n" + "]\n" + "def main [\n" + " local-scope\n" + " x:address:foo:num <- new {(foo num): type}\n" + "]\n" + ); + // no crash +} + +void test_typos_in_recipes() { + Hide_errors = true; + run( + "def foo [\n" + " local-scope\n" + " x:adress:array:number <- copy null # typo\n" + "]\n" + ); + // shouldn't crash +} //:: 'merge' on shape-shifting containers -:(scenario merge_check_shape_shifting_container_containing_exclusive_container) -container foo:_elem [ - x:num - y:_elem -] -exclusive-container bar [ - x:num - y:num -] -def main [ - 1:foo:bar <- 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_shape_shifting_container_containing_exclusive_container_2) -% Hide_errors = true; -container foo:_elem [ - x:num - y:_elem -] -exclusive-container bar [ - x:num - y:num -] -def main [ - 1:foo:bar <- merge 23, 1/y, 34, 35 -] -+error: main: too many ingredients in '1:foo:bar <- merge 23, 1/y, 34, 35' - -:(scenario merge_check_shape_shifting_exclusive_container_containing_container) -exclusive-container foo:_elem [ - x:num - y:_elem -] -container bar [ - x:num - y:num -] -def main [ - 1:foo:bar <- 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_shape_shifting_exclusive_container_containing_container_2) -exclusive-container foo:_elem [ - x:num - y:_elem -] -container bar [ - x:num - y:num -] -def main [ - 1:foo:bar <- merge 0/x, 23 -] -$error: 0 - -:(scenario merge_check_shape_shifting_exclusive_container_containing_container_3) -% Hide_errors = true; -exclusive-container foo:_elem [ - x:num - y:_elem -] -container bar [ - x:num - y:num -] -def main [ - 1:foo:bar <- merge 1/y, 23 -] -+error: main: too few ingredients in '1:foo:bar <- merge 1/y, 23' +void test_merge_check_shape_shifting_container_containing_exclusive_container() { + run( + "container foo:_elem [\n" + " x:num\n" + " y:_elem\n" + "]\n" + "exclusive-container bar [\n" + " x:num\n" + " y:num\n" + "]\n" + "def main [\n" + " 1:foo:bar <- merge 23, 1/y, 34\n" + "]\n" + ); + CHECK_TRACE_CONTENTS( + "mem: storing 23 in location 1\n" + "mem: storing 1 in location 2\n" + "mem: storing 34 in location 3\n" + ); + CHECK_TRACE_COUNT("error", 0); +} + +void test_merge_check_shape_shifting_container_containing_exclusive_container_2() { + Hide_errors = true; + run( + "container foo:_elem [\n" + " x:num\n" + " y:_elem\n" + "]\n" + "exclusive-container bar [\n" + " x:num\n" + " y:num\n" + "]\n" + "def main [\n" + " 1:foo:bar <- merge 23, 1/y, 34, 35\n" + "]\n" + ); + CHECK_TRACE_CONTENTS( + "error: main: too many ingredients in '1:foo:bar <- merge 23, 1/y, 34, 35'\n" + ); +} + +void test_merge_check_shape_shifting_exclusive_container_containing_container() { + run( + "exclusive-container foo:_elem [\n" + " x:num\n" + " y:_elem\n" + "]\n" + "container bar [\n" + " x:num\n" + " y:num\n" + "]\n" + "def main [\n" + " 1:foo:bar <- merge 1/y, 23, 34\n" + "]\n" + ); + CHECK_TRACE_CONTENTS( + "mem: storing 1 in location 1\n" + "mem: storing 23 in location 2\n" + "mem: storing 34 in location 3\n" + ); + CHECK_TRACE_COUNT("error", 0); +} + +void test_merge_check_shape_shifting_exclusive_container_containing_container_2() { + run( + "exclusive-container foo:_elem [\n" + " x:num\n" + " y:_elem\n" + "]\n" + "container bar [\n" + " x:num\n" + " y:num\n" + "]\n" + "def main [\n" + " 1:foo:bar <- merge 0/x, 23\n" + "]\n" + ); + CHECK_TRACE_COUNT("error", 0); +} + +void test_merge_check_shape_shifting_exclusive_container_containing_container_3() { + Hide_errors = true; + run( + "exclusive-container foo:_elem [\n" + " x:num\n" + " y:_elem\n" + "]\n" + "container bar [\n" + " x:num\n" + " y:num\n" + "]\n" + "def main [\n" + " 1:foo:bar <- merge 1/y, 23\n" + "]\n" + ); + CHECK_TRACE_CONTENTS( + "error: main: too few ingredients in '1:foo:bar <- merge 1/y, 23'\n" + ); +} |