2482 - better choice between valid variants
Literal '0' ingredients should map to numbers before addresses.
This commit is contained in:
parent
0ddcab7bc0
commit
7f193a0e00
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user