about summary refs log tree commit diff stats
path: root/036call_ingredient.cc
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-05-05 21:17:24 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-05-05 21:17:24 -0700
commitb96af395b9af2ff9df94b3e82213171f30827c8d (patch)
tree17c8c12648ccc25625e2534ec8d74fbe8f1542cc /036call_ingredient.cc
parent2e3b597fe85b654e82b891c22d50754fa5a26156 (diff)
downloadmu-b96af395b9af2ff9df94b3e82213171f30827c8d.tar.gz
1276 - make C++ version the default
I've tried to update the Readme, but there are at least a couple of issues.
Diffstat (limited to '036call_ingredient.cc')
-rw-r--r--036call_ingredient.cc129
1 files changed, 129 insertions, 0 deletions
diff --git a/036call_ingredient.cc b/036call_ingredient.cc
new file mode 100644
index 00000000..6224f8df
--- /dev/null
+++ b/036call_ingredient.cc
@@ -0,0 +1,129 @@
+//: Calls can take ingredients just like primitives. To access a recipe's
+//: ingredients, use 'next-ingredient'.
+
+:(scenario next_ingredient)
+recipe main [
+  f 2:literal
+]
+recipe f [
+  12:integer <- next-ingredient
+  13:integer <- add 1:literal, 12:integer
+]
++run: instruction f/1
++mem: location 12 is 2
++mem: storing 3 in location 13
+
+:(scenario next_ingredient_missing)
+recipe main [
+  f
+]
+recipe f [
+  _, 12:integer <- next-ingredient
+]
++mem: storing 0 in location 12
+
+:(before "End call Fields")
+vector<vector<long long int> > ingredient_atoms;
+index_t next_ingredient_to_process;
+:(replace{} "call(recipe_number r)")
+call(recipe_number r) :running_recipe(r), running_step_index(0), next_ingredient_to_process(0) {}
+
+:(replace "Current_routine->calls.push(call(current_instruction().operation))" following "End Primitive Recipe Implementations")
+call callee(current_instruction().operation);
+for (size_t i = 0; i < current_instruction().ingredients.size(); ++i) {
+  callee.ingredient_atoms.push_back(read_memory(current_instruction().ingredients[i]));
+}
+Current_routine->calls.push(callee);
+
+:(before "End Primitive Recipe Declarations")
+NEXT_INGREDIENT,
+:(before "End Primitive Recipe Numbers")
+Recipe_number["next-ingredient"] = NEXT_INGREDIENT;
+:(before "End Primitive Recipe Implementations")
+case NEXT_INGREDIENT: {
+  if (Current_routine->calls.top().next_ingredient_to_process < Current_routine->calls.top().ingredient_atoms.size()) {
+    trace("run") << "product 0 is "
+        << Current_routine->calls.top().ingredient_atoms[Current_routine->calls.top().next_ingredient_to_process][0];
+    write_memory(current_instruction().products[0],
+        Current_routine->calls.top().ingredient_atoms[Current_routine->calls.top().next_ingredient_to_process]);
+    if (current_instruction().products.size() > 1) {
+      vector<long long int> ingredient_exists;
+      ingredient_exists.push_back(1);
+      write_memory(current_instruction().products[1], ingredient_exists);
+    }
+    ++Current_routine->calls.top().next_ingredient_to_process;
+  }
+  else {
+    if (current_instruction().products.size() > 1) {
+      vector<long long int> no_ingredient;
+      no_ingredient.push_back(0);
+      write_memory(current_instruction().products[1], no_ingredient);
+    }
+  }
+  break;
+}
+
+:(scenario rewind_ingredients)
+recipe main [
+  f 2:literal
+]
+recipe f [
+  12:integer <- next-ingredient  # consume ingredient
+  _, 1:boolean <- next-ingredient  # will not find any ingredients
+  rewind-ingredients
+  13:integer, 2:boolean <- next-ingredient  # will find ingredient again
+]
++mem: storing 2 in location 12
++mem: storing 0 in location 1
++mem: storing 2 in location 13
++mem: storing 1 in location 2
+
+:(before "End Primitive Recipe Declarations")
+REWIND_INGREDIENTS,
+:(before "End Primitive Recipe Numbers")
+Recipe_number["rewind-ingredients"] = REWIND_INGREDIENTS;
+:(before "End Primitive Recipe Implementations")
+case REWIND_INGREDIENTS: {
+  Current_routine->calls.top().next_ingredient_to_process = 0;
+  break;
+}
+
+:(scenario ingredient)
+recipe main [
+  f 1:literal, 2:literal
+]
+recipe f [
+  12:integer <- ingredient 1:literal  # consume second ingredient first
+  13:integer, 1:boolean <- next-ingredient  # next-ingredient tries to scan past that
+]
++mem: storing 2 in location 12
++mem: storing 0 in location 1
+
+:(before "End Primitive Recipe Declarations")
+INGREDIENT,
+:(before "End Primitive Recipe Numbers")
+Recipe_number["ingredient"] = INGREDIENT;
+:(before "End Primitive Recipe Implementations")
+case INGREDIENT: {
+  if (static_cast<index_t>(current_instruction().ingredients[0].value) < Current_routine->calls.top().ingredient_atoms.size()) {
+    Current_routine->calls.top().next_ingredient_to_process = current_instruction().ingredients[0].value;
+    trace("run") << "product 0 is "
+        << Current_routine->calls.top().ingredient_atoms[Current_routine->calls.top().next_ingredient_to_process][0];
+    write_memory(current_instruction().products[0],
+        Current_routine->calls.top().ingredient_atoms[Current_routine->calls.top().next_ingredient_to_process]);
+    if (current_instruction().products.size() > 1) {
+      vector<long long int> ingredient_exists;
+      ingredient_exists.push_back(1);
+      write_memory(current_instruction().products[1], ingredient_exists);
+    }
+    ++Current_routine->calls.top().next_ingredient_to_process;
+  }
+  else {
+    if (current_instruction().products.size() > 1) {
+      vector<long long int> no_ingredient;
+      no_ingredient.push_back(0);
+      write_memory(current_instruction().products[1], no_ingredient);
+    }
+  }
+  break;
+}