2015-03-17 03:26:59 +00:00
|
|
|
//: Calls can also generate results, using 'reply'.
|
2015-03-15 16:49:23 +00:00
|
|
|
:(scenario "reply")
|
|
|
|
recipe main [
|
|
|
|
3:integer, 4:integer <- f 2:literal
|
|
|
|
]
|
|
|
|
recipe f [
|
2015-03-17 05:45:24 +00:00
|
|
|
12:integer <- next-ingredient
|
2015-03-15 16:49:23 +00:00
|
|
|
13:integer <- add 1:literal, 12:integer
|
|
|
|
reply 12:integer, 13:integer
|
|
|
|
]
|
|
|
|
+run: instruction main/0
|
2015-03-31 17:56:01 +00:00
|
|
|
+run: result 0 is 2
|
2015-03-24 06:59:59 +00:00
|
|
|
+mem: storing 2 in location 3
|
2015-03-31 17:56:01 +00:00
|
|
|
+run: result 1 is 3
|
2015-03-24 06:59:59 +00:00
|
|
|
+mem: storing 3 in location 4
|
2015-03-15 16:49:23 +00:00
|
|
|
|
|
|
|
:(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]));
|
|
|
|
}
|
|
|
|
rr.calls.pop();
|
2015-04-15 02:06:57 +00:00
|
|
|
assert(!rr.calls.empty());
|
2015-03-15 16:49:23 +00:00
|
|
|
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) {
|
2015-03-31 17:56:01 +00:00
|
|
|
trace("run") << "result " << i << " is " << to_string(callee_results[i]);
|
2015-03-15 16:49:23 +00:00
|
|
|
write_memory(caller_instruction.products[i], callee_results[i]);
|
|
|
|
}
|
|
|
|
++caller_pc;
|
|
|
|
break;
|
|
|
|
}
|
2015-03-31 17:56:01 +00:00
|
|
|
|
2015-04-16 17:35:49 +00:00
|
|
|
//: Results can include containers and exclusive containers, addresses and arrays.
|
|
|
|
:(scenario "reply_container")
|
2015-03-31 17:56:01 +00:00
|
|
|
recipe main [
|
|
|
|
3:point <- f 2:literal
|
|
|
|
]
|
|
|
|
recipe f [
|
|
|
|
12:integer <- next-ingredient
|
|
|
|
13:integer <- copy 35:literal
|
|
|
|
reply 12:point
|
|
|
|
]
|
|
|
|
+run: instruction main/0
|
|
|
|
+run: result 0 is [2, 35]
|
|
|
|
+mem: storing 2 in location 3
|
|
|
|
+mem: storing 35 in location 4
|
|
|
|
|
|
|
|
:(code)
|
|
|
|
string to_string(const vector<int>& in) {
|
|
|
|
if (in.empty()) return "[]";
|
|
|
|
ostringstream out;
|
|
|
|
if (in.size() == 1) {
|
|
|
|
out << in[0];
|
|
|
|
return out.str();
|
|
|
|
}
|
|
|
|
out << "[";
|
|
|
|
for (size_t i = 0; i < in.size(); ++i) {
|
|
|
|
if (i > 0) out << ", ";
|
|
|
|
out << in[i];
|
|
|
|
}
|
|
|
|
out << "]";
|
|
|
|
return out.str();
|
|
|
|
}
|