about summary refs log tree commit diff stats
path: root/056recipe_header.cc
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-10-29 20:03:16 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-10-29 20:03:16 -0700
commit9cfb86fac1b90c957e7568a2d5fa5f737cdf90e4 (patch)
treea5bffac0cc708b60aa1c720d9ba38a119c1891bb /056recipe_header.cc
parente6692482643dc007988188e2b19fbb9219ca2833 (diff)
downloadmu-9cfb86fac1b90c957e7568a2d5fa5f737cdf90e4.tar.gz
2322 - deduce types from recipe header
Diffstat (limited to '056recipe_header.cc')
-rw-r--r--056recipe_header.cc50
1 files changed, 47 insertions, 3 deletions
diff --git a/056recipe_header.cc b/056recipe_header.cc
index 2ba0ac4b..cc47ca6a 100644
--- a/056recipe_header.cc
+++ b/056recipe_header.cc
@@ -96,10 +96,54 @@ void check_header_products(const recipe_ordinal r) {
   }
 }
 
+//: Deduce types from the header if possible.
+
+:(scenarios run)
+:(scenario deduce_instruction_types_from_recipe_header)
+recipe main [
+  1:number/raw <- add2 3, 5
+]
+recipe add2 x:number, y:number -> z:number [
+  local-scope
+  load-ingredients
+  z <- add x, y  # no type for z
+  reply z
+]
++mem: storing 8 in location 1
+
+:(before "Transform.push_back(transform_names)")
+  Transform.push_back(deduce_types_from_header);
+
+:(code)
+void deduce_types_from_header(const recipe_ordinal r) {
+  recipe& rr = Recipe[r];
+  if (rr.products.empty()) return;
+  trace(9991, "transform") << "--- deducing types from header for " << rr.name << end();
+  map<string, const type_tree*> header;
+  for (long long int i = 0; i < SIZE(rr.ingredients); ++i) {
+    header[rr.ingredients.at(i).name] = rr.ingredients.at(i).type;
+  }
+  for (long long int i = 0; i < SIZE(rr.products); ++i) {
+    header[rr.products.at(i).name] = rr.products.at(i).type;
+  }
+  for (long long int i = 0; i < SIZE(rr.steps); ++i) {
+    instruction& inst = rr.steps.at(i);
+    trace(9993, "transform") << inst.to_string() << '\n';
+    for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
+      if (inst.ingredients.at(i).type) continue;
+      inst.ingredients.at(i).type = new type_tree(*header[inst.ingredients.at(i).name]);
+    }
+    for (long long int i = 0; i < SIZE(inst.products); ++i) {
+      if (inst.products.at(i).type) continue;
+      inst.products.at(i).type = new type_tree(*header[inst.products.at(i).name]);
+      trace(9993, "transform") << "type of " << inst.products.at(i).name << " is " << dump_types(inst.products.at(i)) << '\n';
+    }
+  }
+}
+
 //: One final convenience: no need to say what to return if the information is
 //: in the header.
 
-:(scenarios run)
 :(scenario reply_based_on_header)
 recipe main [
   1:number/raw <- add2 3, 5
@@ -107,7 +151,7 @@ recipe main [
 recipe add2 x:number, y:number -> z:number [
   local-scope
   load-ingredients
-  z:number <- add x, y
+  z <- add x, y
   reply
 ]
 +mem: storing 8 in location 1
@@ -126,7 +170,7 @@ recipe main [
 recipe add2 x:number, y:number -> z:number [
   local-scope
   load-ingredients
-  z:number <- add x, y
+  z <- add x, y
 ]
 +mem: storing 8 in location 1