diff options
-rw-r--r-- | 030container.cc | 25 | ||||
-rw-r--r-- | 031merge.cc | 10 | ||||
-rw-r--r-- | 036refcount.cc | 20 | ||||
-rw-r--r-- | 042name.cc | 4 | ||||
-rw-r--r-- | 055shape_shifting_container.cc | 38 | ||||
-rw-r--r-- | 069hash.cc | 4 | ||||
-rw-r--r-- | 071recipe.cc | 4 | ||||
-rw-r--r-- | 073wait.cc | 4 |
8 files changed, 68 insertions, 41 deletions
diff --git a/030container.cc b/030container.cc index 098c38c5..322364c0 100644 --- a/030container.cc +++ b/030container.cc @@ -148,25 +148,19 @@ void clear_container_metadata() { if (r.metadata.size) return r.metadata.size; :(before "End size_of(type) Special-cases") -const type_tree* root = root_type(type); -if (!contains_key(Type, root->value)) { - raise << "no such type " << root->value << '\n' << end(); +const type_tree* base_type = type; +// Update base_type in size_of(type) +if (!contains_key(Type, base_type->value)) { + raise << "no such type " << base_type->value << '\n' << end(); return 0; } -type_info t = get(Type, root->value); +type_info t = get(Type, base_type->value); if (t.kind == CONTAINER) { // Compute size_of Container if (!contains_key(Container_metadata, type)) return 1; // error raised elsewhere return get(Container_metadata, type).size; } -:(code) -const type_tree* root_type(const type_tree* t) { - const type_tree* result = t->atom ? t : t->left; - assert(result->atom); - return result; -} - //: precompute Container_metadata before we need size_of //: also store a copy in each reagent in each instruction in each recipe @@ -421,10 +415,11 @@ case GET: { :(code) const reagent element_type(const type_tree* type, int offset_value) { assert(offset_value >= 0); - const type_tree* root = root_type(type); - assert(contains_key(Type, root->value)); - assert(!get(Type, root->value).name.empty()); - const type_info& info = get(Type, root->value); + const type_tree* base_type = type; + // Update base_type in element_type + assert(contains_key(Type, base_type->value)); + assert(!get(Type, base_type->value).name.empty()); + const type_info& info = get(Type, base_type->value); assert(info.kind == CONTAINER); if (offset_value >= SIZE(info.elements)) return reagent(); // error handled elsewhere reagent/*copy*/ element = info.elements.at(offset_value); diff --git a/031merge.cc b/031merge.cc index 75dc466b..14999123 100644 --- a/031merge.cc +++ b/031merge.cc @@ -166,7 +166,7 @@ void check_merge_call(const vector<reagent>& ingredients, const reagent& product if (types_coercible(expected_ingredient, ingredients.at(ingredient_index))) { ++ingredient_index; ++state.data.top().container_element_index; - while (state.data.top().container_element_index >= SIZE(get(Type, root_type(state.data.top().container.type)->value).elements)) { + while (state.data.top().container_element_index >= SIZE(get(Type, get_base_type(state.data.top().container.type)->value).elements)) { state.data.pop(); if (state.data.empty()) { if (ingredient_index < SIZE(ingredients)) @@ -201,7 +201,7 @@ void check_merge_call(const vector<reagent>& ingredients, const reagent& product return; } ++state.data.top().container_element_index; - } while (state.data.top().container_element_index >= SIZE(get(Type, root_type(state.data.top().container.type)->value).elements)); + } while (state.data.top().container_element_index >= SIZE(get(Type, get_base_type(state.data.top().container.type)->value).elements)); } } } @@ -209,6 +209,12 @@ void check_merge_call(const vector<reagent>& ingredients, const reagent& product assert(false); } +// replaced in a later layer +// todo: find some clean way to take this call completely out of this layer +const type_tree* get_base_type(const type_tree* t) { + return t; +} + :(scenario merge_check_product) % Hide_errors = true; def main [ diff --git a/036refcount.cc b/036refcount.cc index 09bb5d30..6822314b 100644 --- a/036refcount.cc +++ b/036refcount.cc @@ -321,8 +321,10 @@ void compute_container_address_offsets(const type_tree* type, const string& loca compute_container_address_offsets(array_element(type), location_for_error_messages); // End compute_container_address_offsets Non-atom Special-cases } - if (!contains_key(Type, root_type(type)->value)) return; // error raised elsewhere - type_info& info = get(Type, root_type(type)->value); + const type_tree* base_type = type; + // Update base_type in compute_container_address_offsets + if (!contains_key(Type, base_type->value)) return; // error raised elsewhere + type_info& info = get(Type, base_type->value); if (info.kind == CONTAINER) { compute_container_address_offsets(info, type, location_for_error_messages); } @@ -353,12 +355,13 @@ void append_addresses(int base_offset, const type_tree* type, map<set<tag_condit get_or_insert(out, key).insert(address_element_info(base_offset, new type_tree(*type->right))); return; } - const type_tree* root = root_type(type); - const type_info& info = get(Type, root->value); + const type_tree* base_type = type; + // Update base_type in append_container_address_offsets + const type_info& info = get(Type, base_type->value); if (info.kind == CONTAINER) { for (int curr_index = 0, curr_offset = base_offset; curr_index < SIZE(info.elements); ++curr_index) { - trace(9993, "transform") << "checking container " << root->name << ", element " << curr_index << end(); - reagent/*copy*/ element = element_type(type, curr_index); // not root + trace(9993, "transform") << "checking container " << base_type->name << ", element " << curr_index << end(); + reagent/*copy*/ element = element_type(type, curr_index); // not base_type // Compute Container Address Offset(element) if (is_mu_address(element)) { trace(9993, "transform") << "address at offset " << curr_offset << end(); @@ -379,8 +382,9 @@ void append_addresses(int base_offset, const type_tree* type, map<set<tag_condit curr_offset += size_of(element); } else if (is_mu_exclusive_container(element)) { - const type_tree* element_root_type = root_type(element.type); - const type_info& element_info = get(Type, element_root_type->value); + const type_tree* element_base_type = element.type; + // Update element_base_type For Exclusive Container in append_addresses + const type_info& element_info = get(Type, element_base_type->value); for (int tag = 0; tag < SIZE(element_info.elements); ++tag) { set<tag_condition_info> new_key = key; new_key.insert(tag_condition_info(curr_offset, tag)); diff --git a/042name.cc b/042name.cc index 6b6d2a74..1fc2f201 100644 --- a/042name.cc +++ b/042name.cc @@ -121,7 +121,9 @@ type_ordinal skip_addresses(type_tree* type) { while (type && is_compound_type_starting_with(type, "address")) type = type->right; if (!type) return -1; // error handled elsewhere - return root_type(type)->value; + const type_tree* base_type = type; + // Update base_type in skip_addresses + return base_type->value; } int find_element_name(const type_ordinal t, const string& name, const string& recipe_name) { diff --git a/055shape_shifting_container.cc b/055shape_shifting_container.cc index 061cd0ef..dec225dc 100644 --- a/055shape_shifting_container.cc +++ b/055shape_shifting_container.cc @@ -4,21 +4,39 @@ //: atomic types :(before "End is_mu_container(type) Special-cases") if (!type->atom) - return is_mu_container(root_type(type)); + return is_mu_container(get_base_type(type)); :(before "End is_mu_exclusive_container(type) Special-cases") if (!type->atom) - return is_mu_exclusive_container(root_type(type)); -// a few calls to root_type() without the assertion (for better error handling) + return is_mu_exclusive_container(get_base_type(type)); :(after "Update GET base_type in Check") -if (!base_type->atom) base_type = base_type->left; +base_type = get_base_type(base_type); :(after "Update GET base_type in Run") -if (!base_type->atom) base_type = base_type->left; +base_type = get_base_type(base_type); :(after "Update PUT base_type in Check") -if (!base_type->atom) base_type = base_type->left; +base_type = get_base_type(base_type); :(after "Update PUT base_type in Run") -if (!base_type->atom) base_type = base_type->left; +base_type = get_base_type(base_type); :(after "Update MAYBE_CONVERT base_type in Check") -if (!base_type->atom) base_type = base_type->left; +base_type = get_base_type(base_type); +:(after "Update base_type in size_of(type)") +base_type = get_base_type(base_type); +:(after "Update base_type in element_type") +base_type = get_base_type(base_type); +:(after "Update base_type in compute_container_address_offsets") +base_type = get_base_type(base_type); +:(after "Update base_type in append_container_address_offsets") +base_type = get_base_type(base_type); +:(after "Update element_base_type For Exclusive Container in append_addresses") +element_base_type = get_base_type(element_base_type); +:(after "Update base_type in skip_addresses") +base_type = get_base_type(base_type); +:(replace{} "const type_tree* get_base_type(const type_tree* t)") +const type_tree* get_base_type(const type_tree* t) { + const type_tree* result = t->atom ? t : t->left; + if (!result->atom) + raise << "invalid type " << to_string(t) << '\n' << end(); + return result; +} :(scenario ill_formed_container) % Hide_errors = true; @@ -498,7 +516,7 @@ def main [ //: that we need to teach about type ingredients. :(before "End compute_container_sizes Non-atom Special-cases") -const type_tree* root = root_type(type); +const type_tree* root = get_base_type(type); type_info& info = get(Type, root->value); if (info.kind == CONTAINER) { compute_container_sizes(info, type, pending_metadata, location_for_error_messages); @@ -558,7 +576,7 @@ void test_container_sizes_recursive_shape_shifting_container() { } :(before "End compute_container_address_offsets Non-atom Special-cases") -const type_tree* root = root_type(type); +const type_tree* root = get_base_type(type); type_info& info = get(Type, root->value); if (info.kind == CONTAINER) { compute_container_address_offsets(info, type, location_for_error_messages); diff --git a/069hash.cc b/069hash.cc index ac301b5c..94cfcda9 100644 --- a/069hash.cc +++ b/069hash.cc @@ -89,7 +89,7 @@ size_t hash_mu_array(size_t h, const reagent& r) { } size_t hash_mu_container(size_t h, const reagent& r) { - type_info& info = get(Type, root_type(r.type)->value); + type_info& info = get(Type, get_base_type(r.type)->value); int address = r.value; int offset = 0; for (int i = 0; i < SIZE(info.elements); ++i) { @@ -104,7 +104,7 @@ size_t hash_mu_container(size_t h, const reagent& r) { } size_t hash_mu_exclusive_container(size_t h, const reagent& r) { - const type_tree* type = root_type(r.type); + const type_tree* type = get_base_type(r.type); assert(type->value); int tag = get(Memory, r.value); reagent/*copy*/ variant = variant_type(r, tag); diff --git a/071recipe.cc b/071recipe.cc index 345057d5..6efb023d 100644 --- a/071recipe.cc +++ b/071recipe.cc @@ -205,7 +205,9 @@ recipe from_reagent(const reagent& r) { assert(r.type->name == "recipe"); return result_header; } - assert(root_type(r.type)->name == "recipe"); + const type_tree* root_type = r.type->atom ? r.type : r.type->left; + assert(root_type->atom); + assert(root_type->name == "recipe"); const type_tree* curr = r.type->right; for (/*nada*/; curr && !curr->atom; curr = curr->right) { if (curr->left->atom && curr->left->name == "->") { diff --git a/073wait.cc b/073wait.cc index a243982b..917a7a03 100644 --- a/073wait.cc +++ b/073wait.cc @@ -205,9 +205,9 @@ case GET_LOCATION: { raise << maybe(current_recipe_name()) << "tried to access location 0 in '" << to_original_string(current_instruction()) << "'\n" << end(); break; } - const type_tree* base_root_type = root_type(base.type); + const type_tree* base_type = get_base_type(base.type); int offset = ingredients.at(1).at(0); - if (offset < 0 || offset >= SIZE(get(Type, base_root_type->value).elements)) break; // copied from Check above + if (offset < 0 || offset >= SIZE(get(Type, base_type->value).elements)) break; // copied from Check above int result = base_address; for (int i = 0; i < offset; ++i) result += size_of(element_type(base.type, i)); |