2563 - bring back 'call'

Still need to type-check it, though.
This commit is contained in:
Kartik K. Agaram 2016-01-18 09:13:02 -08:00
parent 83d8299d2d
commit af085cf654
2 changed files with 59 additions and 1 deletions

View File

@ -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)

View File

@ -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;