about summary refs log tree commit diff stats
path: root/cpp
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-03-15 09:43:05 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-03-15 09:43:05 -0700
commitec92602746894c81990a37d7a5e5d7f14a518f0e (patch)
tree5783f2eaadfae829ea4c1524cff52ee8f3d3904c /cpp
parentfa0c006672437f4e89f86d0f53e9e4b3da767a74 (diff)
downloadmu-ec92602746894c81990a37d7a5e5d7f14a518f0e.tar.gz
928 - 'call' layer is now more cohesive
It does less though. Args temporarily not supported.
Diffstat (limited to 'cpp')
-rw-r--r--cpp/.traces/calling_recipe2
-rw-r--r--cpp/002trace3
-rw-r--r--cpp/012run61
-rw-r--r--cpp/020call117
4 files changed, 76 insertions, 107 deletions
diff --git a/cpp/.traces/calling_recipe b/cpp/.traces/calling_recipe
index 3c220e09..c0538ca8 100644
--- a/cpp/.traces/calling_recipe
+++ b/cpp/.traces/calling_recipe
@@ -1,4 +1,4 @@
-parse/0: instruction: 25
+parse/0: instruction: 23
 parse/0: instruction: 2
 parse/0:   ingredient: {name: "2", type: 0}
 parse/0:   ingredient: {name: "2", type: 0}
