about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-01-18 09:13:02 -0800
committerKartik K. Agaram <vc@akkartik.com>2016-01-18 09:13:02 -0800
commitaf085cf654eb499c1756509dea1d74f93ecbef45 (patch)
treea427216eb34e075fc005fd6aee13ceb507868437
parent83d8299d2d966c39b4970828ff5743a5b05e3287 (diff)
downloadmu-af085cf654eb499c1756509dea1d74f93ecbef45.tar.gz
2563 - bring back 'call'
Still need to type-check it, though.
-rw-r--r--034call.cc6
-rw-r--r--061recipe.cc54
2 files changed, 59 insertions, 1 deletions
diff --git a/034call.cc b/034call.cc
index 957a43f6..ff004dc1 100644
--- a/034call.cc
+++ b/034call.cc
@@ -115,8 +115,12 @@ default: {
     assert(Trace_stream->callstack_depth < 9000);  // 9998-101 plus cushion
   }
   Current_routine->calls.push_front(call(current_instruction().operation));
+  finish_call_housekeeping(call_instruction, ingredients);
+  continue;  // not done with caller; don't increment step_index of caller
+}
+:(code)
+void finish_call_housekeeping(const instruction& call_instruction, const vector<vector<double> >& ingredients) {
   // End Call Housekeeping
-  continue;  // not done with caller; don't increment current_step_index()
 }
 
 :(scenario calling_undefined_recipe_fails)
diff --git a/061recipe.cc b/061recipe.cc
index 3d7c0eaa..56ccc8d1 100644
--- a/061recipe.cc
+++ b/061recipe.cc
@@ -2,6 +2,29 @@
 //: also like to make the recipe a variable, pass recipes to "higher-order"
 //: recipes, return recipes from recipes and so on.
 
+:(scenario call_literal_recipe)
+recipe main [
+  1:number <- call f, 34
+]
+recipe f x:number -> y:number [
+  local-scope
+  load-ingredients
+  y <- copy x
+]
++mem: storing 34 in location 1
+
+:(scenario call_variable)
+recipe main [
+  {1: (recipe number -> number)} <- copy f
+  2:number <- call {1: (recipe number -> number)}, 34
+]
+recipe f x:number -> y:number [
+  local-scope
+  load-ingredients
+  y <- copy x
+]
++mem: storing 34 in location 2
+
 :(before "End Mu Types Initialization")
 put(Type_ordinal, "recipe-literal", 0);
 // 'recipe' variables can store recipe-literal
@@ -16,6 +39,37 @@ if (!x.properties.at(0).second && contains_key(Recipe_ordinal, x.name)) {
   return true;
 }
 
+:(before "End Primitive Recipe Declarations")
+CALL,
+:(before "End Primitive Recipe Numbers")
+put(Recipe_ordinal, "call", CALL);
+:(before "End Primitive Recipe Checks")
+case CALL: {
+  if (inst.ingredients.empty()) {
+    raise_error << maybe(get(Recipe, r).name) << "'call' requires at least one ingredient (the recipe to call)\n" << end();
+    break;
+  }
+  if (!is_mu_recipe(inst.ingredients.at(0))) {
+    raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'call' should be a recipe, but got " << inst.ingredients.at(0).original_string << '\n' << end();
+    break;
+  }
+  break;
+}
+:(before "End Primitive Recipe Implementations")
+case CALL: {
+  // Begin Call
+  if (Trace_stream) {
+    ++Trace_stream->callstack_depth;
+    trace("trace") << "indirect 'call': incrementing callstack depth to " << Trace_stream->callstack_depth << end();
+    assert(Trace_stream->callstack_depth < 9000);  // 9998-101 plus cushion
+  }
+  const instruction& caller_instruction = current_instruction();
+  Current_routine->calls.push_front(call(ingredients.at(0).at(0)));
+  ingredients.erase(ingredients.begin());  // drop the callee
+  finish_call_housekeeping(caller_instruction, ingredients);
+  continue;
+}
+
 :(code)
 bool is_mu_recipe(reagent r) {
   if (!r.type) return false;