2790
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:
parent
d15c554a51
commit
1d1faace5d
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user