From 69f04c3fb0136778b80f7f64e16ae37cf8d22907 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Sun, 15 Mar 2015 09:49:23 -0700 Subject: 929 - recipes again take ingredients and reply with results --- cpp/.traces/calling_recipe | 2 +- cpp/.traces/next_ingredient | 6 ------ cpp/021call_ingredient | 44 ++++++++++++++++++++++++++++++++++++++++++++ cpp/022call_reply | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 cpp/021call_ingredient create mode 100644 cpp/022call_reply diff --git a/cpp/.traces/calling_recipe b/cpp/.traces/calling_recipe index c0538ca8..3c220e09 100644 --- a/cpp/.traces/calling_recipe +++ b/cpp/.traces/calling_recipe @@ -1,4 +1,4 @@ -parse/0: instruction: 23 +parse/0: instruction: 25 parse/0: instruction: 2 parse/0: ingredient: {name: "2", type: 0} parse/0: ingredient: {name: "2", type: 0} diff --git a/cpp/.traces/next_ingredient b/cpp/.traces/next_ingredient index 1970698a..8ded3d51 100644 --- a/cpp/.traces/next_ingredient +++ b/cpp/.traces/next_ingredient @@ -16,9 +16,3 @@ run/0: ingredient 1 is 12 mem/0: location 12 is 2 run/0: product 0 is 3 mem/0: storing in location 13 -run/0: instruction main/1 -run/0: ingredient 0 is 1 -run/0: ingredient 1 is 12 -mem/0: location 12 is 2 -run/0: product 0 is 3 -mem/0: storing in location 13 diff --git a/cpp/021call_ingredient b/cpp/021call_ingredient new file mode 100644 index 00000000..f42f0b48 --- /dev/null +++ b/cpp/021call_ingredient @@ -0,0 +1,44 @@ +// 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 in location 13 + +:(before "End Call Fields") +vector > 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) {} + +:(replace "rr.calls.push(call(instructions[pc].operation))" following "End Primitive Recipe Implementations") +call callee(instructions[pc].operation); +for (vector::iterator p = instructions[pc].ingredients.begin(); p != instructions[pc].ingredients.end(); ++p) { + callee.ingredient_atoms.push_back(read_memory(*p)); +} +rr.calls.push(callee); + +:(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; +} diff --git a/cpp/022call_reply b/cpp/022call_reply new file mode 100644 index 00000000..0d0149cb --- /dev/null +++ b/cpp/022call_reply @@ -0,0 +1,39 @@ +// Calls can also generate results, using 'reply'. +:(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 > callee_results; + for (size_t i = 0; i < instructions[pc].ingredients.size(); ++i) { + callee_results.push_back(read_memory(instructions[pc].ingredients[i])); + } + 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; +} -- cgit 1.4.1-2-gfad0