about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-11-06 14:15:37 -0800
committerKartik K. Agaram <vc@akkartik.com>2015-11-06 14:21:36 -0800
commitc157066cab02f91b2d5e53dbec09151936538578 (patch)
tree0125f6d42b84f470b79dc64b2b2c61364b2c2f0b
parentf3760b0f2828250b4b5fb1a52601fe6b11ff328f (diff)
downloadmu-c157066cab02f91b2d5e53dbec09151936538578.tar.gz
2380 - done loading mu code
New assertions still failing during tests.

This whole implementation of generic recipes is like an extended spike.
I don't have nearly enough tests. Ideally I'd have confidence in
generics once layer 59 passed its tests.
-rw-r--r--010vm.cc12
-rw-r--r--030container.cc8
-rw-r--r--043new.cc2
-rw-r--r--046closure_name.cc2
-rw-r--r--057static_dispatch.cc14
-rw-r--r--059generic_recipe.cc12
6 files changed, 27 insertions, 23 deletions
diff --git a/010vm.cc b/010vm.cc
index 31749999..b4ba23f1 100644
--- a/010vm.cc
+++ b/010vm.cc
@@ -273,12 +273,8 @@ type_tree* new_type_tree(const string_tree* properties) {
   type_tree* result = new type_tree(0);
   if (!properties->value.empty()) {
     const string& type_name = properties->value;
-    if (!contains_key(Type_ordinal, type_name)
-        // types can contain integers, like for array sizes
-        && !is_integer(type_name)) {
-      put(Type_ordinal, type_name, Next_type_ordinal++);
-    }
-    result->value = get(Type_ordinal, type_name);
+    if (contains_key(Type_ordinal, type_name))
+      result->value = get(Type_ordinal, type_name);
   }
   result->left = new_type_tree(properties->left);
   result->right = new_type_tree(properties->right);
@@ -412,11 +408,11 @@ void dump_types_tree(const type_tree* type, ostream& out) {
   out << ">";
 }
 
-void dump_type_name(recipe_ordinal type, ostream& out) {
+void dump_type_name(type_ordinal type, ostream& out) {
   if (contains_key(Type, type))
     out << get(Type, type).name;
   else
-    out << "?";
+    out << "?" << type;
 }
 
 string instruction::to_string() const {
diff --git a/030container.cc b/030container.cc
index 4ad2ee36..ae6f590c 100644
--- a/030container.cc
+++ b/030container.cc
@@ -149,14 +149,14 @@ case GET: {
   else
     offset_value = offset.value;
   if (offset_value < 0 || offset_value >= SIZE(get(Type, base_type).elements)) {
-    raise_error << maybe(get(Recipe, r).name) << "invalid offset " << offset_value << " for " << Type[base_type].name << '\n' << end();
+    raise_error << maybe(get(Recipe, r).name) << "invalid offset " << offset_value << " for " << get(Type, base_type).name << '\n' << end();
     break;
   }
   reagent product = inst.products.at(0);
   // Update GET product in Check
   const reagent element = element_type(base, offset_value);
   if (!types_match(product, element)) {
-    raise_error << maybe(get(Recipe, r).name) << "'get' " << offset.original_string << " (" << offset_value << ") on " << Type[base_type].name << " can't be saved in " << product.original_string << "; type should be " << dump_types(element) << '\n' << end();
+    raise_error << maybe(get(Recipe, r).name) << "'get' " << offset.original_string << " (" << offset_value << ") on " << get(Type, base_type).name << " can't be saved in " << product.original_string << "; type should be " << dump_types(element) << '\n' << end();
     break;
   }
   break;
@@ -274,7 +274,7 @@ case GET_ADDRESS: {
   if (is_integer(offset.name)) {  // later layers permit non-integer offsets
     offset_value = to_integer(offset.name);
     if (offset_value < 0 || offset_value >= SIZE(get(Type, base_type).elements)) {
-      raise_error << maybe(get(Recipe, r).name) << "invalid offset " << offset_value << " for " << Type[base_type].name << '\n' << end();
+      raise_error << maybe(get(Recipe, r).name) << "invalid offset " << offset_value << " for " << get(Type, base_type).name << '\n' << end();
       break;
     }
   }
@@ -288,7 +288,7 @@ case GET_ADDRESS: {
   // ..except for an address at the start
   element.type = new type_tree(get(Type_ordinal, "address"), element.type);
   if (!types_match(product, element)) {
-    raise_error << maybe(get(Recipe, r).name) << "'get-address' " << offset.original_string << " (" << offset_value << ") on " << Type[base_type].name << " can't be saved in " << product.original_string << "; type should be " << dump_types(element) << '\n' << end();
+    raise_error << maybe(get(Recipe, r).name) << "'get-address' " << offset.original_string << " (" << offset_value << ") on " << get(Type, base_type).name << " can't be saved in " << product.original_string << "; type should be " << dump_types(element) << '\n' << end();
     break;
   }
   break;
diff --git a/043new.cc b/043new.cc
index 752ee323..f951bb95 100644
--- a/043new.cc
+++ b/043new.cc
@@ -53,7 +53,7 @@ case NEW: {
 Transform.push_back(transform_new_to_allocate);
 
 :(code)
-void transform_new_to_allocate(recipe_ordinal r) {
+void transform_new_to_allocate(const recipe_ordinal r) {
   trace(9991, "transform") << "--- convert 'new' to 'allocate' for recipe " << get(Recipe, r).name << end();
   for (long long int i = 0; i < SIZE(get(Recipe, r).steps); ++i) {
     instruction& inst = get(Recipe, r).steps.at(i);
diff --git a/046closure_name.cc b/046closure_name.cc
index 3d8e2e00..75803f2d 100644
--- a/046closure_name.cc
+++ b/046closure_name.cc
@@ -67,7 +67,7 @@ void collect_surrounding_spaces(const recipe_ordinal r) {
       const string& surrounding_recipe_name = s->value;
       if (contains_key(Surrounding_space, r)
           && Surrounding_space[r] != get(Recipe_ordinal, surrounding_recipe_name)) {
-        raise_error << "recipe " << get(Recipe, r).name << " can have only one 'surrounding' recipe but has " << Recipe[Surrounding_space[r]].name << " and " << surrounding_recipe_name << '\n' << end();
+        raise_error << "recipe " << get(Recipe, r).name << " can have only one 'surrounding' recipe but has " << get(Recipe, Surrounding_space[r]).name << " and " << surrounding_recipe_name << '\n' << end();
         continue;
       }
       trace(9993, "name") << "lexically surrounding space for recipe " << get(Recipe, r).name << " comes from " << surrounding_recipe_name << end();
diff --git a/057static_dispatch.cc b/057static_dispatch.cc
index 597ef4d0..69e6bdb5 100644
--- a/057static_dispatch.cc
+++ b/057static_dispatch.cc
@@ -29,24 +29,24 @@ for (map<string, vector<recipe_ordinal> >::iterator p = Recipe_variants.begin();
 
 :(before "End Load Recipe Header(result)")
 if (contains_key(Recipe_ordinal, result.name)) {
-  if ((Recipe.find(get(Recipe_ordinal, result.name)) == Recipe.end()
-          || get(Recipe, get(Recipe_ordinal, result.name)).has_header)
+  const recipe_ordinal r = get(Recipe_ordinal, result.name);
+  if ((!contains_key(Recipe, r) || get(Recipe, r).has_header)
       && !header_already_exists(result)) {
     string new_name = next_unused_recipe_name(result.name);
     put(Recipe_ordinal, new_name, Next_recipe_ordinal++);
-    Recipe_variants[result.name].push_back(get(Recipe_ordinal, new_name));
+    get(Recipe_variants, result.name).push_back(get(Recipe_ordinal, new_name));
     result.name = new_name;
   }
 }
 else {
   // save first variant
   put(Recipe_ordinal, result.name, Next_recipe_ordinal++);
-  Recipe_variants[result.name].push_back(get(Recipe_ordinal, result.name));
+  get_or_insert(Recipe_variants, result.name).push_back(get(Recipe_ordinal, result.name));
 }
 
 :(code)
 bool header_already_exists(const recipe& rr) {
-  const vector<recipe_ordinal>& variants = Recipe_variants[rr.name];
+  const vector<recipe_ordinal>& variants = get(Recipe_variants, rr.name);
   for (long long int i = 0; i < SIZE(variants); ++i) {
     if (Recipe.find(variants.at(i)) != Recipe.end()
         && all_reagents_match(rr, get(Recipe, variants.at(i)))) {
@@ -114,14 +114,14 @@ void resolve_ambiguous_calls(recipe_ordinal r) {
     instruction& inst = get(Recipe, r).steps.at(index);
     if (inst.is_label) continue;
     if (!contains_key(Recipe_variants, inst.name)) continue;
-    assert(!Recipe_variants[inst.name].empty());
+    assert(!get(Recipe_variants, inst.name).empty());
     replace_best_variant(inst);
   }
 }
 
 void replace_best_variant(instruction& inst) {
   trace(9992, "transform") << "instruction " << inst.name << end();
-  vector<recipe_ordinal>& variants = Recipe_variants[inst.name];
+  vector<recipe_ordinal>& variants = get(Recipe_variants, inst.name);
   long long int best_score = variant_score(inst, get(Recipe_ordinal, inst.name));
   for (long long int i = 0; i < SIZE(variants); ++i) {
     long long int current_score = variant_score(inst, variants.at(i));
diff --git a/059generic_recipe.cc b/059generic_recipe.cc
index 29850848..c3dfa486 100644
--- a/059generic_recipe.cc
+++ b/059generic_recipe.cc
@@ -20,11 +20,19 @@ recipe foo a:_t -> result:_t [
 +mem: storing 14 in location 11
 +mem: storing 15 in location 12
 
-//: Suppress unknown type checks in generic recipes. Their specializations
-//: will be checked.
+//: 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)")
   if (any_type_ingredient_in_header(r)) return;
+:(after "void check_header_products(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)")
+  if (any_type_ingredient_in_header(r)) return;
 
 :(before "End Instruction Dispatch(inst, best_score)")
 if (best_score == -1) {