about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-11-04 23:44:46 -0800
committerKartik K. Agaram <vc@akkartik.com>2015-11-04 23:44:46 -0800
commit436b2b2eac33b893f7b9b0a7229ac1d98c034d2c (patch)
tree6619f453b5fd99b204380b17b94e9d8321e642f1
parent54275c64e2404612bf8754238bf71ae805f4022e (diff)
downloadmu-436b2b2eac33b893f7b9b0a7229ac1d98c034d2c.tar.gz
2360
More flailing around trying to come up with the right phase ordering.
I've tried to narrow down each transform's constraints wrt transforms in
previous layers.

One issue that keeps biting me is the Type map containing empty records
because of stray [] operations. That's gotta be important.
-rw-r--r--013update_operation.cc2
-rw-r--r--030container.cc2
-rw-r--r--040brace.cc38
-rw-r--r--041jump_target.cc2
-rw-r--r--043new.cc2
-rw-r--r--046closure_name.cc4
-rw-r--r--048check_type_by_name.cc2
-rw-r--r--052tangle.cc4
-rw-r--r--056recipe_header.cc8
-rw-r--r--058generic_container.cc5
-rw-r--r--059generic_recipe.cc6
11 files changed, 60 insertions, 15 deletions
diff --git a/013update_operation.cc b/013update_operation.cc
index 22a8f538..8ff8d628 100644
--- a/013update_operation.cc
+++ b/013update_operation.cc
@@ -1,7 +1,7 @@
 //: Once all code is loaded, save operation ids of instructions and check that
 //: nothing's undefined.
 
-:(after "Begin Transforms")
+:(before "End Transforms")
 Transform.push_back(update_instruction_operations);
 
 :(code)
