diff options
-rw-r--r-- | cpp/.traces/calling_recipe | 11 | ||||
-rw-r--r-- | cpp/011load | 25 | ||||
-rw-r--r-- | cpp/012run | 17 | ||||
-rw-r--r-- | cpp/020call | 8 |
4 files changed, 53 insertions, 8 deletions
diff --git a/cpp/.traces/calling_recipe b/cpp/.traces/calling_recipe new file mode 100644 index 00000000..c0538ca8 --- /dev/null +++ b/cpp/.traces/calling_recipe @@ -0,0 +1,11 @@ +parse/0: instruction: 23 +parse/0: instruction: 2 +parse/0: ingredient: {name: "2", type: 0} +parse/0: ingredient: {name: "2", type: 0} +parse/0: product: {name: "3", type: 1} +run/0: instruction main/0 +run/0: instruction f/0 +run/0: ingredient 0 is 2 +run/0: ingredient 1 is 2 +run/0: product 0 is 4 +mem/0: storing in location 3 diff --git a/cpp/011load b/cpp/011load index ab2d6535..b53063c5 100644 --- a/cpp/011load +++ b/cpp/011load @@ -1,5 +1,5 @@ // It's often convenient to express recipes in a textual fashion. -:(scenarios add_recipe) +:(scenarios add_recipes) :(scenario first_recipe) recipe main [ 1:integer <- copy 23:literal @@ -9,10 +9,15 @@ recipe main [ +parse: product: {name: "1", type: 1} :(code) -int add_recipe(string form) { +int add_recipes(string form) { istringstream in(form); in >> std::noskipws; + int result = add_recipe(in); + while (!in.eof()) add_recipe(in); + return result; +} +int add_recipe(istringstream& in) { skip_comments_and_newlines(in); string _recipe = next_word(in); if (_recipe != "recipe") @@ -20,8 +25,11 @@ int add_recipe(string form) { string recipe_name = next_word(in); if (recipe_name.empty()) - raise << "empty recipe name in " << form << '\n'; - int r = Recipe_number[recipe_name] = Next_recipe_number++; + raise << "empty recipe name in " << in.str() << '\n'; + if (Recipe_number.find(recipe_name) == Recipe_number.end()) + Recipe_number[recipe_name] = Next_recipe_number++; + int r = Recipe_number[recipe_name]; +//? cout << recipe_name << ": adding recipe " << r << '\n'; //? 2 if (next_word(in) != "[") raise << "recipe body must begin with '['\n"; @@ -33,6 +41,7 @@ int add_recipe(string form) { Recipe[r].steps.push_back(curr); } Recipe[r].name = recipe_name; +//? cout << "recipe " << recipe_name << " has " << Recipe[r].steps.size() << " steps.\n"; //? 1 return r; } @@ -51,6 +60,12 @@ bool next_instruction(istream& in, instruction* curr) { } skip_comments_and_newlines(in); if (in.eof()) return false; +//? if (words.size() == 1) cout << words[0] << ' ' << words[0].size() << '\n'; //? 1 + if (words.size() == 1 && words[0] == "]") { +//? cout << "AAA\n"; //? 1 + return false; // end of recipe + } + if (words.size() == 1 && *(words[0].end()-1) == ':') { curr->is_label = true; words[0].erase(words[0].end()-1); @@ -68,6 +83,8 @@ bool next_instruction(istream& in, instruction* curr) { ++p; // skip <- } + if (Recipe_number.find(*p) == Recipe_number.end()) + Recipe_number[*p] = Next_recipe_number++; curr->operation = Recipe_number[*p]; ++p; for (; p != words.end(); ++p) { diff --git a/cpp/012run b/cpp/012run index 2145f360..1a17c6d2 100644 --- a/cpp/012run +++ b/cpp/012run @@ -23,6 +23,8 @@ recipe main [ struct call { recipe_number running_recipe; size_t pc; + vector<int> incoming_atoms; + vector<int> outgoing_atoms; call(recipe_number r) :running_recipe(r), pc(0) {} }; typedef stack<call> call_stack; @@ -38,7 +40,7 @@ struct routine { :(code) void run(string form) { - recipe_number r = add_recipe(form); + recipe_number r = add_recipes(form); routine rr; rr.calls.push(call(r)); run(rr); @@ -57,6 +59,7 @@ void run(routine rr) { ++rr.calls.top().pc; } size_t& pc = rr.calls.top().pc; +//? cout << "instruction " << TOP_RECIPE.name << '/' << pc << '\n'; //? 1 trace("run") << "instruction " << TOP_RECIPE.name << '/' << pc; switch (instructions[pc].operation) { // Primitive Recipe Implementations. @@ -67,9 +70,15 @@ void run(routine rr) { break; } // End Primitive Recipe Implementations. - default: - raise << "undefined operation " << instructions[pc].operation; - } + default: { + if (Recipe.find(instructions[pc].operation) == Recipe.end()) { + raise << "undefined operation " << instructions[pc].operation << '\n'; + break; + } +//? cout << "calling " << instructions[pc].operation << '\n'; //? 1 + rr.calls.push(call(instructions[pc].operation)); + // todo: push incoming atoms + }} ++pc; } #undef TOP_RECIPE diff --git a/cpp/020call b/cpp/020call new file mode 100644 index 00000000..bcc29b3d --- /dev/null +++ b/cpp/020call @@ -0,0 +1,8 @@ +:(scenario "calling_recipe") +recipe main [ + f +] +recipe f [ + 3:integer <- add 2:literal, 2:literal +] ++mem: storing in location 3 |