3654
Follow-up to commit 3321: move get_base_type() more thoroughly to layer 55. The notion of a base_type doesn't really make sense before we introduce type ingredients and shape-shifting containers, and it simplifies early layers a *lot* even including the cost of that *ugly* preamble in layer 55 to retrofit all the places.
This commit is contained in:
parent
4ecab1821e
commit
b55b15a920
|
@ -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);
|
||||
|
|
10
031merge.cc
10
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 [
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 == "->") {
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue