The issue alluded to in the previous 2789 is now fixed. I'm not happy
with my solution, though. I pollute Type_ordinal with type ingredients
in parse_type_tree and simply ignore such entries later on. I'd much
rather avoid the pollution in the first place, but I'm not sure how to
do that..
This commit is contained in:
Kartik K. Agaram 2016-03-19 00:24:52 -07:00
parent d15c554a51
commit 1d1faace5d
4 changed files with 34 additions and 12 deletions

View File

@ -433,6 +433,7 @@ void insert_container(const string& command, kind_of_type kind, istream& in) {
void replace_unknown_types_with_unique_ordinals(type_tree* type, const type_info& info) {
if (!type) return;
// End insert_container Special-cases
if (!type->name.empty()) {
if (contains_key(Type_ordinal, type->name)) {
type->value = get(Type_ordinal, type->name);
@ -440,12 +441,12 @@ void replace_unknown_types_with_unique_ordinals(type_tree* type, const type_info
else if (is_integer(type->name)) { // sometimes types will contain non-type tags, like numbers for the size of an array
type->value = 0;
}
// End insert_container Special-cases
else if (type->name != "->") { // used in recipe types
put(Type_ordinal, type->name, Next_type_ordinal++);
type->value = get(Type_ordinal, type->name);
}
}
recurse:
replace_unknown_types_with_unique_ordinals(type->left, info);
replace_unknown_types_with_unique_ordinals(type->right, info);
}

View File

@ -94,8 +94,9 @@ void read_type_ingredients(string& name) {
:(before "End insert_container Special-cases")
// check for use of type ingredients
else if (is_type_ingredient_name(type->name)) {
else if (!type->name.empty() && is_type_ingredient_name(type->name)) {
type->value = get(info.type_ingredient_names, type->name);
goto recurse;
}
:(code)
bool is_type_ingredient_name(const string& type) {
@ -239,6 +240,7 @@ bool contains_type_ingredient(const reagent& x) {
bool contains_type_ingredient(const type_tree* type) {
if (!type) return false;
if (type->value >= START_TYPE_INGREDIENTS) return true;
assert(!is_type_ingredient_name(type->name));
return contains_type_ingredient(type->left) || contains_type_ingredient(type->right);
}

View File

@ -660,6 +660,35 @@ container foo:_t [
+mem: storing 0 in location 12
+mem: storing 0 in location 13
:(code)
// this one needs a little more fine-grained control
void test_shape_shifting_new_ingredient_does_not_pollute_global_namespace() {
Trace_file = "shape_shifting_new_ingredient_does_not_pollute_global_namespace";
// if you specialize a shape-shifting recipe that allocates a type-ingredient..
transform("def barz x:_elem [\n"
" local-scope\n"
" load-ingredients\n"
" y:address:shared:number <- new _elem:type\n"
"]\n"
"def fooz [\n"
" local-scope\n"
" barz 34\n"
"]\n");
// ..and if you then try to load a new shape-shifting container with that
// type-ingredient
run("container foo:_elem [\n"
" x:_elem\n"
" y:number\n"
"]\n");
// then it should work as usual
reagent callsite("x:foo:point");
reagent element = element_type(callsite, 0);
CHECK_EQ(element.name, "x");
CHECK_EQ(element.type->name, "point");
CHECK(!element.type->right);
}
:(scenario shape_shifting_recipe_supports_compound_types)
def main [
1:address:shared:point <- new point:type

10
z.mu
View File

@ -1,10 +0,0 @@
def barz x:_elem [
local-scope
load-ingredients
y:address:shared:number <- new _elem:type
]
def fooz [
local-scope
barz 34
]