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.
This commit is contained in:
Kartik K. Agaram 2015-11-04 23:44:46 -08:00
parent 54275c64e2
commit 436b2b2eac
11 changed files with 60 additions and 15 deletions

View File

@ -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)

View File

@ -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));
}

View File

@ -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;

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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();

View File

@ -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();