about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--010vm.cc5
-rw-r--r--012transform.cc1
-rw-r--r--013update_operation.cc1
-rw-r--r--021check_instruction.cc1
-rw-r--r--030container.cc53
-rw-r--r--040brace.cc1
-rw-r--r--042name.cc1
-rw-r--r--043new.cc1
-rw-r--r--046closure_name.cc6
-rw-r--r--048check_type_by_name.cc1
-rw-r--r--056recipe_header.cc2
-rw-r--r--057static_dispatch.cc1
-rw-r--r--059generic_recipe.cc7
13 files changed, 68 insertions, 13 deletions
diff --git a/010vm.cc b/010vm.cc
index cf46bc65..a4c5eb54 100644
--- a/010vm.cc
+++ b/010vm.cc
@@ -269,14 +269,17 @@ string_tree* parse_property_list(istream& in) {
 }
 
 type_tree* new_type_tree(const string_tree* properties) {
+//?   dump_property(properties, cerr);  cerr << '\n';
   if (!properties) return NULL;
   type_tree* result = new type_tree(0);
   if (!properties->value.empty()) {
     const string& type_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
+      result->value = 0;
     else
-      result->value = -1;
+      result->value = -1;  // should never happen; will trigger errors later
   }
   result->left = new_type_tree(properties->left);
   result->right = new_type_tree(properties->right);
diff --git a/012transform.cc b/012transform.cc
index 1dedc93c..b5266ed6 100644
--- a/012transform.cc
+++ b/012transform.cc
@@ -48,6 +48,7 @@ void transform_all() {
 
 void parse_int_reagents() {
   trace(9991, "transform") << "--- parsing any uninitialized reagents as integers" << end();
+//?   cerr << "--- parsing any uninitialized reagents as integers" << '\n';
   for (map<recipe_ordinal, recipe>::iterator p = Recipe.begin(); p != Recipe.end(); ++p) {
     recipe& r = p->second;
     if (r.steps.empty()) continue;
diff --git a/013update_operation.cc b/013update_operation.cc
index a8feb065..2139d82a 100644
--- a/013update_operation.cc
+++ b/013update_operation.cc
@@ -7,6 +7,7 @@ Transform.push_back(update_instruction_operations);
 :(code)
 void update_instruction_operations(recipe_ordinal r) {
   trace(9991, "transform") << "--- compute instruction operations for recipe " << get(Recipe, r).name << end();
+//?   cerr << "--- compute instruction operations for recipe " << get(Recipe, r).name << '\n';
   for (long long int index = 0; index < SIZE(get(Recipe, r).steps); ++index) {
     instruction& inst = get(Recipe, r).steps.at(index);
     if (inst.is_label) continue;
diff --git a/021check_instruction.cc b/021check_instruction.cc
index 3c44f36a..723ada71 100644
--- a/021check_instruction.cc
+++ b/021check_instruction.cc
@@ -14,6 +14,7 @@ Transform.push_back(check_instruction);
 :(code)
 void check_instruction(const recipe_ordinal r) {
   trace(9991, "transform") << "--- perform checks for recipe " << get(Recipe, r).name << end();
+//?   cerr << "--- perform checks for recipe " << get(Recipe, r).name << '\n';
   map<string, vector<type_ordinal> > metadata;
   for (long long int i = 0; i < SIZE(get(Recipe, r).steps); ++i) {
     instruction& inst = get(Recipe, r).steps.at(i);
diff --git a/030container.cc b/030container.cc
index 5c19c4c8..6a063658 100644
--- a/030container.cc
+++ b/030container.cc
@@ -517,32 +517,39 @@ container bar [
 $error: 0
 
 :(after "Begin Transforms")
-Transform.push_back(check_invalid_types);
+Transform.push_back(check_or_set_invalid_types);
 
 :(code)
-void check_invalid_types(const recipe_ordinal r) {
+void check_or_set_invalid_types(const recipe_ordinal r) {
   for (long long int index = 0; index < SIZE(get(Recipe, r).steps); ++index) {
     const instruction& inst = get(Recipe, r).steps.at(index);
     for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
-      check_invalid_types(inst.ingredients.at(i).type, maybe(get(Recipe, r).name), "'"+inst.to_string()+"'");
+      check_or_set_invalid_types(inst.ingredients.at(i).type, inst.ingredients.at(i).properties.at(0).second,
+                          maybe(get(Recipe, r).name), "'"+inst.to_string()+"'");
     }
     for (long long int i = 0; i < SIZE(inst.products); ++i) {
-      check_invalid_types(inst.products.at(i).type, maybe(get(Recipe, r).name), "'"+inst.to_string()+"'");
+      check_or_set_invalid_types(inst.products.at(i).type, inst.products.at(i).properties.at(0).second,
+                          maybe(get(Recipe, r).name), "'"+inst.to_string()+"'");
     }
   }
 }
 
-void check_invalid_types(const type_tree* type, const string& block, const string& name) {
+void check_or_set_invalid_types(type_tree* type, const string_tree* type_name, const string& block, const string& name) {
   if (!type) return;  // will throw a more precise error elsewhere
+//?   cerr << "checking ";  dump_types(type, cerr);  cerr << '\n';
   // End Container Type Checks
   if (type->value == 0) {
     assert(!type->left && !type->right);
     return;
   }
-  if (!contains_key(Type, type->value))
-    raise_error << block << "unknown type in " << name << '\n' << end();
-  check_invalid_types(type->left, block, name);
-  check_invalid_types(type->right, block, name);
+  if (!contains_key(Type, type->value)) {
+    if (type_name && contains_key(Type_ordinal, type_name->value))
+      type->value = get(Type_ordinal, type_name->value);
+    else
+      raise_error << block << "unknown type in " << name << '\n' << end();
+  }
+  check_or_set_invalid_types(type->left, type_name ? type_name->left : NULL, block, name);
+  check_or_set_invalid_types(type->right, type_name ? type_name->right : NULL, block, name);
 }
 
 :(scenario container_unknown_field)
@@ -579,6 +586,34 @@ void check_container_field_types() {
   }
 }
 
+void check_invalid_types(const recipe_ordinal r) {
+  for (long long int index = 0; index < SIZE(get(Recipe, r).steps); ++index) {
+    const instruction& inst = get(Recipe, r).steps.at(index);
+    for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
+      check_invalid_types(inst.ingredients.at(i).type,
+                          maybe(get(Recipe, r).name), "'"+inst.to_string()+"'");
+    }
+    for (long long int i = 0; i < SIZE(inst.products); ++i) {
+      check_invalid_types(inst.products.at(i).type,
+                          maybe(get(Recipe, r).name), "'"+inst.to_string()+"'");
+    }
+  }
+}
+
+void check_invalid_types(type_tree* type, const string& block, const string& name) {
+  if (!type) return;  // will throw a more precise error elsewhere
+//?   cerr << "checking ";  dump_types(type, cerr);  cerr << '\n';
+  // End Container Type Checks
+  if (type->value == 0) {
+    assert(!type->left && !type->right);
+    return;
+  }
+  if (!contains_key(Type, type->value))
+    raise_error << block << "unknown type in " << name << '\n' << end();
+  check_invalid_types(type->left, block, name);
+  check_invalid_types(type->right, block, name);
+}
+
 //:: Construct types out of their constituent fields. Doesn't currently do
 //:: type-checking but *does* match sizes.
 :(before "End Primitive Recipe Declarations")
diff --git a/040brace.cc b/040brace.cc
index 670949d2..47adbedf 100644
--- a/040brace.cc
+++ b/040brace.cc
@@ -40,6 +40,7 @@ void transform_braces(const recipe_ordinal r) {
   // use signed integer for step index because we'll be doing arithmetic on it
   list<pair<int/*OPEN/CLOSE*/, /*step*/long long int> > braces;
   trace(9991, "transform") << "--- transform braces for recipe " << get(Recipe, r).name << end();
+//?   cerr << "--- transform braces for recipe " << get(Recipe, r).name << '\n';
   for (long long int index = 0; index < SIZE(get(Recipe, r).steps); ++index) {
     const instruction& inst = get(Recipe, r).steps.at(index);
     if (inst.label == "{") {
diff --git a/042name.cc b/042name.cc
index d38bda4c..9177a33d 100644
--- a/042name.cc
+++ b/042name.cc
@@ -31,6 +31,7 @@ for (long long int i = 0; i < SIZE(recently_added_recipes); ++i) {
 :(code)
 void transform_names(const recipe_ordinal r) {
   trace(9991, "transform") << "--- transform names for recipe " << get(Recipe, r).name << end();
+//?   cerr << "--- transform names for recipe " << get(Recipe, r).name << '\n';
   bool names_used = false;
   bool numeric_locations_used = false;
   map<string, long long int>& names = Name[r];
diff --git a/043new.cc b/043new.cc
index f951bb95..233b49b5 100644
--- a/043new.cc
+++ b/043new.cc
@@ -55,6 +55,7 @@ Transform.push_back(transform_new_to_allocate);
 :(code)
 void transform_new_to_allocate(const recipe_ordinal r) {
   trace(9991, "transform") << "--- convert 'new' to 'allocate' for recipe " << get(Recipe, r).name << end();
+//?   cerr << "--- convert 'new' to 'allocate' for recipe " << get(Recipe, r).name << '\n';
   for (long long int i = 0; i < SIZE(get(Recipe, r).steps); ++i) {
     instruction& inst = get(Recipe, r).steps.at(i);
     // Convert 'new' To 'allocate'
diff --git a/046closure_name.cc b/046closure_name.cc
index 75803f2d..11945c76 100644
--- a/046closure_name.cc
+++ b/046closure_name.cc
@@ -41,6 +41,7 @@ Transform.push_back(collect_surrounding_spaces);
 :(code)
 void collect_surrounding_spaces(const recipe_ordinal r) {
   trace(9991, "transform") << "--- collect surrounding spaces for recipe " << get(Recipe, r).name << end();
+//?   cerr << "--- collect surrounding spaces for recipe " << get(Recipe, r).name << '\n';
   for (long long int i = 0; i < SIZE(get(Recipe, r).steps); ++i) {
     const instruction& inst = get(Recipe, r).steps.at(i);
     if (inst.is_label) continue;
@@ -71,6 +72,11 @@ void collect_surrounding_spaces(const recipe_ordinal r) {
         continue;
       }
       trace(9993, "name") << "lexically surrounding space for recipe " << get(Recipe, r).name << " comes from " << surrounding_recipe_name << end();
+//?       cerr << "lexically surrounding space for recipe " << get(Recipe, r).name << " comes from " << surrounding_recipe_name << '\n';
+      if (!contains_key(Recipe_ordinal, surrounding_recipe_name)) {
+        raise << "can't find recipe providing surrounding space for " << get(Recipe, r).name << ": " << surrounding_recipe_name << '\n' << end();
+        continue;
+      }
       Surrounding_space[r] = get(Recipe_ordinal, surrounding_recipe_name);
     }
   }
diff --git a/048check_type_by_name.cc b/048check_type_by_name.cc
index 79328427..7bed4b22 100644
--- a/048check_type_by_name.cc
+++ b/048check_type_by_name.cc
@@ -20,6 +20,7 @@ Transform.push_back(check_types_by_name);
 :(code)
 void check_types_by_name(const recipe_ordinal r) {
   trace(9991, "transform") << "--- deduce types for recipe " << get(Recipe, r).name << end();
+//?   cerr << "--- deduce types for recipe " << get(Recipe, r).name << '\n';
   map<string, type_tree*> type;
   map<string, string_tree*> type_name;
   for (long long int i = 0; i < SIZE(get(Recipe, r).steps); ++i) {
diff --git a/056recipe_header.cc b/056recipe_header.cc
index cb63b013..33ccc44f 100644
--- a/056recipe_header.cc
+++ b/056recipe_header.cc
@@ -109,6 +109,7 @@ void check_header_products(const recipe_ordinal r) {
   const recipe& rr = get(Recipe, r);
   if (rr.products.empty()) return;
   trace(9991, "transform") << "--- checking reply instructions against header for " << rr.name << end();
+//?   cerr << "--- checking reply instructions against header for " << rr.name << '\n';
   for (long long int i = 0; i < SIZE(rr.steps); ++i) {
     const instruction& inst = rr.steps.at(i);
     if (inst.name != "reply") continue;
@@ -146,6 +147,7 @@ void deduce_types_from_header(const recipe_ordinal r) {
   recipe& rr = get(Recipe, r);
   if (rr.products.empty()) return;
   trace(9991, "transform") << "--- deduce types from header for " << rr.name << end();
+//?   cerr << "--- deduce types from header for " << rr.name << '\n';
   map<string, const type_tree*> header;
   for (long long int i = 0; i < SIZE(rr.ingredients); ++i) {
     header[rr.ingredients.at(i).name] = rr.ingredients.at(i).type;
diff --git a/057static_dispatch.cc b/057static_dispatch.cc
index 69e6bdb5..c2184c93 100644
--- a/057static_dispatch.cc
+++ b/057static_dispatch.cc
@@ -110,6 +110,7 @@ Transform.push_back(resolve_ambiguous_calls);
 void resolve_ambiguous_calls(recipe_ordinal r) {
   if (!get(Recipe, r).has_header) return;
   trace(9991, "transform") << "--- resolve ambiguous calls for recipe " << get(Recipe, r).name << end();
+//?   cerr << "--- resolve ambiguous calls for recipe " << get(Recipe, r).name << '\n';
   for (long long int index = 0; index < SIZE(get(Recipe, r).steps); ++index) {
     instruction& inst = get(Recipe, r).steps.at(index);
     if (inst.is_label) continue;
diff --git a/059generic_recipe.cc b/059generic_recipe.cc
index c3dfa486..e435f3f3 100644
--- a/059generic_recipe.cc
+++ b/059generic_recipe.cc
@@ -23,15 +23,15 @@ recipe foo a:_t -> result:_t [
 //: Before anything else, disable all previous transforms which rely on
 //: reagent.type if a recipe contains any type ingredients.
 
-:(after "void check_invalid_types(const recipe_ordinal r)")
+:(after "void check_instruction(const recipe_ordinal r)")
   if (any_type_ingredient_in_header(r)) return;
-:(after "void check_header_products(const recipe_ordinal r)")
+:(after "void check_or_set_invalid_types(const recipe_ordinal r)")
   if (any_type_ingredient_in_header(r)) return;
 :(after "void transform_names(const recipe_ordinal r)")
   if (any_type_ingredient_in_header(r)) return;
 :(after "void transform_new_to_allocate(const recipe_ordinal r)")
   if (any_type_ingredient_in_header(r)) return;
-:(after "void check_instruction(const recipe_ordinal r)")
+:(after "void check_header_products(const recipe_ordinal r)")
   if (any_type_ingredient_in_header(r)) return;
 
 :(before "End Instruction Dispatch(inst, best_score)")
@@ -43,6 +43,7 @@ if (best_score == -1) {
     variants.push_back(new_variant(exemplar, inst));
     inst.name = get(Recipe, variants.back()).name;
     trace(9992, "transform") << "new specialization: " << inst.name << end();
+//?     cerr << "new specialization: " << inst.name << '\n';
   }
 }