Start using type names from the type tree rather than the property tree
in most places. Hopefully the only occurrences of
'properties.at(0).second' left are ones where we're managing it. Next we
can stop writing to it.
This commit is contained in:
Kartik K. Agaram 2016-02-20 20:05:52 -08:00
parent 343bc5359b
commit 65c905fe84
11 changed files with 92 additions and 90 deletions

View File

@ -269,7 +269,7 @@ type_tree* new_type_tree(const string_tree* properties) {
if (!properties) return NULL;
type_tree* result = new type_tree("", 0);
if (!properties->value.empty()) {
const string& type_name = properties->value;
const string& type_name = result->name = properties->value;
if (contains_key(Type_ordinal, type_name))
result->value = get(Type_ordinal, type_name);
else if (is_integer(type_name)) // sometimes types will contain non-type tags, like numbers for the size of an array
@ -298,6 +298,7 @@ reagent::reagent(const reagent& old) {
}
type_tree::type_tree(const type_tree& old) {
name = old.name;
value = old.value;
left = old.left ? new type_tree(*old.left) : NULL;
right = old.right ? new type_tree(*old.right) : NULL;

View File

@ -124,7 +124,7 @@ if (s.at(0) == '[') {
:(code)
bool is_literal_string(const reagent& x) {
return x.properties.at(0).second && x.properties.at(0).second->value == "literal-string";
return x.type && x.type->name == "literal-string";
}
string emit_literal_string(string name) {

View File

@ -181,8 +181,8 @@ bool is_mu_number(reagent r) {
if (!r.type) return false;
if (is_literal(r)) {
if (!r.properties.at(0).second) return false;
return r.properties.at(0).second->value == "literal-number"
|| r.properties.at(0).second->value == "literal";
return r.type->name == "literal-number"
|| r.type->name == "literal";
}
if (r.type->value == get(Type_ordinal, "character")) return true; // permit arithmetic on unicode code points
return r.type->value == get(Type_ordinal, "number");
@ -191,7 +191,7 @@ bool is_mu_number(reagent r) {
bool is_mu_scalar(reagent r) {
if (!r.type) return false;
if (is_literal(r))
return !r.properties.at(0).second || r.properties.at(0).second->value != "literal-string";
return !r.properties.at(0).second || r.type->name != "literal-string";
if (is_mu_array(r)) return false;
return size_of(r) == 1;
}

View File

@ -437,7 +437,7 @@ type_tree* new_type_tree_with_new_types_for_unknown(const string_tree* propertie
if (!properties) return NULL;
type_tree* result = new type_tree("", 0);
if (!properties->value.empty()) {
const string& type_name = properties->value;
const string& type_name = result->name = properties->value;
if (contains_key(Type_ordinal, type_name)) {
result->value = get(Type_ordinal, type_name);
}

View File

@ -106,8 +106,8 @@ void drop_from_type(reagent& r, string expected_type) {
raise_error << "can't drop " << expected_type << " from " << to_string(r) << '\n' << end();
return;
}
if (r.properties.at(0).second->value != expected_type) {
raise_error << "can't drop " << expected_type << " from " << to_string(r) << '\n' << end();
if (r.type->name != expected_type) {
raise_error << "can't drop2 " << expected_type << " from " << to_string(r) << '\n' << end();
return;
}
type_tree* tmp = r.type;

View File

@ -34,13 +34,13 @@
type_ordinal shared = put(Type_ordinal, "shared", Next_type_ordinal++);
get_or_insert(Type, shared).name = "shared";
:(before "End Drop Address In lookup_memory(x)")
if (x.properties.at(0).second->value == "shared") {
if (x.type->name == "shared") {
trace(9999, "mem") << "skipping refcount at " << x.value << end();
x.set_value(x.value+1); // skip refcount
drop_from_type(x, "shared");
}
:(before "End Drop Address In canonize_type(r)")
if (r.properties.at(0).second->value == "shared") {
if (r.type->name == "shared") {
drop_from_type(r, "shared");
}
@ -655,5 +655,5 @@ string read_mu_string(long long int address) {
bool is_mu_type_literal(reagent r) {
//? if (!r.properties.empty())
//? dump_property(r.properties.at(0).second, cerr);
return is_literal(r) && !r.properties.empty() && r.properties.at(0).second && r.properties.at(0).second->value == "type";
return is_literal(r) && !r.properties.empty() && r.properties.at(0).second && r.type->name == "type";
}

View File

@ -121,7 +121,7 @@ void append_fragment(vector<instruction>& base, const vector<instruction>& patch
for (long long int j = 0; j < SIZE(inst.ingredients); ++j) {
reagent& x = inst.ingredients.at(j);
if (!is_literal(x)) continue;
if (x.properties.at(0).second->value == "label" && contains_key(jump_targets, x.name))
if (x.type->name == "label" && contains_key(jump_targets, x.name))
x.name = prefix+x.name;
}
base.push_back(inst);

View File

@ -273,10 +273,12 @@ void replace_type_ingredients(type_tree* element_type, string_tree* element_type
// rather than {foo: (number)}
// We'd also like to use it with multiple types: foo:address:number.
replacement = curr;
if (!final_type_ingredient(type_ingredient_index, container_info))
if (!final_type_ingredient(type_ingredient_index, container_info)) {
splice_right = false;
}
}
}
element_type->name = replacement->name;
element_type->value = replacement->value;
assert(!element_type->left); // since value is set
element_type->left = replacement->left ? new type_tree(*replacement->left) : NULL;
@ -346,8 +348,8 @@ void test_replace_type_ingredients_entire() {
reagent callsite("x:foo:point");
reagent element = element_type(callsite, 0);
CHECK_EQ(element.name, "x");
CHECK_EQ(element.properties.at(0).second->value, "point");
CHECK(!element.properties.at(0).second->right);
CHECK_EQ(element.type->name, "point");
CHECK(!element.type->right);
}
void test_replace_type_ingredients_tail() {
@ -360,9 +362,9 @@ void test_replace_type_ingredients_tail() {
reagent callsite("x:bar:point");
reagent element = element_type(callsite, 0);
CHECK_EQ(element.name, "x");
CHECK_EQ(element.properties.at(0).second->value, "foo");
CHECK_EQ(element.properties.at(0).second->right->value, "point");
CHECK(!element.properties.at(0).second->right->right);
CHECK_EQ(element.type->name, "foo");
CHECK_EQ(element.type->right->name, "point");
CHECK(!element.type->right->right);
}
void test_replace_type_ingredients_head_tail_multiple() {
@ -375,12 +377,12 @@ void test_replace_type_ingredients_head_tail_multiple() {
reagent callsite("x:bar:address:shared:array:character");
reagent element = element_type(callsite, 0);
CHECK_EQ(element.name, "x");
CHECK_EQ(element.properties.at(0).second->value, "foo");
CHECK_EQ(element.properties.at(0).second->right->value, "address");
CHECK_EQ(element.properties.at(0).second->right->right->value, "shared");
CHECK_EQ(element.properties.at(0).second->right->right->right->value, "array");
CHECK_EQ(element.properties.at(0).second->right->right->right->right->value, "character");
CHECK(!element.properties.at(0).second->right->right->right->right->right);
CHECK_EQ(element.type->name, "foo");
CHECK_EQ(element.type->right->name, "address");
CHECK_EQ(element.type->right->right->name, "shared");
CHECK_EQ(element.type->right->right->right->name, "array");
CHECK_EQ(element.type->right->right->right->right->name, "character");
CHECK(!element.type->right->right->right->right->right);
}
void test_replace_type_ingredients_head_middle() {
@ -393,13 +395,13 @@ void test_replace_type_ingredients_head_middle() {
reagent callsite("x:bar:address");
reagent element = element_type(callsite, 0);
CHECK_EQ(element.name, "x");
CHECK(element.properties.at(0).second)
CHECK_EQ(element.properties.at(0).second->value, "foo");
CHECK(element.properties.at(0).second->right)
CHECK_EQ(element.properties.at(0).second->right->value, "address");
CHECK(element.properties.at(0).second->right->right)
CHECK_EQ(element.properties.at(0).second->right->right->value, "number");
CHECK(!element.properties.at(0).second->right->right->right);
CHECK(element.type)
CHECK_EQ(element.type->name, "foo");
CHECK(element.type->right)
CHECK_EQ(element.type->right->name, "address");
CHECK(element.type->right->right)
CHECK_EQ(element.type->right->right->name, "number");
CHECK(!element.type->right->right->right);
}
void test_replace_last_type_ingredient_with_multiple() {
@ -410,15 +412,15 @@ void test_replace_last_type_ingredient_with_multiple() {
reagent callsite("{f: (foo number (address shared array character))}");
reagent element1 = element_type(callsite, 0);
CHECK_EQ(element1.name, "x");
CHECK_EQ(element1.properties.at(0).second->value, "number");
CHECK(!element1.properties.at(0).second->right);
CHECK_EQ(element1.type->name, "number");
CHECK(!element1.type->right);
reagent element2 = element_type(callsite, 1);
CHECK_EQ(element2.name, "y");
CHECK_EQ(element2.properties.at(0).second->value, "address");
CHECK_EQ(element2.properties.at(0).second->right->value, "shared");
CHECK_EQ(element2.properties.at(0).second->right->right->value, "array");
CHECK_EQ(element2.properties.at(0).second->right->right->right->value, "character");
CHECK(!element2.properties.at(0).second->right->right->right->right);
CHECK_EQ(element2.type->name, "address");
CHECK_EQ(element2.type->right->name, "shared");
CHECK_EQ(element2.type->right->right->name, "array");
CHECK_EQ(element2.type->right->right->right->name, "character");
CHECK(!element2.type->right->right->right->right);
}
void test_replace_middle_type_ingredient_with_multiple() {
@ -430,19 +432,19 @@ void test_replace_middle_type_ingredient_with_multiple() {
reagent callsite("{f: (foo number (address shared array character) boolean)}");
reagent element1 = element_type(callsite, 0);
CHECK_EQ(element1.name, "x");
CHECK_EQ(element1.properties.at(0).second->value, "number");
CHECK(!element1.properties.at(0).second->right);
CHECK_EQ(element1.type->name, "number");
CHECK(!element1.type->right);
reagent element2 = element_type(callsite, 1);
CHECK_EQ(element2.name, "y");
CHECK_EQ(element2.properties.at(0).second->value, "address");
CHECK_EQ(element2.properties.at(0).second->right->value, "shared");
CHECK_EQ(element2.properties.at(0).second->right->right->value, "array");
CHECK_EQ(element2.properties.at(0).second->right->right->right->value, "character");
CHECK(!element2.properties.at(0).second->right->right->right->right);
CHECK_EQ(element2.type->name, "address");
CHECK_EQ(element2.type->right->name, "shared");
CHECK_EQ(element2.type->right->right->name, "array");
CHECK_EQ(element2.type->right->right->right->name, "character");
CHECK(!element2.type->right->right->right->right);
reagent element3 = element_type(callsite, 2);
CHECK_EQ(element3.name, "z");
CHECK_EQ(element3.properties.at(0).second->value, "boolean");
CHECK(!element3.properties.at(0).second->right);
CHECK_EQ(element3.type->name, "boolean");
CHECK(!element3.type->right);
}
bool has_nth_type(const type_tree* base, long long int n) {

View File

@ -121,14 +121,14 @@ bool all_concrete_header_reagents_strictly_match(const instruction& inst, const
return false;
}
for (long long int i = 0; i < SIZE(variant.ingredients); ++i) {
if (!concrete_types_strictly_match(variant.ingredients.at(i), inst.ingredients.at(i))) {
if (!concrete_type_names_strictly_match(variant.ingredients.at(i), inst.ingredients.at(i))) {
trace(9993, "transform") << "concrete-type match failed: ingredient " << i << end();
return false;
}
}
for (long long int i = 0; i < SIZE(inst.products); ++i) {
if (is_dummy(inst.products.at(i))) continue;
if (!concrete_types_strictly_match(variant.products.at(i), inst.products.at(i))) {
if (!concrete_type_names_strictly_match(variant.products.at(i), inst.products.at(i))) {
trace(9993, "transform") << "strict match failed: product " << i << end();
return false;
}
@ -142,7 +142,7 @@ recipe_ordinal best_shape_shifting_variant(const instruction& inst, vector<recip
// primary score
long long int max_score = -1;
for (long long int i = 0; i < SIZE(candidates); ++i) {
long long int score = number_of_concrete_types(candidates.at(i));
long long int score = number_of_concrete_type_names(candidates.at(i));
assert(score > -1);
if (score > max_score) max_score = score;
}
@ -150,7 +150,7 @@ recipe_ordinal best_shape_shifting_variant(const instruction& inst, vector<recip
long long int min_score2 = 999;
long long int best_index = 0;
for (long long int i = 0; i < SIZE(candidates); ++i) {
long long int score1 = number_of_concrete_types(candidates.at(i));
long long int score1 = number_of_concrete_type_names(candidates.at(i));
assert(score1 <= max_score);
if (score1 != max_score) continue;
const recipe& candidate = get(Recipe, candidates.at(i));
@ -178,63 +178,63 @@ bool any_type_ingredient_in_header(recipe_ordinal variant) {
return false;
}
bool concrete_types_strictly_match(reagent to, reagent from) {
bool concrete_type_names_strictly_match(reagent to, reagent from) {
canonize_type(to);
canonize_type(from);
return concrete_types_strictly_match(to.properties.at(0).second, from.properties.at(0).second, from);
return concrete_type_names_strictly_match(to.type, from.type, from);
}
long long int number_of_concrete_types(recipe_ordinal r) {
long long int number_of_concrete_type_names(recipe_ordinal r) {
const recipe& caller = get(Recipe, r);
long long int result = 0;
for (long long int i = 0; i < SIZE(caller.ingredients); ++i)
result += number_of_concrete_types(caller.ingredients.at(i));
result += number_of_concrete_type_names(caller.ingredients.at(i));
for (long long int i = 0; i < SIZE(caller.products); ++i)
result += number_of_concrete_types(caller.products.at(i));
result += number_of_concrete_type_names(caller.products.at(i));
return result;
}
long long int number_of_concrete_types(const reagent& r) {
return number_of_concrete_types(r.properties.at(0).second);
long long int number_of_concrete_type_names(const reagent& r) {
return number_of_concrete_type_names(r.type);
}
long long int number_of_concrete_types(const string_tree* type) {
long long int number_of_concrete_type_names(const type_tree* type) {
if (!type) return 0;
long long int result = 0;
if (!type->value.empty() && !is_type_ingredient_name(type->value))
if (!type->name.empty() && !is_type_ingredient_name(type->name))
result++;
result += number_of_concrete_types(type->left);
result += number_of_concrete_types(type->right);
result += number_of_concrete_type_names(type->left);
result += number_of_concrete_type_names(type->right);
return result;
}
bool concrete_types_strictly_match(const string_tree* to, const string_tree* from, const reagent& rhs_reagent) {
bool concrete_type_names_strictly_match(const type_tree* to, const type_tree* from, const reagent& rhs_reagent) {
if (!to) return !from;
if (!from) return !to;
if (is_type_ingredient_name(to->value)) return true; // type ingredient matches anything
if (to->value == "literal" && from->value == "literal")
if (is_type_ingredient_name(to->name)) return true; // type ingredient matches anything
if (to->name == "literal" && from->name == "literal")
return true;
if (to->value == "literal"
&& Literal_type_names.find(from->value) != Literal_type_names.end())
if (to->name == "literal"
&& Literal_type_names.find(from->name) != Literal_type_names.end())
return true;
if (from->value == "literal"
&& Literal_type_names.find(to->value) != Literal_type_names.end())
if (from->name == "literal"
&& Literal_type_names.find(to->name) != Literal_type_names.end())
return true;
if (from->value == "literal" && to->value == "address")
if (from->name == "literal" && to->name == "address")
return rhs_reagent.name == "0";
//? cerr << to->value << " vs " << from->value << '\n';
return to->value == from->value
&& concrete_types_strictly_match(to->left, from->left, rhs_reagent)
&& concrete_types_strictly_match(to->right, from->right, rhs_reagent);
//? cerr << to->name << " vs " << from->name << '\n';
return to->name == from->name
&& concrete_type_names_strictly_match(to->left, from->left, rhs_reagent)
&& concrete_type_names_strictly_match(to->right, from->right, rhs_reagent);
}
bool contains_type_ingredient_name(const reagent& x) {
return contains_type_ingredient_name(x.properties.at(0).second);
return contains_type_ingredient_name(x.type);
}
bool contains_type_ingredient_name(const string_tree* type) {
bool contains_type_ingredient_name(const type_tree* type) {
if (!type) return false;
if (is_type_ingredient_name(type->value)) return true;
if (is_type_ingredient_name(type->name)) return true;
return contains_type_ingredient_name(type->left) || contains_type_ingredient_name(type->right);
}
@ -301,7 +301,7 @@ void save_or_deduce_type_name(reagent& x, map<string, string_tree*>& type_name,
return;
}
if (contains_key(type_name, x.name)) return;
if (x.properties.at(0).second->value == "offset" || x.properties.at(0).second->value == "variant") return; // special-case for container-access instructions
if (x.type->name == "offset" || x.type->name == "variant") return; // special-case for container-access instructions
put(type_name, x.name, x.properties.at(0).second);
trace(9993, "transform") << "type of " << x.name << " is " << to_string(x.properties.at(0).second) << end();
}
@ -390,7 +390,7 @@ void replace_type_ingredients(recipe& new_recipe, const map<string, const string
for (long long int j = 0; j < SIZE(inst.products); ++j)
replace_type_ingredients(inst.products.at(j), mappings, new_recipe);
// special-case for new: replace type ingredient in first ingredient *value*
if (inst.name == "new" && inst.ingredients.at(0).properties.at(0).second->value != "literal-string") {
if (inst.name == "new" && inst.ingredients.at(0).type->name != "literal-string") {
string_tree* type_name = parse_string_tree(inst.ingredients.at(0).name);
replace_type_ingredients(type_name, mappings);
inst.ingredients.at(0).name = inspect(type_name);

View File

@ -32,7 +32,7 @@ type_ordinal recipe = put(Type_ordinal, "recipe", Next_type_ordinal++);
get_or_insert(Type, recipe).name = "recipe";
:(before "End Null-type is_disqualified Exceptions")
if (!x.properties.at(0).second && contains_key(Recipe_ordinal, x.name)) {
if (!x.type && contains_key(Recipe_ordinal, x.name)) {
x.properties.at(0).second = new string_tree("recipe-literal");
x.type = new type_tree("recipe-literal", get(Type_ordinal, "recipe-literal"));
x.set_value(get(Recipe_ordinal, x.name));
@ -126,27 +126,26 @@ void check_indirect_calls_against_header(const recipe_ordinal r) {
}
recipe from_reagent(const reagent& r) {
assert(r.properties.at(0).second->value == "recipe");
assert(r.type->name == "recipe");
recipe result_header; // will contain only ingredients and products, nothing else
result_header.has_header = true;
const string_tree* curr = r.properties.at(0).second->right;
const type_tree* curr = r.type->right;
for (; curr; curr=curr->right) {
if (curr->value == "->") {
if (curr->name == "->") {
curr = curr->right; // skip delimiter
break;
}
result_header.ingredients.push_back("recipe:"+curr->value);
}
for (; curr; curr=curr->right) {
result_header.products.push_back("recipe:"+curr->value);
result_header.ingredients.push_back("recipe:"+curr->name);
}
for (; curr; curr=curr->right)
result_header.products.push_back("recipe:"+curr->name);
return result_header;
}
bool is_mu_recipe(reagent r) {
if (!r.type) return false;
if (r.properties.at(0).second->value == "recipe") return true;
if (r.properties.at(0).second->value == "recipe-literal") return true;
if (r.type->name == "recipe") return true;
if (r.type->name == "recipe-literal") return true;
// End is_mu_recipe Cases
return false;
}

View File

@ -58,7 +58,7 @@ size_t hash_mu_address(size_t h, reagent& r) {
if (r.value == 0) return 0;
r.value = get_or_insert(Memory, r.value);
drop_from_type(r, "address");
if (r.properties.at(0).second->value == "shared") {
if (r.type->name == "shared") {
++r.value;
drop_from_type(r, "shared");
}