diff --git a/030container.cc b/030container.cc
index 05b3a6e9..72acd48d 100644
--- a/030container.cc
+++ b/030container.cc
@@ -190,6 +190,7 @@ case GET: {
 const reagent element_type(const reagent& canonized_base, long long int offset_value) {
   assert(offset_value >= 0);
   assert(Type.find(canonized_base.type->value) != Type.end());
+  assert(!Type[canonized_base.type->value].name.empty());
   const type_info& info = Type[canonized_base.type->value];
   assert(info.kind == CONTAINER);
   reagent element;
@@ -563,6 +564,7 @@ check_container_field_types();
 void check_container_field_types() {
   for (map<type_ordinal, type_info>::iterator p = Type.begin(); p != Type.end(); ++p) {
     const type_info& info = p->second;
+    // Check Container Field Types(info)
     for (long long int i = 0; i < SIZE(info.elements); ++i) {
       check_invalid_types(info.elements.at(i), maybe(info.name), info.element_names.at(i));
     }
diff --git a/040brace.cc b/040brace.cc
index fb6698b5..71324aaa 100644
--- a/040brace.cc
+++ b/040brace.cc
@@ -80,12 +80,18 @@ void transform_braces(const recipe_ordinal r) {
       }
     }
     // update instruction operation
-    if (inst.old_name.find("-if") != string::npos)
+    if (inst.old_name.find("-if") != string::npos) {
       inst.name = "jump-if";
-    else if (inst.old_name.find("-unless") != string::npos)
+      inst.operation = JUMP_IF;
+    }
+    else if (inst.old_name.find("-unless") != string::npos) {
       inst.name = "jump-unless";
-    else
+      inst.operation = JUMP_UNLESS;
+    }
+    else {
       inst.name = "jump";
+      inst.operation = JUMP;
+    }
     // check for explicitly provided targets
     if (inst.old_name.find("-if") != string::npos || inst.old_name.find("-unless") != string::npos) {
       // conditional branches check arg 1
@@ -349,3 +355,29 @@ recipe main [
   }
 ]
 +error: break-if expects 1 or 2 ingredients, but got none
+
+//: Make sure these pseudo recipes get consistent numbers in all tests, even
+//: though they aren't implemented. Allows greater flexibility in ordering
+//: transforms.
+
+:(before "End Primitive Recipe Declarations")
+BREAK,
+BREAK_IF,
+BREAK_UNLESS,
+LOOP,
+LOOP_IF,
+LOOP_UNLESS,
+:(before "End Primitive Recipe Numbers")
+Recipe_ordinal["break"] = BREAK;
+Recipe_ordinal["break-if"] = BREAK_IF;
+Recipe_ordinal["break-unless"] = BREAK_UNLESS;
+Recipe_ordinal["loop"] = LOOP;
+Recipe_ordinal["loop-if"] = LOOP_IF;
+Recipe_ordinal["loop-unless"] = LOOP_UNLESS;
+:(before "End Primitive Recipe Checks")
+case BREAK: break;
+case BREAK_IF: break;
+case BREAK_UNLESS: break;
+case LOOP: break;
+case LOOP_IF: break;
+case LOOP_UNLESS: break;
diff --git a/041jump_target.cc b/041jump_target.cc
index 56a2cbce..d395cd97 100644
--- a/041jump_target.cc
+++ b/041jump_target.cc
@@ -18,7 +18,7 @@ recipe main [
 :(before "End Mu Types Initialization")
 Type_ordinal["label"] = 0;
 
-:(after "Begin Transforms")
+:(before "Transform.push_back(transform_braces)")
 Transform.push_back(transform_labels);
 
 :(code)
diff --git a/043new.cc b/043new.cc
index 13240cfe..a851e3d5 100644
--- a/043new.cc
+++ b/043new.cc
@@ -49,7 +49,7 @@ case NEW: {
 }
 
 //:: translate 'new' to 'allocate' instructions that take a size instead of a type
-:(after "Transform.push_back(check_instruction)" following "Transform.push_back(check_invalid_types)")  // so that all types are defined
+:(after "Transform.push_back(check_instruction)")  // check_instruction will guard against direct 'allocate' instructions below
 Transform.push_back(transform_new_to_allocate);
 
 :(code)
diff --git a/046closure_name.cc b/046closure_name.cc
index d6197fce..56b3227a 100644
--- a/046closure_name.cc
+++ b/046closure_name.cc
@@ -30,12 +30,12 @@ recipe increment-counter [
 +mem: storing 5 in location 3
 
 //: To make this work, compute the recipe that provides names for the
-//: surrounding space of each recipe. This must happen before transform_names.
+//: surrounding space of each recipe.
 
 :(before "End Globals")
 map<recipe_ordinal, recipe_ordinal> Surrounding_space;
 
-:(after "Begin Transforms")
+:(before "Transform.push_back(transform_names)")
 Transform.push_back(collect_surrounding_spaces);
 
 :(code)
diff --git a/048check_type_by_name.cc b/048check_type_by_name.cc
index fb193d78..938cacd5 100644
--- a/048check_type_by_name.cc
+++ b/048check_type_by_name.cc
@@ -14,7 +14,7 @@ recipe main [
 ]
 +error: main: x used with multiple types
 
-:(after "Begin Transforms")
+:(before "Transform.push_back(transform_names)")
 Transform.push_back(check_types_by_name);
 
 :(code)
diff --git a/052tangle.cc b/052tangle.cc
index 618dd981..0582f79f 100644
--- a/052tangle.cc
+++ b/052tangle.cc
@@ -135,8 +135,8 @@ bool is_waypoint(string label) {
 //: complain about unapplied fragments
 :(before "End Globals")
 bool Transform_check_insert_fragments_Ran = false;
-:(before "End Transforms")
-Transform.push_back(check_insert_fragments);  // final transform
+:(after "Transform.push_back(insert_fragments)")
+Transform.push_back(check_insert_fragments);
 :(code)
 void check_insert_fragments(unused recipe_ordinal) {
   if (Transform_check_insert_fragments_Ran) return;
diff --git a/056recipe_header.cc b/056recipe_header.cc
index a0a88640..0ad3794c 100644
--- a/056recipe_header.cc
+++ b/056recipe_header.cc
@@ -101,7 +101,7 @@ recipe add2 x:number, y:number -> z:number [
 ]
 +error: add2: replied with the wrong type at 'reply z'
 
-:(before "End Transforms")
+:(after "Transform.push_back(check_types_by_name)")
 Transform.push_back(check_header_products);
 
 :(code)
@@ -111,7 +111,7 @@ void check_header_products(const recipe_ordinal r) {
   trace(9991, "transform") << "--- checking reply instructions against header for " << rr.name << end();
   for (long long int i = 0; i < SIZE(rr.steps); ++i) {
     const instruction& inst = rr.steps.at(i);
-    if (inst.operation != REPLY) continue;
+    if (inst.name != "reply") continue;
     if (SIZE(rr.products) != SIZE(inst.ingredients)) {
       raise_error << maybe(rr.name) << "tried to reply the wrong number of products in '" << inst.to_string() << "'\n" << end();
     }
@@ -138,7 +138,7 @@ recipe add2 x:number, y:number -> z:number [
 ]
 +mem: storing 8 in location 1
 
-:(before "Transform.push_back(transform_names)")
+:(before "Transform.push_back(check_header_products)")
 Transform.push_back(deduce_types_from_header);
 
 :(code)
@@ -225,7 +225,7 @@ recipe add2 x:number, y:number -> z:number [
 +transform: reply z:number
 +mem: storing 8 in location 1
 
-:(after "Begin Transforms")
+:(after "Transform.push_back(insert_fragments)")
 Transform.push_back(deduce_fallthrough_reply);
 
 :(code)
diff --git a/058generic_container.cc b/058generic_container.cc
index 4ab2a5cd..e757143b 100644
--- a/058generic_container.cc
+++ b/058generic_container.cc
@@ -34,6 +34,11 @@ assert(Next_type_ordinal < START_TYPE_INGREDIENTS);
 :(before "End type_info Fields")
 map<string, type_ordinal> type_ingredient_names;
 
+//: Suppress unknown type checks in generic containers.
+
+:(before "Check Container Field Types(info)")
+if (!info.type_ingredient_names.empty()) continue;
+
 :(before "End container Name Refinements")
 if (name.find(':') != string::npos) {
   trace(9999, "parse") << "container has type ingredients; parsing" << end();
diff --git a/059generic_recipe.cc b/059generic_recipe.cc
index 0f5d85a1..72521285 100644
--- a/059generic_recipe.cc
+++ b/059generic_recipe.cc
@@ -20,6 +20,12 @@ 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.
+
+:(after "void check_invalid_types(const recipe_ordinal r)")
+  if (any_type_ingredient_in_header(r)) return;
+
 :(before "End Instruction Dispatch(inst, best_score)")
 if (best_score == -1) {
   trace(9992, "transform") << "no variant found; searching for variant with suitable type ingredients" << end();