3545
Type-check ingredients of 'start-running'
This commit is contained in:
parent
70f4e9b60d
commit
a542b5a9c5
34
071recipe.cc
34
071recipe.cc
|
@ -160,24 +160,38 @@ void check_indirect_calls_against_header(const recipe_ordinal r) {
|
|||
const recipe& caller = get(Recipe, r);
|
||||
for (int i = 0; i < SIZE(caller.steps); ++i) {
|
||||
const instruction& inst = caller.steps.at(i);
|
||||
if (inst.operation != CALL) continue;
|
||||
if (inst.ingredients.empty()) continue; // error raised above
|
||||
if (inst.ingredients.empty()) continue; // if indirect call, error raised above
|
||||
const reagent& callee = inst.ingredients.at(0);
|
||||
if (!is_mu_recipe(callee)) continue; // error raised above
|
||||
if (!is_mu_recipe(callee)) continue; // if indirect call, error raised above
|
||||
const recipe callee_header = is_literal(callee) ? get(Recipe, callee.value) : from_reagent(inst.ingredients.at(0));
|
||||
if (!callee_header.has_header) continue;
|
||||
for (long int i = /*skip callee*/1; i < min(SIZE(inst.ingredients), SIZE(callee_header.ingredients)+/*skip callee*/1); ++i) {
|
||||
if (!types_coercible(callee_header.ingredients.at(i-/*skip callee*/1), inst.ingredients.at(i)))
|
||||
raise << maybe(caller.name) << "ingredient " << i-/*skip callee*/1 << " has the wrong type at '" << inst.original_string << "'\n" << end();
|
||||
if (is_indirect_call_with_ingredients(inst.operation)) {
|
||||
for (long int i = /*skip callee*/1; i < min(SIZE(inst.ingredients), SIZE(callee_header.ingredients)+/*skip callee*/1); ++i) {
|
||||
if (!types_coercible(callee_header.ingredients.at(i-/*skip callee*/1), inst.ingredients.at(i)))
|
||||
raise << maybe(caller.name) << "ingredient " << i-/*skip callee*/1 << " has the wrong type at '" << inst.original_string << "'\n" << end();
|
||||
}
|
||||
}
|
||||
for (long int i = 0; i < min(SIZE(inst.products), SIZE(callee_header.products)); ++i) {
|
||||
if (is_dummy(inst.products.at(i))) continue;
|
||||
if (!types_coercible(callee_header.products.at(i), inst.products.at(i)))
|
||||
raise << maybe(caller.name) << "product " << i << " has the wrong type at '" << inst.original_string << "'\n" << end();
|
||||
if (is_indirect_call_with_products(inst.operation)) {
|
||||
for (long int i = 0; i < min(SIZE(inst.products), SIZE(callee_header.products)); ++i) {
|
||||
if (is_dummy(inst.products.at(i))) continue;
|
||||
if (!types_coercible(callee_header.products.at(i), inst.products.at(i)))
|
||||
raise << maybe(caller.name) << "product " << i << " has the wrong type at '" << inst.original_string << "'\n" << end();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool is_indirect_call_with_ingredients(const recipe_ordinal r) {
|
||||
if (r == CALL) return true;
|
||||
// End is_indirect_call_with_ingredients Special-cases
|
||||
return false;
|
||||
}
|
||||
bool is_indirect_call_with_products(const recipe_ordinal r) {
|
||||
if (r == CALL) return true;
|
||||
// End is_indirect_call_with_products Special-cases
|
||||
return false;
|
||||
}
|
||||
|
||||
recipe from_reagent(const reagent& r) {
|
||||
assert(r.type);
|
||||
recipe result_header; // will contain only ingredients and products, nothing else
|
||||
|
|
|
@ -239,6 +239,21 @@ def f2 [
|
|||
]
|
||||
+mem: storing 4 in location 2
|
||||
|
||||
//: type-checking for 'start-running'
|
||||
|
||||
:(scenario start_running_checks_types)
|
||||
% Hide_errors = true;
|
||||
def f1 [
|
||||
start-running f2, 3
|
||||
]
|
||||
def f2 n:&:num [
|
||||
]
|
||||
+error: f1: ingredient 0 has the wrong type at 'start-running f2, 3'
|
||||
|
||||
// 'start-running' only uses the ingredients of the callee, not its products
|
||||
:(before "End is_indirect_call_with_ingredients Special-cases")
|
||||
if (r == START_RUNNING) return true;
|
||||
|
||||
//: more complex: refcounting management when starting up new routines
|
||||
|
||||
:(scenario start_running_immediately_updates_refcounts_of_ingredients)
|
||||
|
|
Loading…
Reference in New Issue
Block a user