about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--071recipe.cc34
-rw-r--r--072scheduler.cc15
2 files changed, 39 insertions, 10 deletions
diff --git a/071recipe.cc b/071recipe.cc
index 9135feda..2acfa840 100644
--- a/071recipe.cc
+++ b/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
diff --git a/072scheduler.cc b/072scheduler.cc
index e027b9dc..c5cd616a 100644
--- a/072scheduler.cc
+++ b/072scheduler.cc
@@ -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)