diff --git a/cpp/002trace b/cpp/002trace
index 796ad7f1..b4d0cfca 100644
--- a/cpp/002trace
+++ b/cpp/002trace
@@ -113,7 +113,7 @@ struct trace_stream {
   void newline() {
     if (!curr_stream) return;
     past_lines.push_back(pair<string, pair<int, string> >(curr_layer, pair<int, string>(frame[curr_layer], curr_stream->str())));
-    if (curr_layer == dump_layer || curr_layer == "dump" ||
+    if (curr_layer == dump_layer || curr_layer == "dump" || dump_layer == "all" ||
         (!Hide_warnings && curr_layer == "warn"))
       cerr << frame[curr_layer] << ": " << with_newline(curr_stream->str());
     delete curr_stream;
@@ -204,6 +204,7 @@ struct lease_tracer {
 #define START_TRACING_UNTIL_END_OF_SCOPE  lease_tracer leased_tracer;
 :(before "End Test Setup")
   START_TRACING_UNTIL_END_OF_SCOPE
+//?   Trace_stream->dump_layer = "all"; //? 1
 
 :(before "End Tracing")
 void trace_all(const string& label, const list<string>& in) {
diff --git a/cpp/012run b/cpp/012run
index 3f02c7b9..558a264d 100644
--- a/cpp/012run
+++ b/cpp/012run
@@ -18,24 +18,12 @@ recipe main [
 +mem: storing in location 2
 
 :(before "End Types")
-// Each recipe can be 'called' many many times in a program. Each call needs a
-// little extra information. TODO: move this into the call layer somehow
-struct call {
-  recipe_number running_recipe;
-  size_t pc;
-  // End Call Fields
-  call(recipe_number r) :running_recipe(r), pc(0) {}
-};
-typedef stack<call> call_stack;
-
-// TODO: move this into the scheduler layer somehow
+// Book-keeping while running a recipe.
+// Later layers will change this.
 struct routine {
-  size_t alloc;
-  size_t alloc_max;
-  call_stack calls;
-  size_t limit;
-  size_t running_since;
-  // todo: sleep conditions
+  recipe_number running_recipe;
+  size_t running_at;
+  routine(recipe_number r) :running_recipe(r), running_at(0) {}
 };
 
 :(code)
@@ -44,23 +32,15 @@ void run(string form) {
 }
 
 void run(recipe_number r) {
-  routine rr;
-  rr.calls.push(call(r));
-  run(rr);
+  run(routine(r));
 }
 
 void run(routine rr) {
-  while (!rr.calls.empty()) {
-    vector<instruction>& instructions = Recipe[rr.calls.top().running_recipe].steps;
-    // TODO: move this into the call layer somehow
-    while (rr.calls.top().pc >= instructions.size()) {
-      rr.calls.pop();
-      if (rr.calls.empty()) return;
-      // todo: no results returned warning
-      ++rr.calls.top().pc;
-    }
-    size_t& pc = rr.calls.top().pc;
-    trace("run") << "instruction " << Recipe[rr.calls.top().running_recipe].name << '/' << pc;
+  while (!done(rr)) {
+    vector<instruction>& instructions = steps(rr);
+    size_t& pc = running_at(rr);
+    // Running one instruction.
+    trace("run") << "instruction " << recipe_name(rr) << '/' << pc;
     switch (instructions[pc].operation) {
       // Primitive Recipe Implementations.
       case COPY: {
@@ -78,6 +58,25 @@ void run(routine rr) {
   }
 }
 
+// Some helpers.
+// We'll need to override these later as we change the definition of routine.
+// Important that they return referrences into the routine.
+inline size_t& running_at(routine& rr) {
+  return rr.running_at;
+}
+
+inline string recipe_name(routine& rr) {
+  return Recipe[rr.running_recipe].name;
+}
+
+inline vector<instruction>& steps(routine& rr) {
+  return Recipe[rr.running_recipe].steps;
+}
+
+inline bool done(routine& rr) {
+  return running_at(rr) >= steps(rr).size();
+}
+
 :(before "End Main")
 if (argc > 1) {
   setup();
diff --git a/cpp/020call b/cpp/020call
index ef15ee94..f926a100 100644
--- a/cpp/020call
+++ b/cpp/020call
@@ -1,3 +1,4 @@
+// So far the recipes we define can't run each other. Let's change that.
 :(scenario "calling_recipe")
 recipe main [
   f
@@ -7,11 +8,37 @@ recipe f [
 ]
 +mem: storing in location 3
 
-:(before "End Call Fields")
-vector<vector<int> > ingredient_atoms;
-size_t next_ingredient_to_process;
-:(replace{} "call(recipe_number r)")
-call(recipe_number r) :running_recipe(r), pc(0), next_ingredient_to_process(0) {}
+:(before "struct routine {")
+// Everytime a recipe runs another, we interrupt it and start running the new
+// recipe. When that finishes, we continue this one where we left off.
+// This requires maintaining a 'stack' of interrupted recipes or 'calls'.
+struct call {
+  recipe_number running_recipe;
+  size_t pc;
+  // End Call Fields
+  call(recipe_number r) :running_recipe(r), pc(0) {}
+};
+typedef stack<call> call_stack;
+
+:(replace{} "struct routine")
+struct routine {
+  call_stack calls;
+  routine(recipe_number r) {
+    calls.push(call(r));
+  }
+};
+:(replace{} "inline size_t& running_at(routine& rr)")
+inline size_t& running_at(routine& rr) {
+  return rr.calls.top().pc;
+}
+:(replace{} "inline string recipe_name(routine& rr)")
+inline string recipe_name(routine& rr) {
+  return Recipe[rr.calls.top().running_recipe].name;
+}
+:(replace{} "inline vector<instruction>& steps(routine& rr)")
+inline vector<instruction>& steps(routine& rr) {
+  return Recipe[rr.calls.top().running_recipe].steps;
+}
 
 :(replace{} "default:" following "End Primitive Recipe Implementations.")
 default: {
@@ -20,79 +47,21 @@ default: {
     raise << "undefined operation " << instructions[pc].operation << '\n';
     break;
   }
-  call callee(instructions[pc].operation);
-  for (vector<reagent>::iterator p = instructions[pc].ingredients.begin(); p != instructions[pc].ingredients.end(); ++p) {
-    callee.ingredient_atoms.push_back(read_memory(*p));
-  }
-  rr.calls.push(callee);
+  rr.calls.push(call(instructions[pc].operation));
   continue;  // not done with caller; don't increment pc
 }
 
-:(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 in location 13
-
-:(before "End Globals")
-const int NEXT_INGREDIENT = 22;
-:(before "End Primitive Recipe Numbers")
-Recipe_number["next_ingredient"] = NEXT_INGREDIENT;
-assert(Next_recipe_number == NEXT_INGREDIENT);
-Next_recipe_number++;
-:(before "End Primitive Recipe Implementations")
-case NEXT_INGREDIENT: {
-  if (rr.calls.top().next_ingredient_to_process < rr.calls.top().ingredient_atoms.size()) {
-    trace("run") << "product 0 is "
-        << rr.calls.top().ingredient_atoms[rr.calls.top().next_ingredient_to_process][0];
-    write_memory(instructions[pc].products[0],
-        rr.calls.top().ingredient_atoms[rr.calls.top().next_ingredient_to_process]);
-    ++rr.calls.top().next_ingredient_to_process;
-  }
-  break;
+:(replace{} "inline bool done(routine& rr)")
+inline bool done(routine& rr) {
+  return rr.calls.empty();
 }
 
-:(scenario "reply")
-recipe main [
-  3:integer, 4:integer <- f 2:literal
-]
-recipe f [
-  12:integer <- next_ingredient
-  13:integer <- add 1:literal, 12:integer
-  reply 12:integer, 13:integer
-]
-+run: instruction main/0
-+run: result 0 is 1[2...]
-+mem: storing in location 3
-+run: result 1 is 1[3...]
-+mem: storing in location 4
-
-:(before "End Globals")
-const int REPLY = 23;
-:(before "End Primitive Recipe Numbers")
-Recipe_number["reply"] = REPLY;
-assert(Next_recipe_number == REPLY);
-Next_recipe_number++;
-:(before "End Primitive Recipe Implementations")
-case REPLY: {
-  vector<vector<int> > callee_results;
-  for (size_t i = 0; i < instructions[pc].ingredients.size(); ++i) {
-    callee_results.push_back(read_memory(instructions[pc].ingredients[i]));
-  }
+:(before "Running one instruction.")
+// when we reach the end of one call, we may reach the end of the one below
+// it, and the one below that, and so on
+while (running_at(rr) >= steps(rr).size()) {
   rr.calls.pop();
-  size_t& caller_pc = rr.calls.top().pc;
-  instruction& caller_instruction = Recipe[rr.calls.top().running_recipe].steps[caller_pc];
-  assert(caller_instruction.products.size() <= callee_results.size());
-  for (size_t i = 0; i < caller_instruction.products.size(); ++i) {
-    trace("run") << "result " << i << " is " << callee_results[i].size() << "[" << callee_results[i][0] << "...]";
-    write_memory(caller_instruction.products[i], callee_results[i]);
-  }
-  ++caller_pc;
-  break;
+  if (rr.calls.empty()) return;
+  // todo: no results returned warning
+  ++running_at(rr);
 }