diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-11-27 18:10:15 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-11-27 18:10:15 -0800 |
commit | 7f193a0e006c44604918b54c853bd49508dbe8fd (patch) | |
tree | a937f880fa2e7a64666c8ceb262dc16de9f777be | |
parent | 0ddcab7bc0e856dfe5e0556e972f3c21fd16d6d1 (diff) | |
download | mu-7f193a0e006c44604918b54c853bd49508dbe8fd.tar.gz |
2482 - better choice between valid variants
Literal '0' ingredients should map to numbers before addresses.
-rw-r--r-- | 021check_instruction.cc | 8 | ||||
-rw-r--r-- | 031address.cc | 2 | ||||
-rw-r--r-- | 057static_dispatch.cc | 33 |
3 files changed, 38 insertions, 5 deletions
diff --git a/021check_instruction.cc b/021check_instruction.cc index f79ae140..930eacde 100644 --- a/021check_instruction.cc +++ b/021check_instruction.cc @@ -82,15 +82,19 @@ recipe main [ $error: 0 :(code) +bool types_match(const reagent& lhs, const reagent& rhs) { + if (!is_unsafe(rhs) && is_literal(rhs)) return valid_type_for_literal(lhs, rhs) && size_of(rhs) == size_of(lhs); + return types_strictly_match(lhs, rhs); +} + // copy arguments because later layers will want to make changes to them // without perturbing the caller -bool types_match(reagent lhs, reagent rhs) { +bool types_strictly_match(reagent lhs, reagent rhs) { // '_' never raises type error if (is_dummy(lhs)) return true; // to sidestep type-checking, use /unsafe in the source. // this will be highlighted in red inside vim. just for setting up some tests. if (is_unsafe(rhs)) return true; - if (is_literal(rhs)) return valid_type_for_literal(lhs, rhs) && size_of(rhs) == size_of(lhs); if (!lhs.type) return !rhs.type; return types_match(lhs.type, rhs.type); } diff --git a/031address.cc b/031address.cc index 4d012ad5..040037bd 100644 --- a/031address.cc +++ b/031address.cc @@ -61,7 +61,7 @@ void lookup_memory(reagent& x) { drop_one_lookup(x); } -:(after "bool types_match(reagent lhs, reagent rhs)") +:(after "bool types_strictly_match(reagent lhs, reagent rhs)") if (!canonize_type(lhs)) return false; if (!canonize_type(rhs)) return false; diff --git a/057static_dispatch.cc b/057static_dispatch.cc index f38b813d..bc9fd8e2 100644 --- a/057static_dispatch.cc +++ b/057static_dispatch.cc @@ -140,6 +140,7 @@ void replace_best_variant(instruction& inst, const recipe& caller_recipe) { } long long int variant_score(const instruction& inst, recipe_ordinal variant) { + long long int result = 100; if (variant == -1) return -1; // ghost from a previous test if (!contains_key(Recipe, variant)) { assert(variant < MAX_PRIMITIVE_RECIPES); @@ -155,6 +156,14 @@ long long int variant_score(const instruction& inst, recipe_ordinal variant) { trace(9993, "transform") << "mismatch: ingredient " << i << end(); return -1; } + if (types_strictly_match(header_ingredients.at(i), inst.ingredients.at(i))) { + trace(9993, "transform") << "strict match: ingredient " << i << end(); + } + else { + // slight penalty for things like coercing literal 0 to an address + trace(9993, "transform") << "non-strict match: ingredient " << i << end(); + result--; + } } if (SIZE(inst.products) > SIZE(get(Recipe, variant).products)) { trace(9993, "transform") << "too few products" << end(); @@ -166,10 +175,18 @@ long long int variant_score(const instruction& inst, recipe_ordinal variant) { trace(9993, "transform") << "mismatch: product " << i << end(); return -1; } + if (types_strictly_match(header_products.at(i), inst.products.at(i))) { + trace(9993, "transform") << "strict match: ingredient " << i << end(); + } + else { + // slight penalty for things like coercing literal 0 to an address + trace(9993, "transform") << "non-strict match: ingredient " << i << end(); + result--; + } } // the greater the number of unused ingredients, the lower the score - return 100 - (SIZE(get(Recipe, variant).products)-SIZE(inst.products)) - - (SIZE(inst.ingredients)-SIZE(get(Recipe, variant).ingredients)); // ok to go negative + return result - (SIZE(get(Recipe, variant).products)-SIZE(inst.products)) + - (SIZE(inst.ingredients)-SIZE(get(Recipe, variant).ingredients)); // ok to go negative } :(scenario static_dispatch_disabled_on_headerless_definition) @@ -212,3 +229,15 @@ recipe equal x:number, y:number -> z:boolean [ +mem: storing 0 in location 3 # comparing booleans continues to use primitive +mem: storing 1 in location 6 + +:(scenario static_dispatch_prefers_literals_to_be_numbers_rather_than_addresses) +recipe main [ + 1:number <- foo 0 +] +recipe foo x:address:number -> y:number [ + reply 34 +] +recipe foo x:number -> y:number [ + reply 35 +] ++mem: storing 35 in location 1 |