diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-02-25 01:24:11 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-02-25 01:24:11 -0800 |
commit | 6f5d7864f6c0c62b8849349cb182c61f8dbed452 (patch) | |
tree | c4c22032dc09eefbc3b55268044d29607804c4fd /cpp/012run | |
parent | dc3803320013059ad400853e3f6a2851f7f82c04 (diff) | |
download | mu-6f5d7864f6c0c62b8849349cb182c61f8dbed452.tar.gz |
832 - call-stack for C++ version
These #defines and references now span many different layers. Let's see if the lack of encapsulation causes problems. Also interesting to run into a case where I need to modify a foundational layer and touch every single scenario/trace. Only alternative was to duplicate all the different layers that add instructions. Sign of problems with this model?
Diffstat (limited to 'cpp/012run')
-rw-r--r-- | cpp/012run | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/cpp/012run b/cpp/012run index 194a55c5..79dcbfc2 100644 --- a/cpp/012run +++ b/cpp/012run @@ -3,7 +3,7 @@ recipe main [ 1:integer <- copy 23:literal ] -+run: instruction 0 ++run: instruction main/0 +run: ingredient 0 is 23 +mem: storing in location 1 @@ -12,20 +12,45 @@ recipe main [ 1:integer <- copy 23:literal 2:integer <- copy 1:integer ] -+run: instruction 1 ++run: instruction main/1 +run: ingredient 0 is 1 +mem: location 1 is 23 +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. +struct call { + recipe_number running_recipe; + size_t pc; + call(recipe_number r) :running_recipe(r), pc(0) {} +}; +typedef stack<call> call_stack; + :(code) void run(string form) { - run(add_recipe(form)); + recipe_number r = add_recipe(form); + call_stack context; + context.push(call(r)); + run(context); } -void run(recipe_number r) { - vector<instruction>& instructions(Recipe[r].steps); - for (size_t pc = 0; pc < instructions.size(); ++pc) { - trace("run") << "instruction " << pc; +void run(call_stack context) { +// #defines save us the trouble of updating aliases when dependent variables +// change. +#define TOP Recipe[context.top().running_recipe] +#define instructions TOP.steps + while (!context.empty()) { + while (context.top().pc >= instructions.size()) { + context.pop(); + if (context.empty()) return; + // todo: no results returned warning + ++context.top().pc; + } +//? cout << context.size() << '\n'; //? 1 + size_t& pc = context.top().pc; +//? cout << "instruction " << TOP.name << '/' << pc << '\n'; //? 1 + trace("run") << "instruction " << TOP.name << '/' << pc; switch (instructions[pc].operation) { // Primitive Recipe Implementations. case COPY: { @@ -38,7 +63,10 @@ void run(recipe_number r) { default: raise << "undefined operation " << instructions[pc].operation; } + ++pc; } +#undef TOP +#undef instructions } vector<int> read_memory(reagent x) { |