diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-11-04 13:14:41 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-11-04 13:14:41 -0800 |
commit | 5d4a1d3b80066711a00b111a4832eecdb547024f (patch) | |
tree | dd1f0aa85a32916c6fae408cf4e34ec15d1e2268 | |
parent | 4c3e1f0780da52c72be467c6bfd3b2073ce57190 (diff) | |
download | mu-5d4a1d3b80066711a00b111a4832eecdb547024f.tar.gz |
2354
-rw-r--r-- | 010vm.cc | 4 | ||||
-rw-r--r-- | 058generic_container.cc | 40 |
2 files changed, 41 insertions, 3 deletions
diff --git a/010vm.cc b/010vm.cc index 906a2cd1..17f2140c 100644 --- a/010vm.cc +++ b/010vm.cc @@ -389,7 +389,7 @@ string dump_types(const reagent& x) { return out.str(); } -void dump_types(type_tree* type, ostream& out) { +void dump_types(const type_tree* type, ostream& out) { // abbreviate a single-node tree to just its contents if (!type->left && !type->right) { dump_type_name(type->value, out); @@ -398,7 +398,7 @@ void dump_types(type_tree* type, ostream& out) { dump_types_tree(type, out); } -void dump_types_tree(type_tree* type, ostream& out) { +void dump_types_tree(const type_tree* type, ostream& out) { out << "<"; if (type->left) dump_types_tree(type->left, out); diff --git a/058generic_container.cc b/058generic_container.cc index e36872c4..4ab2a5cd 100644 --- a/058generic_container.cc +++ b/058generic_container.cc @@ -75,6 +75,12 @@ if (type->value >= START_TYPE_INGREDIENTS :(before "End size_of(type) Container Cases") if (t.elements.at(i)->value >= START_TYPE_INGREDIENTS) { trace(9999, "type") << "checking size of type ingredient\n" << end(); + long long int size = size_of_type_ingredient(t.elements.at(i), type->right); + if (!size) { + ostringstream out; + dump_types(type, out); + raise_error << "illegal type '" << out.str() << "' seems to be missing a type ingredient or three\n" << end(); + } result += size_of_type_ingredient(t.elements.at(i), type->right); continue; } @@ -84,10 +90,11 @@ if (t.elements.at(i)->value >= START_TYPE_INGREDIENTS) { long long int size_of_type_ingredient(const type_tree* element_template, const type_tree* rest_of_use) { long long int type_ingredient_index = element_template->value - START_TYPE_INGREDIENTS; const type_tree* curr = rest_of_use; + if (!curr) return 0; while (type_ingredient_index > 0) { - assert(curr); --type_ingredient_index; curr = curr->right; + if (!curr) return 0; } assert(curr); assert(!curr->left); // unimplemented @@ -129,6 +136,9 @@ recipe main [ :(before "End element_type Special-cases") if (contains_type_ingredient(element)) { + if (!canonized_base.type->right) { + raise_error << "illegal type '" << dump_types(canonized_base) << "' seems to be missing a type ingredient or three\n" << end(); + } replace_type_ingredients(element.type, canonized_base.type->right); } @@ -144,8 +154,15 @@ bool contains_type_ingredient(const type_tree* type) { } void replace_type_ingredients(type_tree* element_type, type_tree* callsite_type) { + if (!callsite_type) return; // error but it's already been raised above if (!element_type) return; if (element_type->value >= START_TYPE_INGREDIENTS) { + if (!has_nth_type(callsite_type, element_type->value-START_TYPE_INGREDIENTS)) { + ostringstream out; + dump_types(callsite_type, out); + raise_error << "illegal type '" << out.str() << "' seems to be missing a type ingredient or three\n" << end(); + return; + } element_type->value = nth_type(callsite_type, element_type->value-START_TYPE_INGREDIENTS); } replace_type_ingredients(element_type->right, callsite_type); @@ -157,6 +174,27 @@ type_ordinal nth_type(type_tree* base, long long int n) { return nth_type(base->right, n-1); } +bool has_nth_type(type_tree* base, long long int n) { + assert(n >= 0); + if (base == NULL) return false; + if (n == 0) return true; + return has_nth_type(base->right, n-1); +} + +:(scenario get_on_generic_container_error) +% Hide_errors = true; +container foo:_t [ + x:_t + y:number +] +recipe main [ + 10:foo:point <- merge 14, 15, 16 + 1:number <- get 10:foo, 1:offset +] ++error: illegal type 'foo' seems to be missing a type ingredient or three + +//: get-address similarly + :(scenario get_address_on_generic_container) container foo:_t [ x:_t |