about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--cpp/.traces/calling_recipe11
-rw-r--r--cpp/011load25
-rw-r--r--cpp/012run17
-rw-r--r--cpp/020call8
4 files changed, 53 insertions, 8 deletions
diff --git a/cpp/.traces/calling_recipe b/cpp/.traces/calling_recipe
new file mode 100644
index 00000000..c0538ca8
--- /dev/null
+++ b/cpp/.traces/calling_recipe
@@ -0,0 +1,11 @@
+parse/0: instruction: 23
+parse/0: instruction: 2
+parse/0:   ingredient: {name: "2", type: 0}
+parse/0:   ingredient: {name: "2", type: 0}
+parse/0:   product: {name: "3", type: 1}
+run/0: instruction main/0
+run/0: instruction f/0
+run/0: ingredient 0 is 2
+run/0: ingredient 1 is 2
+run/0: product 0 is 4
+mem/0: storing in location 3
diff --git a/cpp/011load b/cpp/011load
index ab2d6535..b53063c5 100644
--- a/cpp/011load
+++ b/cpp/011load
@@ -1,5 +1,5 @@
 // It's often convenient to express recipes in a textual fashion.
-:(scenarios add_recipe)
+:(scenarios add_recipes)
 :(scenario first_recipe)
 recipe main [
   1:integer <- copy 23:literal
@@ -9,10 +9,15 @@ recipe main [
 +parse:   product: {name: "1", type: 1}
 
 :(code)
-int add_recipe(string form) {
+int add_recipes(string form) {
   istringstream in(form);
   in >> std::noskipws;
+  int result = add_recipe(in);
+  while (!in.eof()) add_recipe(in);
+  return result;
+}
 
+int add_recipe(istringstream& in) {
   skip_comments_and_newlines(in);
   string _recipe = next_word(in);
   if (_recipe != "recipe")
@@ -20,8 +25,11 @@ int add_recipe(string form) {
 
   string recipe_name = next_word(in);
   if (recipe_name.empty())
-    raise << "empty recipe name in " << form << '\n';
-  int r = Recipe_number[recipe_name] = Next_recipe_number++;
+    raise << "empty recipe name in " << in.str() << '\n';
+  if (Recipe_number.find(recipe_name) == Recipe_number.end())
+    Recipe_number[recipe_name] = Next_recipe_number++;
+  int r = Recipe_number[recipe_name];
+//?   cout << recipe_name << ": adding recipe " << r << '\n'; //? 2
 
   if (next_word(in) != "[")
     raise << "recipe body must begin with '['\n";
@@ -33,6 +41,7 @@ int add_recipe(string form) {
     Recipe[r].steps.push_back(curr);
   }
   Recipe[r].name = recipe_name;
+//?   cout << "recipe " << recipe_name << " has " << Recipe[r].steps.size() << " steps.\n"; //? 1
   return r;
 }
 
@@ -51,6 +60,12 @@ bool next_instruction(istream& in, instruction* curr) {
   }
   skip_comments_and_newlines(in);  if (in.eof()) return false;
 
+//?   if (words.size() == 1) cout << words[0] << ' ' << words[0].size() << '\n'; //? 1
+  if (words.size() == 1 && words[0] == "]") {
+//?     cout << "AAA\n"; //? 1
+    return false;  // end of recipe
+  }
+
   if (words.size() == 1 && *(words[0].end()-1) == ':') {
     curr->is_label = true;
     words[0].erase(words[0].end()-1);
@@ -68,6 +83,8 @@ bool next_instruction(istream& in, instruction* curr) {
     ++p;  // skip <-
   }
 
+  if (Recipe_number.find(*p) == Recipe_number.end())
+    Recipe_number[*p] = Next_recipe_number++;
   curr->operation = Recipe_number[*p];  ++p;
 
   for (; p != words.end(); ++p) {
diff --git a/cpp/012run b/cpp/012run
index 2145f360..1a17c6d2 100644
--- a/cpp/012run
+++ b/cpp/012run
@@ -23,6 +23,8 @@ recipe main [
 struct call {
   recipe_number running_recipe;
   size_t pc;
+  vector<int> incoming_atoms;
+  vector<int> outgoing_atoms;
   call(recipe_number r) :running_recipe(r), pc(0) {}
 };
 typedef stack<call> call_stack;
@@ -38,7 +40,7 @@ struct routine {
 
 :(code)
 void run(string form) {
-  recipe_number r = add_recipe(form);
+  recipe_number r = add_recipes(form);
   routine rr;
   rr.calls.push(call(r));
   run(rr);
@@ -57,6 +59,7 @@ void run(routine rr) {
       ++rr.calls.top().pc;
     }
     size_t& pc = rr.calls.top().pc;
+//?     cout << "instruction " << TOP_RECIPE.name << '/' << pc << '\n'; //? 1
     trace("run") << "instruction " << TOP_RECIPE.name << '/' << pc;
     switch (instructions[pc].operation) {
     // Primitive Recipe Implementations.
@@ -67,9 +70,15 @@ void run(routine rr) {
       break;
     }
     // End Primitive Recipe Implementations.
-    default:
-      raise << "undefined operation " << instructions[pc].operation;
-    }
+    default: {
+      if (Recipe.find(instructions[pc].operation) == Recipe.end()) {
+        raise << "undefined operation " << instructions[pc].operation << '\n';
+        break;
+      }
+//?       cout << "calling " << instructions[pc].operation << '\n'; //? 1
+      rr.calls.push(call(instructions[pc].operation));
+      // todo: push incoming atoms
+    }}
     ++pc;
   }
 #undef TOP_RECIPE
diff --git a/cpp/020call b/cpp/020call
new file mode 100644
index 00000000..bcc29b3d
--- /dev/null
+++ b/cpp/020call
@@ -0,0 +1,8 @@
+:(scenario "calling_recipe")
+recipe main [
+  f
+]
+recipe f [
+  3:integer <- add 2:literal, 2:literal
+]
++mem: storing in location 3