From 795f5244abc9b9f26ff621fd1997db427289d2ba Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Fri, 6 Nov 2015 11:06:58 -0800 Subject: 2377 - stop using operator[] in map I'm still seeing all sorts of failures in turning on layer 11 of edit/, so I'm backing away and nailing down every culprit I run into. First up: stop accidentally inserting empty objects into maps during lookups. Commands run: $ sed -i 's/\(Recipe_ordinal\|Recipe\|Type_ordinal\|Type\|Memory\)\[\([^]]*\)\] = \(.*\);/put(\1, \2, \3);/' 0[1-9]* $ vi 075scenario_console.cc # manually fix up Memory[Memory[CONSOLE]] $ sed -i 's/\(Memory\)\[\([^]]*\)\]/get_or_insert(\1, \2)/' 0[1-9]* $ sed -i 's/\(Recipe_ordinal\|Type_ordinal\)\[\([^]]*\)\]/get(\1, \2)/' 0[1-9]* $ sed -i 's/\(Recipe\|Type\)\[\([^]]*\)\]/get(\1, \2)/' 0[1-9]* Now mu dies pretty quickly because of all the places I try to lookup a missing value. --- 001help.cc | 16 +++++++ 010vm.cc | 40 ++++++++--------- 011load.cc | 14 +++--- 013update_operation.cc | 10 ++--- 014literal_string.cc | 2 +- 020run.cc | 18 ++++---- 021check_instruction.cc | 24 +++++----- 022arithmetic.cc | 46 +++++++++---------- 023boolean.cc | 14 +++--- 024jump.cc | 24 +++++----- 025compare.cc | 28 ++++++------ 029tools.cc | 40 ++++++++--------- 030container.cc | 110 +++++++++++++++++++++++----------------------- 031address.cc | 16 +++---- 032array.cc | 52 +++++++++++----------- 033exclusive_container.cc | 32 +++++++------- 034call.cc | 8 ++-- 035call_ingredient.cc | 12 ++--- 036call_reply.cc | 10 ++--- 037recipe.cc | 12 ++--- 038scheduler.cc | 38 ++++++++-------- 039wait.cc | 16 +++---- 040brace.cc | 32 +++++++------- 041jump_target.cc | 18 ++++---- 042name.cc | 42 +++++++++--------- 043new.cc | 58 ++++++++++++------------ 044space.cc | 18 ++++---- 045space_surround.cc | 2 +- 046closure_name.cc | 24 +++++----- 047global.cc | 6 +-- 048check_type_by_name.cc | 8 ++-- 050scenario.cc | 34 +++++++------- 052tangle.cc | 8 ++-- 054dilated_reagent.cc | 4 +- 056recipe_header.cc | 20 ++++----- 057static_dispatch.cc | 36 +++++++-------- 058generic_container.cc | 18 ++++---- 059generic_recipe.cc | 26 +++++------ 064random.cc | 10 ++--- 070display.cc | 58 ++++++++++++------------ 072scenario_screen.cc | 60 ++++++++++++------------- 075scenario_console.cc | 52 +++++++++++----------- 080trace_browser.cc | 2 +- 081run_interactive.cc | 36 +++++++-------- 082persist.cc | 14 +++--- 45 files changed, 593 insertions(+), 575 deletions(-) diff --git a/001help.cc b/001help.cc index da3b2b75..3ed85e12 100644 --- a/001help.cc +++ b/001help.cc @@ -87,6 +87,22 @@ bool is_equal(char* s, const char* lit) { //: //: 5. Integer overflow is still impossible to guard against. Maybe after //: reading http://www.cs.utah.edu/~regehr/papers/overflow12.pdf +//: +//: 6. Map's operator[] being non-const is fucking evil. +:(before "Globals") // can't generate prototypes for these +// from http://stackoverflow.com/questions/152643/idiomatic-c-for-reading-from-a-const-map +template typename T::mapped_type& get(T& map, typename T::key_type const& key) { + typename T::iterator iter(map.find(key)); + assert(iter != map.end()); + return iter->second; +} +template typename T::mapped_type& get_or_insert(T& map, typename T::key_type const& key) { + return map[key]; +} +template typename T::mapped_type const& put(T& map, typename T::key_type const& key, typename T::mapped_type const& value) { + map[key] = value; + return map[key]; +} :(before "End Includes") #include diff --git a/010vm.cc b/010vm.cc index 17f2140c..ef21cedf 100644 --- a/010vm.cc +++ b/010vm.cc @@ -34,7 +34,7 @@ struct instruction { string label; // only if is_label string name; // only if !is_label string old_name; // before our automatic rewrite rules - recipe_ordinal operation; // Recipe_ordinal[name] + recipe_ordinal operation; // get(Recipe_ordinal, name) vector ingredients; // only if !is_label vector products; // only if !is_label // End instruction Fields @@ -123,22 +123,22 @@ type_ordinal Next_type_ordinal = 1; :(code) void setup_types() { Type.clear(); Type_ordinal.clear(); - Type_ordinal["literal"] = 0; + put(Type_ordinal, "literal", 0); Next_type_ordinal = 1; // Mu Types Initialization - type_ordinal number = Type_ordinal["number"] = Next_type_ordinal++; - Type_ordinal["location"] = Type_ordinal["number"]; // wildcard type: either a pointer or a scalar - Type[number].name = "number"; - type_ordinal address = Type_ordinal["address"] = Next_type_ordinal++; - Type[address].name = "address"; - type_ordinal boolean = Type_ordinal["boolean"] = Next_type_ordinal++; - Type[boolean].name = "boolean"; - type_ordinal character = Type_ordinal["character"] = Next_type_ordinal++; - Type[character].name = "character"; + type_ordinal number = put(Type_ordinal, "number", Next_type_ordinal++); + put(Type_ordinal, "location", get(Type_ordinal, "number")); // wildcard type: either a pointer or a scalar + get(Type, number).name = "number"; + type_ordinal address = put(Type_ordinal, "address", Next_type_ordinal++); + get(Type, address).name = "address"; + type_ordinal boolean = put(Type_ordinal, "boolean", Next_type_ordinal++); + get(Type, boolean).name = "boolean"; + type_ordinal character = put(Type_ordinal, "character", Next_type_ordinal++); + get(Type, character).name = "character"; // Array types are a special modifier to any other type. For example, // array:number or array:address:boolean. - type_ordinal array = Type_ordinal["array"] = Next_type_ordinal++; - Type[array].name = "array"; + type_ordinal array = put(Type_ordinal, "array", Next_type_ordinal++); + get(Type, array).name = "array"; // End Mu Types Initialization } void teardown_types() { @@ -196,9 +196,9 @@ enum primitive_recipes { //: what to do for them. void setup_recipes() { Recipe.clear(); Recipe_ordinal.clear(); - Recipe_ordinal["idle"] = IDLE; + put(Recipe_ordinal, "idle", IDLE); // Primitive Recipe Numbers - Recipe_ordinal["copy"] = COPY; + put(Recipe_ordinal, "copy", COPY); // End Primitive Recipe Numbers } //: We could just reset the recipe table after every test, but that gets slow @@ -209,7 +209,7 @@ void setup_recipes() { setup_recipes(); assert(MAX_PRIMITIVE_RECIPES < 200); // level 0 is primitives; until 199 Next_recipe_ordinal = 200; -Recipe_ordinal["main"] = Next_recipe_ordinal++; +put(Recipe_ordinal, "main", Next_recipe_ordinal++); // End Load Recipes :(before "End Test Run Initialization") assert(Next_recipe_ordinal < 1000); // recipes being tested didn't overflow into test space @@ -276,9 +276,9 @@ type_tree* new_type_tree(const string_tree* properties) { if (Type_ordinal.find(type_name) == Type_ordinal.end() // types can contain integers, like for array sizes && !is_integer(type_name)) { - Type_ordinal[type_name] = Next_type_ordinal++; + put(Type_ordinal, type_name, Next_type_ordinal++); } - result->value = Type_ordinal[type_name]; + result->value = get(Type_ordinal, type_name); } result->left = new_type_tree(properties->left); result->right = new_type_tree(properties->right); @@ -414,7 +414,7 @@ void dump_types_tree(const type_tree* type, ostream& out) { void dump_type_name(recipe_ordinal type, ostream& out) { if (Type.find(type) != Type.end()) - out << Type[type].name; + out << get(Type, type).name; else out << "?"; } @@ -470,7 +470,7 @@ void dump_memory() { } void dump_recipe(const string& recipe_name) { - const recipe& r = Recipe[Recipe_ordinal[recipe_name]]; + const recipe& r = get(Recipe, get(Recipe_ordinal, recipe_name)); cout << "recipe " << r.name << " [\n"; for (long long int i = 0; i < SIZE(r.steps); ++i) { cout << " " << r.steps.at(i).to_string() << '\n'; diff --git a/011load.cc b/011load.cc index 10fe3817..d7150335 100644 --- a/011load.cc +++ b/011load.cc @@ -48,20 +48,20 @@ long long int slurp_recipe(istream& in) { raise_error << "empty result.name\n" << end(); trace(9991, "parse") << "--- defining " << result.name << end(); if (Recipe_ordinal.find(result.name) == Recipe_ordinal.end()) { - Recipe_ordinal[result.name] = Next_recipe_ordinal++; + put(Recipe_ordinal, result.name, Next_recipe_ordinal++); } - if (Recipe.find(Recipe_ordinal[result.name]) != Recipe.end()) { + if (Recipe.find(get(Recipe_ordinal, result.name)) != Recipe.end()) { trace(9991, "parse") << "already exists" << end(); if (warn_on_redefine(result.name)) raise << "redefining recipe " << result.name << "\n" << end(); - Recipe.erase(Recipe_ordinal[result.name]); + Recipe.erase(get(Recipe_ordinal, result.name)); } slurp_body(in, result); // End recipe Body(result) - Recipe[Recipe_ordinal[result.name]] = result; + get(Recipe, get(Recipe_ordinal, result.name)) = result; // track added recipes because we may need to undo them in tests; see below - recently_added_recipes.push_back(Recipe_ordinal[result.name]); - return Recipe_ordinal[result.name]; + recently_added_recipes.push_back(get(Recipe_ordinal, result.name)); + return get(Recipe_ordinal, result.name); } void slurp_body(istream& in, recipe& result) { @@ -243,7 +243,7 @@ long long int Reserved_for_tests = 1000; :(before "End Setup") for (long long int i = 0; i < SIZE(recently_added_recipes); ++i) { if (recently_added_recipes.at(i) >= Reserved_for_tests) // don't renumber existing recipes, like 'interactive' - Recipe_ordinal.erase(Recipe[recently_added_recipes.at(i)].name); + Recipe_ordinal.erase(get(Recipe, recently_added_recipes.at(i)).name); Recipe.erase(recently_added_recipes.at(i)); } // Clear Other State For recently_added_recipes diff --git a/013update_operation.cc b/013update_operation.cc index 8ff8d628..13c7a3ad 100644 --- a/013update_operation.cc +++ b/013update_operation.cc @@ -6,15 +6,15 @@ Transform.push_back(update_instruction_operations); :(code) void update_instruction_operations(recipe_ordinal r) { - trace(9991, "transform") << "--- compute instruction operations for recipe " << Recipe[r].name << end(); - for (long long int index = 0; index < SIZE(Recipe[r].steps); ++index) { - instruction& inst = Recipe[r].steps.at(index); + trace(9991, "transform") << "--- compute instruction operations for recipe " << get(Recipe, r).name << end(); + for (long long int index = 0; index < SIZE(get(Recipe, r).steps); ++index) { + instruction& inst = get(Recipe, r).steps.at(index); if (inst.is_label) continue; if (Recipe_ordinal.find(inst.name) == Recipe_ordinal.end()) { - raise_error << maybe(Recipe[r].name) << "instruction " << inst.name << " has no recipe\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "instruction " << inst.name << " has no recipe\n" << end(); return; } - inst.operation = Recipe_ordinal[inst.name]; + inst.operation = get(Recipe_ordinal, inst.name); } } diff --git a/014literal_string.cc b/014literal_string.cc index 99e7c097..ce545547 100644 --- a/014literal_string.cc +++ b/014literal_string.cc @@ -19,7 +19,7 @@ recipe main [ +parse: ingredient: {"abc:def/ghi": "literal-string"} :(before "End Mu Types Initialization") -Type_ordinal["literal-string"] = 0; +put(Type_ordinal, "literal-string", 0); :(before "End next_word Special-cases") if (in.peek() == '[') { diff --git a/020run.cc b/020run.cc index 24a0a863..42b11fc2 100644 --- a/020run.cc +++ b/020run.cc @@ -63,9 +63,9 @@ void run_current_routine() //? Instructions_running[current_recipe_name()]++; if (current_instruction().is_label) { ++current_step_index(); continue; } trace(Initial_callstack_depth + Trace_stream->callstack_depth, "run") << current_instruction().to_string() << end(); - if (Memory[0] != 0) { + if (get_or_insert(Memory, 0) != 0) { raise_error << "something wrote to location 0; this should never happen\n" << end(); - Memory[0] = 0; + put(Memory, 0, 0); } // Read all ingredients from memory. // Each ingredient loads a vector of values rather than a single value; mu @@ -119,15 +119,15 @@ inline long long int& current_step_index() { } inline const string& current_recipe_name() { - return Recipe[Current_routine->running_recipe].name; + return get(Recipe, Current_routine->running_recipe).name; } inline const instruction& current_instruction() { - return Recipe[Current_routine->running_recipe].steps.at(Current_routine->running_step_index); + return get(Recipe, Current_routine->running_recipe).steps.at(Current_routine->running_step_index); } inline bool routine::completed() const { - return running_step_index >= SIZE(Recipe[running_recipe].steps); + return running_step_index >= SIZE(get(Recipe, running_recipe).steps); } //:: Startup flow @@ -154,7 +154,7 @@ if (argc > 1) { } transform_all(); //? dump_recipe("handle-keyboard-event"), exit(0); - if (Run_tests) Recipe.erase(Recipe_ordinal[string("main")]); + if (Run_tests) Recipe.erase(get(Recipe_ordinal, string("main"))); } //: Step 3: if we aren't running tests, locate a recipe called 'main' and @@ -171,7 +171,7 @@ if (!Run_tests) { :(code) void run_main(int argc, char* argv[]) { - recipe_ordinal r = Recipe_ordinal[string("main")]; + recipe_ordinal r = get(Recipe_ordinal, string("main")); if (r) run(r); } @@ -258,7 +258,7 @@ vector read_memory(reagent x) { long long int base = x.value; long long int size = size_of(x); for (long long int offset = 0; offset < size; ++offset) { - double val = Memory[base+offset]; + double val = get_or_insert(Memory, base+offset); trace(9999, "mem") << "location " << base+offset << " is " << no_scientific(val) << end(); result.push_back(val); } @@ -276,7 +276,7 @@ void write_memory(reagent x, vector data) { for (long long int offset = 0; offset < SIZE(data); ++offset) { if (base+offset == 0) continue; trace(9999, "mem") << "storing " << no_scientific(data.at(offset)) << " in location " << base+offset << end(); - Memory[base+offset] = data.at(offset); + put(Memory, base+offset, data.at(offset)); } } diff --git a/021check_instruction.cc b/021check_instruction.cc index d0efd2a2..3c44f36a 100644 --- a/021check_instruction.cc +++ b/021check_instruction.cc @@ -13,10 +13,10 @@ Transform.push_back(check_instruction); :(code) void check_instruction(const recipe_ordinal r) { - trace(9991, "transform") << "--- perform checks for recipe " << Recipe[r].name << end(); + trace(9991, "transform") << "--- perform checks for recipe " << get(Recipe, r).name << end(); map > metadata; - for (long long int i = 0; i < SIZE(Recipe[r].steps); ++i) { - instruction& inst = Recipe[r].steps.at(i); + for (long long int i = 0; i < SIZE(get(Recipe, r).steps); ++i) { + instruction& inst = get(Recipe, r).steps.at(i); if (inst.is_label) continue; switch (inst.operation) { // Primitive Recipe Checks @@ -27,7 +27,7 @@ void check_instruction(const recipe_ordinal r) { } for (long long int i = 0; i < SIZE(inst.ingredients); ++i) { if (!types_match(inst.products.at(i), inst.ingredients.at(i))) { - raise_error << maybe(Recipe[r].name) << "can't copy " << inst.ingredients.at(i).original_string << " to " << inst.products.at(i).original_string << "; types don't match\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "can't copy " << inst.ingredients.at(i).original_string << " to " << inst.products.at(i).original_string << "; types don't match\n" << end(); goto finish_checking_instruction; } } @@ -90,8 +90,8 @@ bool types_match(reagent lhs, reagent rhs) { bool types_match(type_tree* lhs, type_tree* rhs) { if (!lhs) return true; if (!rhs || rhs->value == 0) { - if (lhs->value == Type_ordinal["array"]) return false; - if (lhs->value == Type_ordinal["address"]) return false; + if (lhs->value == get(Type_ordinal, "array")) return false; + if (lhs->value == get(Type_ordinal, "address")) return false; return size_of(rhs) == size_of(lhs); } if (lhs->value != rhs->value) return false; @@ -102,8 +102,8 @@ bool types_match(type_tree* lhs, type_tree* rhs) { bool types_match(const reagent lhs, const type_tree* rhs, const vector& data) { if (is_dummy(lhs)) return true; if (rhs->value == 0) { - if (lhs.type->value == Type_ordinal["array"]) return false; - if (lhs.type->value == Type_ordinal["address"]) return scalar(data) && data.at(0) == 0; + if (lhs.type->value == get(Type_ordinal, "array")) return false; + if (lhs.type->value == get(Type_ordinal, "address")) return scalar(data) && data.at(0) == 0; return size_of(rhs) == size_of(lhs); } if (lhs.type->value != rhs->value) return false; @@ -117,13 +117,13 @@ bool is_raw(const reagent& r) { bool is_mu_array(reagent r) { if (!r.type) return false; if (is_literal(r)) return false; - return r.type->value == Type_ordinal["array"]; + return r.type->value == get(Type_ordinal, "array"); } bool is_mu_address(reagent r) { if (!r.type) return false; if (is_literal(r)) return false; - return r.type->value == Type_ordinal["address"]; + return r.type->value == get(Type_ordinal, "address"); } bool is_mu_number(reagent r) { @@ -131,8 +131,8 @@ bool is_mu_number(reagent r) { if (is_literal(r)) return r.properties.at(0).second->value == "literal-number" || r.properties.at(0).second->value == "literal"; - if (r.type->value == Type_ordinal["character"]) return true; // permit arithmetic on unicode code points - return r.type->value == Type_ordinal["number"]; + if (r.type->value == get(Type_ordinal, "character")) return true; // permit arithmetic on unicode code points + return r.type->value == get(Type_ordinal, "number"); } bool is_mu_scalar(reagent r) { diff --git a/022arithmetic.cc b/022arithmetic.cc index 817cd5f2..b16bc584 100644 --- a/022arithmetic.cc +++ b/022arithmetic.cc @@ -3,22 +3,22 @@ :(before "End Primitive Recipe Declarations") ADD, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["add"] = ADD; +put(Recipe_ordinal, "add", ADD); :(before "End Primitive Recipe Checks") case ADD: { // primary goal of these checks is to forbid address arithmetic for (long long int i = 0; i < SIZE(inst.ingredients); ++i) { if (!is_mu_number(inst.ingredients.at(i))) { - raise_error << maybe(Recipe[r].name) << "'add' requires number ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'add' requires number ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end(); goto finish_checking_instruction; } } if (SIZE(inst.products) > 1) { - raise_error << maybe(Recipe[r].name) << "'add' yields exactly one product in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'add' yields exactly one product in '" << inst.to_string() << "'\n" << end(); break; } if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) { - raise_error << maybe(Recipe[r].name) << "'add' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'add' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end(); break; } break; @@ -71,26 +71,26 @@ recipe main [ :(before "End Primitive Recipe Declarations") SUBTRACT, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["subtract"] = SUBTRACT; +put(Recipe_ordinal, "subtract", SUBTRACT); :(before "End Primitive Recipe Checks") case SUBTRACT: { if (inst.ingredients.empty()) { - raise_error << maybe(Recipe[r].name) << "'subtract' has no ingredients\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'subtract' has no ingredients\n" << end(); break; } for (long long int i = 0; i < SIZE(inst.ingredients); ++i) { if (is_raw(inst.ingredients.at(i))) continue; // permit address offset computations in tests if (!is_mu_number(inst.ingredients.at(i))) { - raise_error << maybe(Recipe[r].name) << "'subtract' requires number ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'subtract' requires number ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end(); goto finish_checking_instruction; } } if (SIZE(inst.products) > 1) { - raise_error << maybe(Recipe[r].name) << "'subtract' yields exactly one product in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'subtract' yields exactly one product in '" << inst.to_string() << "'\n" << end(); break; } if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) { - raise_error << maybe(Recipe[r].name) << "'subtract' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'subtract' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end(); break; } break; @@ -128,21 +128,21 @@ recipe main [ :(before "End Primitive Recipe Declarations") MULTIPLY, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["multiply"] = MULTIPLY; +put(Recipe_ordinal, "multiply", MULTIPLY); :(before "End Primitive Recipe Checks") case MULTIPLY: { for (long long int i = 0; i < SIZE(inst.ingredients); ++i) { if (!is_mu_number(inst.ingredients.at(i))) { - raise_error << maybe(Recipe[r].name) << "'multiply' requires number ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'multiply' requires number ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end(); goto finish_checking_instruction; } } if (SIZE(inst.products) > 1) { - raise_error << maybe(Recipe[r].name) << "'multiply' yields exactly one product in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'multiply' yields exactly one product in '" << inst.to_string() << "'\n" << end(); break; } if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) { - raise_error << maybe(Recipe[r].name) << "'multiply' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'multiply' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end(); break; } break; @@ -181,25 +181,25 @@ recipe main [ :(before "End Primitive Recipe Declarations") DIVIDE, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["divide"] = DIVIDE; +put(Recipe_ordinal, "divide", DIVIDE); :(before "End Primitive Recipe Checks") case DIVIDE: { if (inst.ingredients.empty()) { - raise_error << maybe(Recipe[r].name) << "'divide' has no ingredients\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'divide' has no ingredients\n" << end(); break; } for (long long int i = 0; i < SIZE(inst.ingredients); ++i) { if (!is_mu_number(inst.ingredients.at(i))) { - raise_error << maybe(Recipe[r].name) << "'divide' requires number ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'divide' requires number ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end(); goto finish_checking_instruction; } } if (SIZE(inst.products) > 1) { - raise_error << maybe(Recipe[r].name) << "'divide' yields exactly one product in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'divide' yields exactly one product in '" << inst.to_string() << "'\n" << end(); break; } if (!inst.products.empty() && !is_dummy(inst.products.at(0)) && !is_mu_number(inst.products.at(0))) { - raise_error << maybe(Recipe[r].name) << "'divide' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'divide' should yield a number, but got " << inst.products.at(0).original_string << '\n' << end(); break; } break; @@ -239,24 +239,24 @@ recipe main [ :(before "End Primitive Recipe Declarations") DIVIDE_WITH_REMAINDER, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["divide-with-remainder"] = DIVIDE_WITH_REMAINDER; +put(Recipe_ordinal, "divide-with-remainder", DIVIDE_WITH_REMAINDER); :(before "End Primitive Recipe Checks") case DIVIDE_WITH_REMAINDER: { if (SIZE(inst.ingredients) != 2) { - raise_error << maybe(Recipe[r].name) << "'divide-with-remainder' requires exactly two ingredients, but got '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'divide-with-remainder' requires exactly two ingredients, but got '" << inst.to_string() << "'\n" << end(); break; } if (!is_mu_number(inst.ingredients.at(0)) || !is_mu_number(inst.ingredients.at(1))) { - raise_error << maybe(Recipe[r].name) << "'divide-with-remainder' requires number ingredients, but got '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'divide-with-remainder' requires number ingredients, but got '" << inst.to_string() << "'\n" << end(); break; } if (SIZE(inst.products) > 2) { - raise_error << maybe(Recipe[r].name) << "'divide-with-remainder' yields two products in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'divide-with-remainder' yields two products in '" << inst.to_string() << "'\n" << end(); break; } for (long long int i = 0; i < SIZE(inst.products); ++i) { if (!is_dummy(inst.products.at(i)) && !is_mu_number(inst.products.at(i))) { - raise_error << maybe(Recipe[r].name) << "'divide-with-remainder' should yield a number, but got " << inst.products.at(i).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'divide-with-remainder' should yield a number, but got " << inst.products.at(i).original_string << '\n' << end(); goto finish_checking_instruction; } } diff --git a/023boolean.cc b/023boolean.cc index 49683455..13400c4c 100644 --- a/023boolean.cc +++ b/023boolean.cc @@ -3,12 +3,12 @@ :(before "End Primitive Recipe Declarations") AND, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["and"] = AND; +put(Recipe_ordinal, "and", AND); :(before "End Primitive Recipe Checks") case AND: { for (long long int i = 0; i < SIZE(inst.ingredients); ++i) { if (!is_mu_scalar(inst.ingredients.at(i))) { - raise_error << maybe(Recipe[r].name) << "'and' requires boolean ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'and' requires boolean ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end(); goto finish_checking_instruction; } } @@ -53,12 +53,12 @@ recipe main [ :(before "End Primitive Recipe Declarations") OR, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["or"] = OR; +put(Recipe_ordinal, "or", OR); :(before "End Primitive Recipe Checks") case OR: { for (long long int i = 0; i < SIZE(inst.ingredients); ++i) { if (!is_mu_scalar(inst.ingredients.at(i))) { - raise_error << maybe(Recipe[r].name) << "'and' requires boolean ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'and' requires boolean ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end(); goto finish_checking_instruction; } } @@ -103,16 +103,16 @@ recipe main [ :(before "End Primitive Recipe Declarations") NOT, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["not"] = NOT; +put(Recipe_ordinal, "not", NOT); :(before "End Primitive Recipe Checks") case NOT: { if (SIZE(inst.products) > SIZE(inst.ingredients)) { - raise_error << maybe(Recipe[r].name) << "'not' cannot have fewer ingredients than products in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'not' cannot have fewer ingredients than products in '" << inst.to_string() << "'\n" << end(); break; } for (long long int i = 0; i < SIZE(inst.ingredients); ++i) { if (!is_mu_scalar(inst.ingredients.at(i))) { - raise_error << maybe(Recipe[r].name) << "'not' requires boolean ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'not' requires boolean ingredients, but got " << inst.ingredients.at(i).original_string << '\n' << end(); goto finish_checking_instruction; } } diff --git a/024jump.cc b/024jump.cc index 30d5381f..95e31c55 100644 --- a/024jump.cc +++ b/024jump.cc @@ -12,15 +12,15 @@ recipe main [ :(before "End Primitive Recipe Declarations") JUMP, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["jump"] = JUMP; +put(Recipe_ordinal, "jump", JUMP); :(before "End Primitive Recipe Checks") case JUMP: { if (SIZE(inst.ingredients) != 1) { - raise_error << maybe(Recipe[r].name) << "'jump' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'jump' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end(); break; } if (!is_mu_scalar(inst.ingredients.at(0))) { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'jump' should be a label or offset, but got " << inst.ingredients.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'jump' should be a label or offset, but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } break; @@ -35,7 +35,7 @@ case JUMP: { //: special type to designate jump targets :(before "End Mu Types Initialization") -Type_ordinal["offset"] = 0; +put(Type_ordinal, "offset", 0); :(scenario jump_backward) recipe main [ @@ -51,19 +51,19 @@ recipe main [ :(before "End Primitive Recipe Declarations") JUMP_IF, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["jump-if"] = JUMP_IF; +put(Recipe_ordinal, "jump-if", JUMP_IF); :(before "End Primitive Recipe Checks") case JUMP_IF: { if (SIZE(inst.ingredients) != 2) { - raise_error << maybe(Recipe[r].name) << "'jump-if' requires exactly two ingredients, but got " << inst.to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'jump-if' requires exactly two ingredients, but got " << inst.to_string() << '\n' << end(); break; } if (!is_mu_scalar(inst.ingredients.at(0))) { - raise_error << maybe(Recipe[r].name) << "'jump-if' requires a boolean for its first ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'jump-if' requires a boolean for its first ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } if (!is_mu_scalar(inst.ingredients.at(1))) { - raise_error << maybe(Recipe[r].name) << "'jump-if' requires a label or offset for its second ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'jump-if' requires a label or offset for its second ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } break; @@ -103,19 +103,19 @@ recipe main [ :(before "End Primitive Recipe Declarations") JUMP_UNLESS, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["jump-unless"] = JUMP_UNLESS; +put(Recipe_ordinal, "jump-unless", JUMP_UNLESS); :(before "End Primitive Recipe Checks") case JUMP_UNLESS: { if (SIZE(inst.ingredients) != 2) { - raise_error << maybe(Recipe[r].name) << "'jump-unless' requires exactly two ingredients, but got " << inst.to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'jump-unless' requires exactly two ingredients, but got " << inst.to_string() << '\n' << end(); break; } if (!is_mu_scalar(inst.ingredients.at(0))) { - raise_error << maybe(Recipe[r].name) << "'jump-unless' requires a boolean for its first ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'jump-unless' requires a boolean for its first ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } if (!is_mu_scalar(inst.ingredients.at(1))) { - raise_error << maybe(Recipe[r].name) << "'jump-unless' requires a label or offset for its second ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'jump-unless' requires a label or offset for its second ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } break; diff --git a/025compare.cc b/025compare.cc index f7acb64c..056c859d 100644 --- a/025compare.cc +++ b/025compare.cc @@ -3,11 +3,11 @@ :(before "End Primitive Recipe Declarations") EQUAL, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["equal"] = EQUAL; +put(Recipe_ordinal, "equal", EQUAL); :(before "End Primitive Recipe Checks") case EQUAL: { if (SIZE(inst.ingredients) <= 1) { - raise_error << maybe(Recipe[r].name) << "'equal' needs at least two ingredients to compare in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'equal' needs at least two ingredients to compare in '" << inst.to_string() << "'\n" << end(); break; } break; @@ -62,16 +62,16 @@ recipe main [ :(before "End Primitive Recipe Declarations") GREATER_THAN, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["greater-than"] = GREATER_THAN; +put(Recipe_ordinal, "greater-than", GREATER_THAN); :(before "End Primitive Recipe Checks") case GREATER_THAN: { if (SIZE(inst.ingredients) <= 1) { - raise_error << maybe(Recipe[r].name) << "'greater-than' needs at least two ingredients to compare in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'greater-than' needs at least two ingredients to compare in '" << inst.to_string() << "'\n" << end(); break; } for (long long int i = 0; i < SIZE(inst.ingredients); ++i) { if (!is_mu_number(inst.ingredients.at(i))) { - raise_error << maybe(Recipe[r].name) << "'greater-than' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'greater-than' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end(); goto finish_checking_instruction; } } @@ -121,16 +121,16 @@ recipe main [ :(before "End Primitive Recipe Declarations") LESSER_THAN, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["lesser-than"] = LESSER_THAN; +put(Recipe_ordinal, "lesser-than", LESSER_THAN); :(before "End Primitive Recipe Checks") case LESSER_THAN: { if (SIZE(inst.ingredients) <= 1) { - raise_error << maybe(Recipe[r].name) << "'lesser-than' needs at least two ingredients to compare in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'lesser-than' needs at least two ingredients to compare in '" << inst.to_string() << "'\n" << end(); break; } for (long long int i = 0; i < SIZE(inst.ingredients); ++i) { if (!is_mu_number(inst.ingredients.at(i))) { - raise_error << maybe(Recipe[r].name) << "'lesser-than' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'lesser-than' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end(); goto finish_checking_instruction; } } @@ -180,16 +180,16 @@ recipe main [ :(before "End Primitive Recipe Declarations") GREATER_OR_EQUAL, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["greater-or-equal"] = GREATER_OR_EQUAL; +put(Recipe_ordinal, "greater-or-equal", GREATER_OR_EQUAL); :(before "End Primitive Recipe Checks") case GREATER_OR_EQUAL: { if (SIZE(inst.ingredients) <= 1) { - raise_error << maybe(Recipe[r].name) << "'greater-or-equal' needs at least two ingredients to compare in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'greater-or-equal' needs at least two ingredients to compare in '" << inst.to_string() << "'\n" << end(); break; } for (long long int i = 0; i < SIZE(inst.ingredients); ++i) { if (!is_mu_number(inst.ingredients.at(i))) { - raise_error << maybe(Recipe[r].name) << "'greater-or-equal' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'greater-or-equal' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end(); goto finish_checking_instruction; } } @@ -247,16 +247,16 @@ recipe main [ :(before "End Primitive Recipe Declarations") LESSER_OR_EQUAL, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["lesser-or-equal"] = LESSER_OR_EQUAL; +put(Recipe_ordinal, "lesser-or-equal", LESSER_OR_EQUAL); :(before "End Primitive Recipe Checks") case LESSER_OR_EQUAL: { if (SIZE(inst.ingredients) <= 1) { - raise_error << maybe(Recipe[r].name) << "'lesser-or-equal' needs at least two ingredients to compare in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'lesser-or-equal' needs at least two ingredients to compare in '" << inst.to_string() << "'\n" << end(); break; } for (long long int i = 0; i < SIZE(inst.ingredients); ++i) { if (!is_mu_number(inst.ingredients.at(i))) { - raise_error << maybe(Recipe[r].name) << "'lesser-or-equal' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'lesser-or-equal' can only compare numbers; got " << inst.ingredients.at(i).original_string << '\n' << end(); goto finish_checking_instruction; } } diff --git a/029tools.cc b/029tools.cc index 2aa06f62..92f551b3 100644 --- a/029tools.cc +++ b/029tools.cc @@ -9,19 +9,19 @@ recipe main [ :(before "End Primitive Recipe Declarations") TRACE, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["trace"] = TRACE; +put(Recipe_ordinal, "trace", TRACE); :(before "End Primitive Recipe Checks") case TRACE: { if (SIZE(inst.ingredients) < 3) { - raise_error << maybe(Recipe[r].name) << "'trace' takes three or more ingredients rather than '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'trace' takes three or more ingredients rather than '" << inst.to_string() << "'\n" << end(); break; } if (!is_mu_number(inst.ingredients.at(0))) { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'trace' should be a number (depth), but got " << inst.ingredients.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'trace' should be a number (depth), but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } if (!is_literal_string(inst.ingredients.at(1))) { - raise_error << maybe(Recipe[r].name) << "second ingredient of 'trace' should be a literal string (label), but got " << inst.ingredients.at(1).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "second ingredient of 'trace' should be a literal string (label), but got " << inst.ingredients.at(1).original_string << '\n' << end(); break; } break; @@ -43,7 +43,7 @@ case TRACE: { :(before "End Primitive Recipe Declarations") STASH, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["stash"] = STASH; +put(Recipe_ordinal, "stash", STASH); :(before "End Primitive Recipe Checks") case STASH: { break; @@ -92,7 +92,7 @@ string print_mu(const reagent& r, const vector& data) { :(before "End Primitive Recipe Declarations") HIDE_ERRORS, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["hide-errors"] = HIDE_ERRORS; +put(Recipe_ordinal, "hide-errors", HIDE_ERRORS); :(before "End Primitive Recipe Checks") case HIDE_ERRORS: { break; @@ -107,7 +107,7 @@ case HIDE_ERRORS: { :(before "End Primitive Recipe Declarations") SHOW_ERRORS, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["show-errors"] = SHOW_ERRORS; +put(Recipe_ordinal, "show-errors", SHOW_ERRORS); :(before "End Primitive Recipe Checks") case SHOW_ERRORS: { break; @@ -122,7 +122,7 @@ case SHOW_ERRORS: { :(before "End Primitive Recipe Declarations") TRACE_UNTIL, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["trace-until"] = TRACE_UNTIL; +put(Recipe_ordinal, "trace-until", TRACE_UNTIL); :(before "End Primitive Recipe Checks") case TRACE_UNTIL: { break; @@ -138,7 +138,7 @@ case TRACE_UNTIL: { :(before "End Primitive Recipe Declarations") _DUMP_TRACE, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["$dump-trace"] = _DUMP_TRACE; +put(Recipe_ordinal, "$dump-trace", _DUMP_TRACE); :(before "End Primitive Recipe Checks") case _DUMP_TRACE: { break; @@ -157,7 +157,7 @@ case _DUMP_TRACE: { :(before "End Primitive Recipe Declarations") _CLEAR_TRACE, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["$clear-trace"] = _CLEAR_TRACE; +put(Recipe_ordinal, "$clear-trace", _CLEAR_TRACE); :(before "End Primitive Recipe Checks") case _CLEAR_TRACE: { break; @@ -171,7 +171,7 @@ case _CLEAR_TRACE: { :(before "End Primitive Recipe Declarations") _SAVE_TRACE, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["$save-trace"] = _SAVE_TRACE; +put(Recipe_ordinal, "$save-trace", _SAVE_TRACE); :(before "End Primitive Recipe Checks") case _SAVE_TRACE: { break; @@ -198,19 +198,19 @@ recipe main [ :(before "End Primitive Recipe Declarations") ASSERT, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["assert"] = ASSERT; +put(Recipe_ordinal, "assert", ASSERT); :(before "End Primitive Recipe Checks") case ASSERT: { if (SIZE(inst.ingredients) != 2) { - raise_error << maybe(Recipe[r].name) << "'assert' takes exactly two ingredients rather than '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'assert' takes exactly two ingredients rather than '" << inst.to_string() << "'\n" << end(); break; } if (!is_mu_scalar(inst.ingredients.at(0))) { - raise_error << maybe(Recipe[r].name) << "'assert' requires a boolean for its first ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'assert' requires a boolean for its first ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } if (!is_literal_string(inst.ingredients.at(1))) { - raise_error << maybe(Recipe[r].name) << "'assert' requires a literal string for its second ingredient, but got " << inst.ingredients.at(1).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'assert' requires a literal string for its second ingredient, but got " << inst.ingredients.at(1).original_string << '\n' << end(); break; } break; @@ -228,7 +228,7 @@ case ASSERT: { :(before "End Primitive Recipe Declarations") _PRINT, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["$print"] = _PRINT; +put(Recipe_ordinal, "$print", _PRINT); :(before "End Primitive Recipe Checks") case _PRINT: { break; @@ -257,7 +257,7 @@ case _PRINT: { :(before "End Primitive Recipe Declarations") _EXIT, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["$exit"] = _EXIT; +put(Recipe_ordinal, "$exit", _EXIT); :(before "End Primitive Recipe Checks") case _EXIT: { break; @@ -271,11 +271,11 @@ case _EXIT: { :(before "End Primitive Recipe Declarations") _SYSTEM, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["$system"] = _SYSTEM; +put(Recipe_ordinal, "$system", _SYSTEM); :(before "End Primitive Recipe Checks") case _SYSTEM: { if (SIZE(inst.ingredients) != 1) { - raise_error << maybe(Recipe[r].name) << "'$system' requires exactly one ingredient, but got none\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'$system' requires exactly one ingredient, but got none\n" << end(); break; } break; @@ -291,7 +291,7 @@ case _SYSTEM: { :(before "End Primitive Recipe Declarations") _DUMP_MEMORY, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["$dump-memory"] = _DUMP_MEMORY; +put(Recipe_ordinal, "$dump-memory", _DUMP_MEMORY); :(before "End Primitive Recipe Checks") case _DUMP_MEMORY: { break; diff --git a/030container.cc b/030container.cc index 9fde367e..05483cf4 100644 --- a/030container.cc +++ b/030container.cc @@ -2,14 +2,14 @@ :(before "End Mu Types Initialization") //: We'll use this container as a running example, with two number elements. -type_ordinal point = Type_ordinal["point"] = Next_type_ordinal++; -Type[point].size = 2; -Type[point].kind = CONTAINER; -Type[point].name = "point"; -Type[point].elements.push_back(new type_tree(number)); -Type[point].element_names.push_back("x"); -Type[point].elements.push_back(new type_tree(number)); -Type[point].element_names.push_back("y"); +type_ordinal point = put(Type_ordinal, "point", Next_type_ordinal++); +get(Type, point).size = 2; +get(Type, point).kind = CONTAINER; +get(Type, point).name = "point"; +get(Type, point).elements.push_back(new type_tree(number)); +get(Type, point).element_names.push_back("x"); +get(Type, point).elements.push_back(new type_tree(number)); +get(Type, point).element_names.push_back("y"); //: Containers can be copied around with a single instruction just like //: numbers, no matter how large they are. @@ -37,14 +37,14 @@ recipe main [ :(before "End Mu Types Initialization") // A more complex container, containing another container as one of its // elements. -type_ordinal point_number = Type_ordinal["point-number"] = Next_type_ordinal++; -Type[point_number].size = 2; -Type[point_number].kind = CONTAINER; -Type[point_number].name = "point-number"; -Type[point_number].elements.push_back(new type_tree(point)); -Type[point_number].element_names.push_back("xy"); -Type[point_number].elements.push_back(new type_tree(number)); -Type[point_number].element_names.push_back("z"); +type_ordinal point_number = put(Type_ordinal, "point-number", Next_type_ordinal++); +get(Type, point_number).size = 2; +get(Type, point_number).kind = CONTAINER; +get(Type, point_number).name = "point-number"; +get(Type, point_number).elements.push_back(new type_tree(point)); +get(Type, point_number).element_names.push_back("xy"); +get(Type, point_number).elements.push_back(new type_tree(number)); +get(Type, point_number).element_names.push_back("z"); :(scenario copy_handles_nested_container_elements) recipe main [ @@ -87,7 +87,7 @@ if (type->value == 0) { assert(!type->left && !type->right); return 1; } -type_info t = Type[type->value]; +type_info t = get(Type, type->value); if (t.kind == CONTAINER) { // size of a container is the sum of the sizes of its elements long long int result = 0; @@ -124,23 +124,23 @@ recipe main [ :(before "End Primitive Recipe Declarations") GET, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["get"] = GET; +put(Recipe_ordinal, "get", GET); :(before "End Primitive Recipe Checks") case GET: { if (SIZE(inst.ingredients) != 2) { - raise_error << maybe(Recipe[r].name) << "'get' expects exactly 2 ingredients in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'get' expects exactly 2 ingredients in '" << inst.to_string() << "'\n" << end(); break; } reagent base = inst.ingredients.at(0); // new copy for every invocation // Update GET base in Check - if (!base.type || !base.type->value || Type[base.type->value].kind != CONTAINER) { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'get' should be a container, but got " << inst.ingredients.at(0).original_string << '\n' << end(); + if (!base.type || !base.type->value || get(Type, base.type->value).kind != CONTAINER) { + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'get' should be a container, but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } type_ordinal base_type = base.type->value; reagent offset = inst.ingredients.at(1); if (!is_literal(offset) || !is_mu_scalar(offset)) { - raise_error << maybe(Recipe[r].name) << "second ingredient of 'get' should have type 'offset', but got " << inst.ingredients.at(1).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "second ingredient of 'get' should have type 'offset', but got " << inst.ingredients.at(1).original_string << '\n' << end(); break; } long long int offset_value = 0; @@ -148,15 +148,15 @@ case GET: { offset_value = to_integer(offset.name); else offset_value = offset.value; - if (offset_value < 0 || offset_value >= SIZE(Type[base_type].elements)) { - raise_error << maybe(Recipe[r].name) << "invalid offset " << offset_value << " for " << Type[base_type].name << '\n' << end(); + if (offset_value < 0 || offset_value >= SIZE(get(Type, base_type).elements)) { + raise_error << maybe(get(Recipe, r).name) << "invalid offset " << offset_value << " for " << Type[base_type].name << '\n' << end(); break; } reagent product = inst.products.at(0); // Update GET product in Check const reagent element = element_type(base, offset_value); if (!types_match(product, element)) { - raise_error << maybe(Recipe[r].name) << "'get' " << offset.original_string << " (" << offset_value << ") on " << Type[base_type].name << " can't be saved in " << product.original_string << "; type should be " << dump_types(element) << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'get' " << offset.original_string << " (" << offset_value << ") on " << Type[base_type].name << " can't be saved in " << product.original_string << "; type should be " << dump_types(element) << '\n' << end(); break; } break; @@ -172,11 +172,11 @@ case GET: { } type_ordinal base_type = base.type->value; long long int offset = ingredients.at(1).at(0); - if (offset < 0 || offset >= SIZE(Type[base_type].elements)) break; // copied from Check above + if (offset < 0 || offset >= SIZE(get(Type, base_type).elements)) break; // copied from Check above long long int src = base_address; for (long long int i = 0; i < offset; ++i) { // End GET field Cases - src += size_of(Type[base_type].elements.at(i)); + src += size_of(get(Type, base_type).elements.at(i)); } trace(9998, "run") << "address to copy is " << src << end(); reagent tmp = element_type(base, offset); @@ -190,8 +190,8 @@ case GET: { const reagent element_type(const reagent& canonized_base, long long int offset_value) { assert(offset_value >= 0); assert(Type.find(canonized_base.type->value) != Type.end()); - assert(!Type[canonized_base.type->value].name.empty()); - const type_info& info = Type[canonized_base.type->value]; + assert(!get(Type, canonized_base.type->value).name.empty()); + const type_info& info = get(Type, canonized_base.type->value); assert(info.kind == CONTAINER); reagent element; element.type = new type_tree(*info.elements.at(offset_value)); @@ -251,30 +251,30 @@ recipe main [ :(before "End Primitive Recipe Declarations") GET_ADDRESS, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["get-address"] = GET_ADDRESS; +put(Recipe_ordinal, "get-address", GET_ADDRESS); :(before "End Primitive Recipe Checks") case GET_ADDRESS: { if (SIZE(inst.ingredients) != 2) { - raise_error << maybe(Recipe[r].name) << "'get-address' expects exactly 2 ingredients in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'get-address' expects exactly 2 ingredients in '" << inst.to_string() << "'\n" << end(); break; } reagent base = inst.ingredients.at(0); // Update GET_ADDRESS base in Check - if (!base.type || Type[base.type->value].kind != CONTAINER) { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'get-address' should be a container, but got " << inst.ingredients.at(0).original_string << '\n' << end(); + if (!base.type || get(Type, base.type->value).kind != CONTAINER) { + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'get-address' should be a container, but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } type_ordinal base_type = base.type->value; reagent offset = inst.ingredients.at(1); if (!is_literal(offset) || !is_mu_scalar(offset)) { - raise_error << maybe(Recipe[r].name) << "second ingredient of 'get' should have type 'offset', but got " << inst.ingredients.at(1).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "second ingredient of 'get' should have type 'offset', but got " << inst.ingredients.at(1).original_string << '\n' << end(); break; } long long int offset_value = 0; if (is_integer(offset.name)) { // later layers permit non-integer offsets offset_value = to_integer(offset.name); - if (offset_value < 0 || offset_value >= SIZE(Type[base_type].elements)) { - raise_error << maybe(Recipe[r].name) << "invalid offset " << offset_value << " for " << Type[base_type].name << '\n' << end(); + if (offset_value < 0 || offset_value >= SIZE(get(Type, base_type).elements)) { + raise_error << maybe(get(Recipe, r).name) << "invalid offset " << offset_value << " for " << Type[base_type].name << '\n' << end(); break; } } @@ -286,9 +286,9 @@ case GET_ADDRESS: { // same type as for GET.. reagent element = element_type(base, offset_value); // ..except for an address at the start - element.type = new type_tree(Type_ordinal["address"], element.type); + element.type = new type_tree(get(Type_ordinal, "address"), element.type); if (!types_match(product, element)) { - raise_error << maybe(Recipe[r].name) << "'get-address' " << offset.original_string << " (" << offset_value << ") on " << Type[base_type].name << " can't be saved in " << product.original_string << "; type should be " << dump_types(element) << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'get-address' " << offset.original_string << " (" << offset_value << ") on " << Type[base_type].name << " can't be saved in " << product.original_string << "; type should be " << dump_types(element) << '\n' << end(); break; } break; @@ -304,11 +304,11 @@ case GET_ADDRESS: { } type_ordinal base_type = base.type->value; long long int offset = ingredients.at(1).at(0); - if (offset < 0 || offset >= SIZE(Type[base_type].elements)) break; // copied from Check above + if (offset < 0 || offset >= SIZE(get(Type, base_type).elements)) break; // copied from Check above long long int result = base_address; for (long long int i = 0; i < offset; ++i) { // End GET_ADDRESS field Cases - result += size_of(Type[base_type].elements.at(i)); + result += size_of(get(Type, base_type).elements.at(i)); } trace(9998, "run") << "address to copy is " << result << end(); products.resize(1); @@ -391,13 +391,13 @@ void insert_container(const string& command, kind_of_type kind, istream& in) { // End container Name Refinements trace(9991, "parse") << "--- defining " << command << ' ' << name << end(); if (Type_ordinal.find(name) == Type_ordinal.end() - || Type_ordinal[name] == 0) { - Type_ordinal[name] = Next_type_ordinal++; + || get(Type_ordinal, name) == 0) { + put(Type_ordinal, name, Next_type_ordinal++); } - trace(9999, "parse") << "type number: " << Type_ordinal[name] << end(); + trace(9999, "parse") << "type number: " << get(Type_ordinal, name) << end(); skip_bracket(in, "'container' must begin with '['"); - type_info& info = Type[Type_ordinal[name]]; - recently_added_types.push_back(Type_ordinal[name]); + type_info& info = get(Type, get(Type_ordinal, name)); + recently_added_types.push_back(get(Type_ordinal, name)); info.name = name; info.kind = kind; while (!in.eof()) { @@ -415,10 +415,10 @@ void insert_container(const string& command, kind_of_type kind, istream& in) { if (Type_ordinal.find(type_name) == Type_ordinal.end() // types can contain integers, like for array sizes && !is_integer(type_name)) { - Type_ordinal[type_name] = Next_type_ordinal++; + put(Type_ordinal, type_name, Next_type_ordinal++); } - *curr_type = new type_tree(Type_ordinal[type_name]); - trace(9993, "parse") << " type: " << Type_ordinal[type_name] << end(); + *curr_type = new type_tree(get(Type_ordinal, type_name)); + trace(9993, "parse") << " type: " << get(Type_ordinal, type_name) << end(); } info.elements.push_back(new_type); } @@ -458,7 +458,7 @@ vector recently_added_types; recently_added_types.clear(); :(before "End Setup") //: for tests for (long long int i = 0; i < SIZE(recently_added_types); ++i) { - Type_ordinal.erase(Type[recently_added_types.at(i)].name); + Type_ordinal.erase(get(Type, recently_added_types.at(i)).name); // todo: why do I explicitly need to provide this? for (long long int j = 0; j < SIZE(Type.at(recently_added_types.at(i)).elements); ++j) { delete Type.at(recently_added_types.at(i)).elements.at(j); @@ -516,13 +516,13 @@ Transform.push_back(check_invalid_types); :(code) void check_invalid_types(const recipe_ordinal r) { - for (long long int index = 0; index < SIZE(Recipe[r].steps); ++index) { - const instruction& inst = Recipe[r].steps.at(index); + for (long long int index = 0; index < SIZE(get(Recipe, r).steps); ++index) { + const instruction& inst = get(Recipe, r).steps.at(index); for (long long int i = 0; i < SIZE(inst.ingredients); ++i) { - check_invalid_types(inst.ingredients.at(i).type, maybe(Recipe[r].name), "'"+inst.to_string()+"'"); + check_invalid_types(inst.ingredients.at(i).type, maybe(get(Recipe, r).name), "'"+inst.to_string()+"'"); } for (long long int i = 0; i < SIZE(inst.products); ++i) { - check_invalid_types(inst.products.at(i).type, maybe(Recipe[r].name), "'"+inst.to_string()+"'"); + check_invalid_types(inst.products.at(i).type, maybe(get(Recipe, r).name), "'"+inst.to_string()+"'"); } } } @@ -530,7 +530,7 @@ void check_invalid_types(const recipe_ordinal r) { void check_invalid_types(const type_tree* type, const string& block, const string& name) { if (!type) return; // will throw a more precise error elsewhere // End Container Type Checks - if (type->value && (Type.find(type->value) == Type.end() || Type[type->value].name.empty())) { + if (type->value && (Type.find(type->value) == Type.end() || get(Type, type->value).name.empty())) { raise_error << block << "unknown type in " << name << '\n' << end(); } if (type->left) check_invalid_types(type->left, block, name); @@ -576,7 +576,7 @@ void check_container_field_types() { :(before "End Primitive Recipe Declarations") MERGE, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["merge"] = MERGE; +put(Recipe_ordinal, "merge", MERGE); :(before "End Primitive Recipe Checks") case MERGE: { break; diff --git a/031address.cc b/031address.cc index 2478de03..306621f1 100644 --- a/031address.cc +++ b/031address.cc @@ -48,15 +48,15 @@ void canonize(reagent& x) { } void lookup_memory(reagent& x) { - if (!x.type || x.type->value != Type_ordinal["address"]) { + if (!x.type || x.type->value != get(Type_ordinal, "address")) { raise_error << maybe(current_recipe_name()) << "tried to /lookup " << x.original_string << " but it isn't an address\n" << end(); } // compute value if (x.value == 0) { raise_error << maybe(current_recipe_name()) << "tried to /lookup 0\n" << end(); } - trace(9999, "mem") << "location " << x.value << " is " << no_scientific(Memory[x.value]) << end(); - x.set_value(Memory[x.value]); + trace(9999, "mem") << "location " << x.value << " is " << no_scientific(get_or_insert(Memory, x.value)) << end(); + x.set_value(get_or_insert(Memory, x.value)); drop_address_from_type(x); drop_one_lookup(x); } @@ -77,7 +77,7 @@ void lookup_memory(reagent& x) { :(code) bool canonize_type(reagent& r) { while (has_property(r, "lookup")) { - if (!r.type || r.type->value != Type_ordinal["address"]) { + if (!r.type || r.type->value != get(Type_ordinal, "address")) { raise_error << "can't lookup non-address: " << r.original_string << '\n' << end(); return false; } @@ -184,12 +184,12 @@ recipe main [ :(before "End Primitive Recipe Declarations") _DUMP, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["$dump"] = _DUMP; +put(Recipe_ordinal, "$dump", _DUMP); :(before "End Primitive Recipe Implementations") case _DUMP: { reagent after_canonize = current_instruction().ingredients.at(0); canonize(after_canonize); - cerr << maybe(current_recipe_name()) << current_instruction().ingredients.at(0).name << ' ' << no_scientific(current_instruction().ingredients.at(0).value) << " => " << no_scientific(after_canonize.value) << " => " << no_scientific(Memory[after_canonize.value]) << '\n'; + cerr << maybe(current_recipe_name()) << current_instruction().ingredients.at(0).name << ' ' << no_scientific(current_instruction().ingredients.at(0).value) << " => " << no_scientific(after_canonize.value) << " => " << no_scientific(get_or_insert(Memory, after_canonize.value)) << '\n'; break; } @@ -200,11 +200,11 @@ long long int foo = -1; :(before "End Primitive Recipe Declarations") _FOO, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["$foo"] = _FOO; +put(Recipe_ordinal, "$foo", _FOO); :(before "End Primitive Recipe Implementations") case _FOO: { if (current_instruction().ingredients.empty()) { - if (foo != -1) cerr << foo << ": " << no_scientific(Memory[foo]) << '\n'; + if (foo != -1) cerr << foo << ": " << no_scientific(get_or_insert(Memory, foo)) << '\n'; else cerr << '\n'; } else { diff --git a/032array.cc b/032array.cc index 38b333b5..e2bc4ae2 100644 --- a/032array.cc +++ b/032array.cc @@ -16,30 +16,30 @@ recipe main [ :(before "End Primitive Recipe Declarations") CREATE_ARRAY, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["create-array"] = CREATE_ARRAY; +put(Recipe_ordinal, "create-array", CREATE_ARRAY); :(before "End Primitive Recipe Checks") case CREATE_ARRAY: { if (inst.products.empty()) { - raise_error << maybe(Recipe[r].name) << "'create-array' needs one product and no ingredients but got '" << inst.to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'create-array' needs one product and no ingredients but got '" << inst.to_string() << '\n' << end(); break; } reagent product = inst.products.at(0); canonize_type(product); if (!is_mu_array(product)) { - raise_error << maybe(Recipe[r].name) << "'create-array' cannot create non-array " << product.original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'create-array' cannot create non-array " << product.original_string << '\n' << end(); break; } if (!product.type->right) { - raise_error << maybe(Recipe[r].name) << "create array of what? " << inst.to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "create array of what? " << inst.to_string() << '\n' << end(); break; } // 'create-array' will need to check properties rather than types if (!product.properties.at(0).second || !product.properties.at(0).second->right || !product.properties.at(0).second->right->right) { - raise_error << maybe(Recipe[r].name) << "create array of what size? " << inst.to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "create array of what size? " << inst.to_string() << '\n' << end(); break; } if (!is_integer(product.properties.at(0).second->right->right->value)) { - raise_error << maybe(Recipe[r].name) << "'create-array' product should specify size of array after its element type, but got " << product.properties.at(0).second->right->right->value << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'create-array' product should specify size of array after its element type, but got " << product.properties.at(0).second->right->right->value << '\n' << end(); break; } break; @@ -51,12 +51,12 @@ case CREATE_ARRAY: { long long int base_address = product.value; long long int array_size = to_integer(product.properties.at(0).second->right->right->value); // initialize array size, so that size_of will work - Memory[base_address] = array_size; // in array elements + put(Memory, base_address, array_size); // in array elements long long int size = size_of(product); // in locations trace(9998, "run") << "creating array of size " << size << '\n' << end(); // initialize array for (long long int i = 1; i <= size_of(product); ++i) { - Memory[base_address+i] = 0; + put(Memory, base_address+i, 0); } // dummy product; doesn't actually do anything products.resize(1); @@ -105,15 +105,15 @@ recipe main [ //: disable the size mismatch check since the destination array need not be initialized :(before "End size_mismatch(x) Cases") -if (x.type && x.type->value == Type_ordinal["array"]) return false; +if (x.type && x.type->value == get(Type_ordinal, "array")) return false; :(before "End size_of(reagent) Cases") -if (r.type && r.type->value == Type_ordinal["array"]) { +if (r.type && r.type->value == get(Type_ordinal, "array")) { if (!r.type->right) { raise_error << maybe(current_recipe_name()) << "'" << r.original_string << "' is an array of what?\n" << end(); return 1; } // skip the 'array' type to get at the element type - return 1 + Memory[r.value]*size_of(array_element(r.type)); + return 1 + get_or_insert(Memory, r.value)*size_of(array_element(r.type)); } //:: To access elements of an array, use 'index' @@ -142,17 +142,17 @@ recipe main [ :(before "End Primitive Recipe Declarations") INDEX, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["index"] = INDEX; +put(Recipe_ordinal, "index", INDEX); :(before "End Primitive Recipe Checks") case INDEX: { if (SIZE(inst.ingredients) != 2) { - raise_error << maybe(Recipe[r].name) << "'index' expects exactly 2 ingredients in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'index' expects exactly 2 ingredients in '" << inst.to_string() << "'\n" << end(); break; } reagent base = inst.ingredients.at(0); canonize_type(base); if (!is_mu_array(base)) { - raise_error << maybe(Recipe[r].name) << "'index' on a non-array " << base.original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'index' on a non-array " << base.original_string << '\n' << end(); break; } if (inst.products.empty()) break; @@ -161,7 +161,7 @@ case INDEX: { reagent element; element.type = new type_tree(*array_element(base.type)); if (!types_match(product, element)) { - raise_error << maybe(Recipe[r].name) << "'index' on " << base.original_string << " can't be saved in " << product.original_string << "; type should be " << dump_types(element) << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'index' on " << base.original_string << " can't be saved in " << product.original_string << "; type should be " << dump_types(element) << '\n' << end(); break; } break; @@ -179,13 +179,13 @@ case INDEX: { canonize(offset); vector offset_val(read_memory(offset)); type_tree* element_type = array_element(base.type); - if (offset_val.at(0) < 0 || offset_val.at(0) >= Memory[base_address]) { + if (offset_val.at(0) < 0 || offset_val.at(0) >= get_or_insert(Memory, base_address)) { raise_error << maybe(current_recipe_name()) << "invalid index " << no_scientific(offset_val.at(0)) << '\n' << end(); break; } long long int src = base_address + 1 + offset_val.at(0)*size_of(element_type); trace(9998, "run") << "address to copy is " << src << end(); - trace(9998, "run") << "its type is " << Type[element_type->value].name << end(); + trace(9998, "run") << "its type is " << get(Type, element_type->value).name << end(); reagent tmp; tmp.set_value(src); tmp.type = new type_tree(*element_type); @@ -269,17 +269,17 @@ recipe main [ :(before "End Primitive Recipe Declarations") INDEX_ADDRESS, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["index-address"] = INDEX_ADDRESS; +put(Recipe_ordinal, "index-address", INDEX_ADDRESS); :(before "End Primitive Recipe Checks") case INDEX_ADDRESS: { if (SIZE(inst.ingredients) != 2) { - raise_error << maybe(Recipe[r].name) << "'index-address' expects exactly 2 ingredients in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'index-address' expects exactly 2 ingredients in '" << inst.to_string() << "'\n" << end(); break; } reagent base = inst.ingredients.at(0); canonize_type(base); if (!is_mu_array(base)) { - raise_error << maybe(Recipe[r].name) << "'index-address' on a non-array " << base.original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'index-address' on a non-array " << base.original_string << '\n' << end(); break; } if (inst.products.empty()) break; @@ -287,9 +287,9 @@ case INDEX_ADDRESS: { canonize_type(product); reagent element; element.type = new type_tree(*array_element(base.type)); - element.type = new type_tree(Type_ordinal["address"], element.type); + element.type = new type_tree(get(Type_ordinal, "address"), element.type); if (!types_match(product, element)) { - raise_error << maybe(Recipe[r].name) << "'index' on " << base.original_string << " can't be saved in " << product.original_string << "; type should be " << dump_types(element) << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'index' on " << base.original_string << " can't be saved in " << product.original_string << "; type should be " << dump_types(element) << '\n' << end(); break; } break; @@ -307,7 +307,7 @@ case INDEX_ADDRESS: { canonize(offset); vector offset_val(read_memory(offset)); type_tree* element_type = array_element(base.type); - if (offset_val.at(0) < 0 || offset_val.at(0) >= Memory[base_address]) { + if (offset_val.at(0) < 0 || offset_val.at(0) >= get_or_insert(Memory, base_address)) { raise_error << maybe(current_recipe_name()) << "invalid index " << no_scientific(offset_val.at(0)) << '\n' << end(); break; } @@ -377,11 +377,11 @@ recipe main [ :(before "End Primitive Recipe Declarations") LENGTH, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["length"] = LENGTH; +put(Recipe_ordinal, "length", LENGTH); :(before "End Primitive Recipe Checks") case LENGTH: { if (SIZE(inst.ingredients) != 1) { - raise_error << maybe(Recipe[r].name) << "'length' expects exactly 2 ingredients in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'length' expects exactly 2 ingredients in '" << inst.to_string() << "'\n" << end(); break; } reagent x = inst.ingredients.at(0); @@ -401,7 +401,7 @@ case LENGTH: { break; } products.resize(1); - products.at(0).push_back(Memory[x.value]); + products.at(0).push_back(get_or_insert(Memory, x.value)); break; } diff --git a/033exclusive_container.cc b/033exclusive_container.cc index ac7bcfd4..bf14d9d7 100644 --- a/033exclusive_container.cc +++ b/033exclusive_container.cc @@ -7,14 +7,14 @@ :(before "End Mu Types Initialization") //: We'll use this container as a running example, with two number elements. { -type_ordinal tmp = Type_ordinal["number-or-point"] = Next_type_ordinal++; -Type[tmp].size = 2; -Type[tmp].kind = EXCLUSIVE_CONTAINER; -Type[tmp].name = "number-or-point"; -Type[tmp].elements.push_back(new type_tree(number)); -Type[tmp].element_names.push_back("i"); -Type[tmp].elements.push_back(new type_tree(point)); -Type[tmp].element_names.push_back("p"); +type_ordinal tmp = put(Type_ordinal, "number-or-point", Next_type_ordinal++); +get(Type, tmp).size = 2; +get(Type, tmp).kind = EXCLUSIVE_CONTAINER; +get(Type, tmp).name = "number-or-point"; +get(Type, tmp).elements.push_back(new type_tree(number)); +get(Type, tmp).element_names.push_back("i"); +get(Type, tmp).elements.push_back(new type_tree(point)); +get(Type, tmp).element_names.push_back("p"); } //: Tests in this layer often explicitly setup memory before reading it as an @@ -53,7 +53,7 @@ if (t.kind == EXCLUSIVE_CONTAINER) { //: 'maybe-convert' requires a literal in ingredient 1. We'll use a synonym //: called 'variant'. :(before "End Mu Types Initialization") -Type_ordinal["variant"] = 0; +put(Type_ordinal, "variant", 0); :(scenario maybe_convert) recipe main [ @@ -76,21 +76,21 @@ recipe main [ :(before "End Primitive Recipe Declarations") MAYBE_CONVERT, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["maybe-convert"] = MAYBE_CONVERT; +put(Recipe_ordinal, "maybe-convert", MAYBE_CONVERT); :(before "End Primitive Recipe Checks") case MAYBE_CONVERT: { if (SIZE(inst.ingredients) != 2) { - raise_error << maybe(Recipe[r].name) << "'maybe-convert' expects exactly 2 ingredients in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'maybe-convert' expects exactly 2 ingredients in '" << inst.to_string() << "'\n" << end(); break; } reagent base = inst.ingredients.at(0); canonize_type(base); - if (!base.type || !base.type->value || Type[base.type->value].kind != EXCLUSIVE_CONTAINER) { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'maybe-convert' should be an exclusive-container, but got " << base.original_string << '\n' << end(); + if (!base.type || !base.type->value || get(Type, base.type->value).kind != EXCLUSIVE_CONTAINER) { + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'maybe-convert' should be an exclusive-container, but got " << base.original_string << '\n' << end(); break; } if (!is_literal(inst.ingredients.at(1))) { - raise_error << maybe(Recipe[r].name) << "second ingredient of 'maybe-convert' should have type 'variant', but got " << inst.ingredients.at(1).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "second ingredient of 'maybe-convert' should have type 'variant', but got " << inst.ingredients.at(1).original_string << '\n' << end(); break; } break; @@ -106,7 +106,7 @@ case MAYBE_CONVERT: { } long long int tag = current_instruction().ingredients.at(1).value; long long int result; - if (tag == static_cast(Memory[base_address])) { + if (tag == static_cast(get_or_insert(Memory, base_address))) { result = base_address+1; } else { @@ -160,7 +160,7 @@ if (current_instruction().operation == MERGE && current_instruction().products.at(0).type) { reagent x = current_instruction().products.at(0); canonize(x); - if (Type[x.type->value].kind == EXCLUSIVE_CONTAINER) { + if (get(Type, x.type->value).kind == EXCLUSIVE_CONTAINER) { return size_of(x) < SIZE(data); } } diff --git a/034call.cc b/034call.cc index b6793c72..80d142d7 100644 --- a/034call.cc +++ b/034call.cc @@ -82,7 +82,7 @@ inline long long int& current_step_index() { :(replace{} "inline const string& current_recipe_name()") inline const string& current_recipe_name() { assert(!Current_routine->calls.empty()); - return Recipe[current_call().running_recipe].name; + return get(Recipe, current_call().running_recipe).name; } :(replace{} "inline const instruction& current_instruction()") inline const instruction& current_instruction() { @@ -91,13 +91,13 @@ inline const instruction& current_instruction() { } :(code) inline const instruction& to_instruction(const call& call) { - return Recipe[call.running_recipe].steps.at(call.running_step_index); + return get(Recipe, call.running_recipe).steps.at(call.running_step_index); } :(after "Defined Recipe Checks") // not a primitive; check that it's present in the book of recipes if (Recipe.find(inst.operation) == Recipe.end()) { - raise_error << maybe(Recipe[r].name) << "undefined operation in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "undefined operation in '" << inst.to_string() << "'\n" << end(); break; } :(replace{} "default:" following "End Primitive Recipe Implementations") @@ -142,7 +142,7 @@ inline bool routine::completed() const { inline const vector& routine::steps() const { assert(!calls.empty()); - return Recipe[calls.front().running_recipe].steps; + return get(Recipe, calls.front().running_recipe).steps; } :(before "Running One Instruction") diff --git a/035call_ingredient.cc b/035call_ingredient.cc index eb899899..6bba2b23 100644 --- a/035call_ingredient.cc +++ b/035call_ingredient.cc @@ -43,11 +43,11 @@ for (long long int i = 0; i < SIZE(ingredient_types); ++i) { :(before "End Primitive Recipe Declarations") NEXT_INGREDIENT, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["next-ingredient"] = NEXT_INGREDIENT; +put(Recipe_ordinal, "next-ingredient", NEXT_INGREDIENT); :(before "End Primitive Recipe Checks") case NEXT_INGREDIENT: { if (!inst.ingredients.empty()) { - raise_error << maybe(Recipe[r].name) << "'next-ingredient' didn't expect any ingredients in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'next-ingredient' didn't expect any ingredients in '" << inst.to_string() << "'\n" << end(); break; } break; @@ -113,7 +113,7 @@ recipe f [ :(before "End Primitive Recipe Declarations") REWIND_INGREDIENTS, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["rewind-ingredients"] = REWIND_INGREDIENTS; +put(Recipe_ordinal, "rewind-ingredients", REWIND_INGREDIENTS); :(before "End Primitive Recipe Checks") case REWIND_INGREDIENTS: { break; @@ -138,15 +138,15 @@ recipe f [ :(before "End Primitive Recipe Declarations") INGREDIENT, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["ingredient"] = INGREDIENT; +put(Recipe_ordinal, "ingredient", INGREDIENT); :(before "End Primitive Recipe Checks") case INGREDIENT: { if (SIZE(inst.ingredients) != 1) { - raise_error << maybe(Recipe[r].name) << "'ingredient' expects exactly one ingredient, but got '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'ingredient' expects exactly one ingredient, but got '" << inst.to_string() << "'\n" << end(); break; } if (!is_literal(inst.ingredients.at(0)) && !is_mu_number(inst.ingredients.at(0))) { - raise_error << maybe(Recipe[r].name) << "'ingredient' expects a literal ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'ingredient' expects a literal ingredient, but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } break; diff --git a/036call_reply.cc b/036call_reply.cc index e43a704c..695c0910 100644 --- a/036call_reply.cc +++ b/036call_reply.cc @@ -15,7 +15,7 @@ recipe f [ :(before "End Primitive Recipe Declarations") REPLY, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["reply"] = REPLY; +put(Recipe_ordinal, "reply", REPLY); :(before "End Primitive Recipe Checks") case REPLY: { break; // continue to process rest of *caller* instruction @@ -173,7 +173,7 @@ recipe test1 [ // ``` if (curr.name == "reply-if") { if (curr.products.empty()) { - curr.operation = Recipe_ordinal["jump-unless"]; + curr.operation = get(Recipe_ordinal, "jump-unless"); curr.name = "jump-unless"; vector results; copy(++curr.ingredients.begin(), curr.ingredients.end(), inserter(results, results.end())); @@ -181,7 +181,7 @@ if (curr.name == "reply-if") { curr.ingredients.push_back(reagent("1:offset")); result.steps.push_back(curr); curr.clear(); - curr.operation = Recipe_ordinal["reply"]; + curr.operation = get(Recipe_ordinal, "reply"); curr.name = "reply"; curr.ingredients.swap(results); } @@ -196,7 +196,7 @@ if (curr.name == "reply-if") { // ``` if (curr.name == "reply-unless") { if (curr.products.empty()) { - curr.operation = Recipe_ordinal["jump-if"]; + curr.operation = get(Recipe_ordinal, "jump-if"); curr.name = "jump-if"; vector results; copy(++curr.ingredients.begin(), curr.ingredients.end(), inserter(results, results.end())); @@ -204,7 +204,7 @@ if (curr.name == "reply-unless") { curr.ingredients.push_back(reagent("1:offset")); result.steps.push_back(curr); curr.clear(); - curr.operation = Recipe_ordinal["reply"]; + curr.operation = get(Recipe_ordinal, "reply"); curr.name = "reply"; curr.ingredients.swap(results); } diff --git a/037recipe.cc b/037recipe.cc index a2a95a39..0a4fea4e 100644 --- a/037recipe.cc +++ b/037recipe.cc @@ -4,22 +4,22 @@ :(before "End Mu Types Initialization") // 'recipe' is a literal -Type_ordinal["recipe"] = 0; +put(Type_ordinal, "recipe", 0); // 'recipe-ordinal' is the literal that can store recipe literals -type_ordinal recipe_ordinal = Type_ordinal["recipe-ordinal"] = Next_type_ordinal++; -Type[recipe_ordinal].name = "recipe-ordinal"; +type_ordinal recipe_ordinal = put(Type_ordinal, "recipe-ordinal", Next_type_ordinal++); +get(Type, recipe_ordinal).name = "recipe-ordinal"; :(before "End Reagent-parsing Exceptions") if (r.properties.at(0).second && r.properties.at(0).second->value == "recipe") { - r.set_value(Recipe_ordinal[r.name]); + r.set_value(get(Recipe_ordinal, r.name)); return; } :(code) bool is_mu_recipe(reagent r) { if (!r.type) return false; - if (r.type->value == Type_ordinal["recipe"]) return true; - if (r.type->value == Type_ordinal["recipe-ordinal"]) return true; + if (r.type->value == get(Type_ordinal, "recipe")) return true; + if (r.type->value == get(Type_ordinal, "recipe-ordinal")) return true; // End is_mu_recipe Cases return false; } diff --git a/038scheduler.cc b/038scheduler.cc index 1b482fc5..34a6df8d 100644 --- a/038scheduler.cc +++ b/038scheduler.cc @@ -97,7 +97,7 @@ string current_routine_label() { const call_stack& calls = Current_routine->calls; for (call_stack::const_iterator p = calls.begin(); p != calls.end(); ++p) { if (p != calls.begin()) result << '/'; - result << Recipe[p->running_recipe].name; + result << get(Recipe, p->running_recipe).name; } return result.str(); } @@ -111,7 +111,7 @@ Current_routine = NULL; //: special case for the very first routine :(replace{} "void run_main(int argc, char* argv[])") void run_main(int argc, char* argv[]) { - recipe_ordinal r = Recipe_ordinal[string("main")]; + recipe_ordinal r = get(Recipe_ordinal, string("main")); if (r) { routine* main_routine = new routine(r); // Update main_routine @@ -143,15 +143,15 @@ parent_index = -1; :(before "End Primitive Recipe Declarations") START_RUNNING, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["start-running"] = START_RUNNING; +put(Recipe_ordinal, "start-running", START_RUNNING); :(before "End Primitive Recipe Checks") case START_RUNNING: { if (inst.ingredients.empty()) { - raise_error << maybe(Recipe[r].name) << "'start-running' requires at least one ingredient: the recipe to start running\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'start-running' requires at least one ingredient: the recipe to start running\n" << end(); break; } if (!is_mu_recipe(inst.ingredients.at(0))) { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'start-running' should be a recipe, but got " << inst.ingredients.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'start-running' should be a recipe, but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } break; @@ -334,15 +334,15 @@ recipe f2 [ :(before "End Primitive Recipe Declarations") ROUTINE_STATE, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["routine-state"] = ROUTINE_STATE; +put(Recipe_ordinal, "routine-state", ROUTINE_STATE); :(before "End Primitive Recipe Checks") case ROUTINE_STATE: { if (SIZE(inst.ingredients) != 1) { - raise_error << maybe(Recipe[r].name) << "'routine-state' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'routine-state' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end(); break; } if (!is_mu_number(inst.ingredients.at(0))) { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'routine-state' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'routine-state' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } break; @@ -367,15 +367,15 @@ case ROUTINE_STATE: { :(before "End Primitive Recipe Declarations") RESTART, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["restart"] = RESTART; +put(Recipe_ordinal, "restart", RESTART); :(before "End Primitive Recipe Checks") case RESTART: { if (SIZE(inst.ingredients) != 1) { - raise_error << maybe(Recipe[r].name) << "'restart' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'restart' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end(); break; } if (!is_mu_number(inst.ingredients.at(0))) { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'restart' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'restart' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } break; @@ -395,15 +395,15 @@ case RESTART: { :(before "End Primitive Recipe Declarations") STOP, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["stop"] = STOP; +put(Recipe_ordinal, "stop", STOP); :(before "End Primitive Recipe Checks") case STOP: { if (SIZE(inst.ingredients) != 1) { - raise_error << maybe(Recipe[r].name) << "'stop' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'stop' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end(); break; } if (!is_mu_number(inst.ingredients.at(0))) { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'stop' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'stop' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } break; @@ -423,7 +423,7 @@ case STOP: { :(before "End Primitive Recipe Declarations") _DUMP_ROUTINES, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["$dump-routines"] = _DUMP_ROUTINES; +put(Recipe_ordinal, "$dump-routines", _DUMP_ROUTINES); :(before "End Primitive Recipe Checks") case _DUMP_ROUTINES: { break; @@ -477,19 +477,19 @@ limit = -1; /* no limit */ :(before "End Primitive Recipe Declarations") LIMIT_TIME, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["limit-time"] = LIMIT_TIME; +put(Recipe_ordinal, "limit-time", LIMIT_TIME); :(before "End Primitive Recipe Checks") case LIMIT_TIME: { if (SIZE(inst.ingredients) != 2) { - raise_error << maybe(Recipe[r].name) << "'limit-time' requires exactly two ingredient, but got " << inst.to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'limit-time' requires exactly two ingredient, but got " << inst.to_string() << '\n' << end(); break; } if (!is_mu_number(inst.ingredients.at(0))) { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'limit-time' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'limit-time' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } if (!is_mu_number(inst.ingredients.at(1))) { - raise_error << maybe(Recipe[r].name) << "second ingredient of 'limit-time' should be a number (of instructions to run for), but got " << inst.ingredients.at(1).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "second ingredient of 'limit-time' should be a number (of instructions to run for), but got " << inst.ingredients.at(1).original_string << '\n' << end(); break; } break; diff --git a/039wait.cc b/039wait.cc index 27412901..ef3d30e5 100644 --- a/039wait.cc +++ b/039wait.cc @@ -33,7 +33,7 @@ waiting_on_location = old_value_of_waiting_location = 0; :(before "End Primitive Recipe Declarations") WAIT_FOR_LOCATION, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["wait-for-location"] = WAIT_FOR_LOCATION; +put(Recipe_ordinal, "wait-for-location", WAIT_FOR_LOCATION); :(before "End Primitive Recipe Checks") case WAIT_FOR_LOCATION: { break; @@ -44,8 +44,8 @@ case WAIT_FOR_LOCATION: { canonize(loc); Current_routine->state = WAITING; Current_routine->waiting_on_location = loc.value; - Current_routine->old_value_of_waiting_location = Memory[loc.value]; - trace(9998, "run") << "waiting for location " << loc.value << " to change from " << no_scientific(Memory[loc.value]) << end(); + Current_routine->old_value_of_waiting_location = get_or_insert(Memory, loc.value); + trace(9998, "run") << "waiting for location " << loc.value << " to change from " << no_scientific(get_or_insert(Memory, loc.value)) << end(); break; } @@ -55,7 +55,7 @@ case WAIT_FOR_LOCATION: { for (long long int i = 0; i < SIZE(Routines); ++i) { if (Routines.at(i)->state != WAITING) continue; if (Routines.at(i)->waiting_on_location && - Memory[Routines.at(i)->waiting_on_location] != Routines.at(i)->old_value_of_waiting_location) { + get_or_insert(Memory, Routines.at(i)->waiting_on_location) != Routines.at(i)->old_value_of_waiting_location) { trace(9999, "schedule") << "waking up routine\n" << end(); Routines.at(i)->state = RUNNING; Routines.at(i)->waiting_on_location = Routines.at(i)->old_value_of_waiting_location = 0; @@ -92,15 +92,15 @@ waiting_on_routine = 0; :(before "End Primitive Recipe Declarations") WAIT_FOR_ROUTINE, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["wait-for-routine"] = WAIT_FOR_ROUTINE; +put(Recipe_ordinal, "wait-for-routine", WAIT_FOR_ROUTINE); :(before "End Primitive Recipe Checks") case WAIT_FOR_ROUTINE: { if (SIZE(inst.ingredients) != 1) { - raise_error << maybe(Recipe[r].name) << "'wait-for-routine' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'wait-for-routine' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end(); break; } if (!is_mu_number(inst.ingredients.at(0))) { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'wait-for-routine' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'wait-for-routine' should be a routine id generated by 'start-running', but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } break; @@ -138,7 +138,7 @@ for (long long int i = 0; i < SIZE(Routines); ++i) { :(before "End Primitive Recipe Declarations") SWITCH, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["switch"] = SWITCH; +put(Recipe_ordinal, "switch", SWITCH); :(before "End Primitive Recipe Checks") case SWITCH: { break; diff --git a/040brace.cc b/040brace.cc index 9429fe1a..670949d2 100644 --- a/040brace.cc +++ b/040brace.cc @@ -39,11 +39,11 @@ void transform_braces(const recipe_ordinal r) { const int OPEN = 0, CLOSE = 1; // use signed integer for step index because we'll be doing arithmetic on it list > braces; - trace(9991, "transform") << "--- transform braces for recipe " << Recipe[r].name << end(); - for (long long int index = 0; index < SIZE(Recipe[r].steps); ++index) { - const instruction& inst = Recipe[r].steps.at(index); + trace(9991, "transform") << "--- transform braces for recipe " << get(Recipe, r).name << end(); + for (long long int index = 0; index < SIZE(get(Recipe, r).steps); ++index) { + const instruction& inst = get(Recipe, r).steps.at(index); if (inst.label == "{") { - trace(9993, "transform") << maybe(Recipe[r].name) << "push (open, " << index << ")" << end(); + trace(9993, "transform") << maybe(get(Recipe, r).name) << "push (open, " << index << ")" << end(); braces.push_back(pair(OPEN, index)); } if (inst.label == "}") { @@ -52,15 +52,15 @@ void transform_braces(const recipe_ordinal r) { } } stack open_braces; - for (long long int index = 0; index < SIZE(Recipe[r].steps); ++index) { - instruction& inst = Recipe[r].steps.at(index); + for (long long int index = 0; index < SIZE(get(Recipe, r).steps); ++index) { + instruction& inst = get(Recipe, r).steps.at(index); if (inst.label == "{") { open_braces.push(index); continue; } if (inst.label == "}") { if (open_braces.empty()) { - raise << "missing '{' in " << Recipe[r].name << '\n'; + raise << "missing '{' in " << get(Recipe, r).name << '\n'; return; } open_braces.pop(); @@ -113,7 +113,7 @@ void transform_braces(const recipe_ordinal r) { } // if implicit, compute target reagent target; - target.type = new type_tree(Type_ordinal["offset"]); + target.type = new type_tree(get(Type_ordinal, "offset")); target.set_value(0); if (open_braces.empty()) raise_error << inst.old_name << " needs a '{' before\n" << end(); @@ -139,8 +139,8 @@ long long int matching_brace(long long int index, const listfirst ? 1 : -1); if (stacksize == 0) return p->second; } - raise_error << maybe(Recipe[r].name) << "unbalanced '{'\n" << end(); - return SIZE(Recipe[r].steps); // exit current routine + raise_error << maybe(get(Recipe, r).name) << "unbalanced '{'\n" << end(); + return SIZE(get(Recipe, r).steps); // exit current routine } :(scenario loop) @@ -372,12 +372,12 @@ LOOP, LOOP_IF, LOOP_UNLESS, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["break"] = BREAK; -Recipe_ordinal["break-if"] = BREAK_IF; -Recipe_ordinal["break-unless"] = BREAK_UNLESS; -Recipe_ordinal["loop"] = LOOP; -Recipe_ordinal["loop-if"] = LOOP_IF; -Recipe_ordinal["loop-unless"] = LOOP_UNLESS; +put(Recipe_ordinal, "break", BREAK); +put(Recipe_ordinal, "break-if", BREAK_IF); +put(Recipe_ordinal, "break-unless", BREAK_UNLESS); +put(Recipe_ordinal, "loop", LOOP); +put(Recipe_ordinal, "loop-if", LOOP_IF); +put(Recipe_ordinal, "loop-unless", LOOP_UNLESS); :(before "End Primitive Recipe Checks") case BREAK: break; case BREAK_IF: break; diff --git a/041jump_target.cc b/041jump_target.cc index d395cd97..d7ff717a 100644 --- a/041jump_target.cc +++ b/041jump_target.cc @@ -16,7 +16,7 @@ recipe main [ -mem: storing 0 in location 1 :(before "End Mu Types Initialization") -Type_ordinal["label"] = 0; +put(Type_ordinal, "label", 0); :(before "Transform.push_back(transform_braces)") Transform.push_back(transform_labels); @@ -24,21 +24,21 @@ Transform.push_back(transform_labels); :(code) void transform_labels(const recipe_ordinal r) { map offset; - for (long long int i = 0; i < SIZE(Recipe[r].steps); ++i) { - const instruction& inst = Recipe[r].steps.at(i); + for (long long int i = 0; i < SIZE(get(Recipe, r).steps); ++i) { + const instruction& inst = get(Recipe, r).steps.at(i); if (!inst.label.empty() && inst.label.at(0) == '+') { if (offset.find(inst.label) == offset.end()) { offset[inst.label] = i; } else { - raise_error << maybe(Recipe[r].name) << "duplicate label '" << inst.label << "'" << end(); + raise_error << maybe(get(Recipe, r).name) << "duplicate label '" << inst.label << "'" << end(); // have all jumps skip some random but noticeable and deterministic amount of code offset[inst.label] = 9999; } } } - for (long long int i = 0; i < SIZE(Recipe[r].steps); ++i) { - instruction& inst = Recipe[r].steps.at(i); + for (long long int i = 0; i < SIZE(get(Recipe, r).steps); ++i) { + instruction& inst = get(Recipe, r).steps.at(i); if (inst.name == "jump") { replace_offset(inst.ingredients.at(0), offset, i, r); } @@ -60,19 +60,19 @@ void transform_labels(const recipe_ordinal r) { :(code) void replace_offset(reagent& x, /*const*/ map& offset, const long long int current_offset, const recipe_ordinal r) { if (!is_literal(x)) { - raise_error << maybe(Recipe[r].name) << "jump target must be offset or label but is " << x.original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "jump target must be offset or label but is " << x.original_string << '\n' << end(); x.set_value(0); // no jump by default return; } assert(!x.initialized); if (is_integer(x.name)) return; // non-labels will be handled like other number operands if (!is_jump_target(x.name)) { - raise_error << maybe(Recipe[r].name) << "can't jump to label " << x.name << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "can't jump to label " << x.name << '\n' << end(); x.set_value(0); // no jump by default return; } if (offset.find(x.name) == offset.end()) { - raise_error << maybe(Recipe[r].name) << "can't find label " << x.name << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "can't find label " << x.name << '\n' << end(); x.set_value(0); // no jump by default return; } diff --git a/042name.cc b/042name.cc index 0454e9dd..ae540c57 100644 --- a/042name.cc +++ b/042name.cc @@ -30,30 +30,30 @@ for (long long int i = 0; i < SIZE(recently_added_recipes); ++i) { :(code) void transform_names(const recipe_ordinal r) { - trace(9991, "transform") << "--- transform names for recipe " << Recipe[r].name << end(); + trace(9991, "transform") << "--- transform names for recipe " << get(Recipe, r).name << end(); bool names_used = false; bool numeric_locations_used = false; map& names = Name[r]; // store the indices 'used' so far in the map long long int& curr_idx = names[""]; ++curr_idx; // avoid using index 0, benign skip in some other cases - for (long long int i = 0; i < SIZE(Recipe[r].steps); ++i) { - instruction& inst = Recipe[r].steps.at(i); + for (long long int i = 0; i < SIZE(get(Recipe, r).steps); ++i) { + instruction& inst = get(Recipe, r).steps.at(i); // End transform_names(inst) Special-cases // map names to addresses for (long long int in = 0; in < SIZE(inst.ingredients); ++in) { if (is_numeric_location(inst.ingredients.at(in))) numeric_locations_used = true; if (is_named_location(inst.ingredients.at(in))) names_used = true; - if (disqualified(inst.ingredients.at(in), inst, Recipe[r].name)) continue; + if (disqualified(inst.ingredients.at(in), inst, get(Recipe, r).name)) continue; if (!already_transformed(inst.ingredients.at(in), names)) { - raise_error << maybe(Recipe[r].name) << "use before set: " << inst.ingredients.at(in).name << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "use before set: " << inst.ingredients.at(in).name << '\n' << end(); } inst.ingredients.at(in).set_value(lookup_name(inst.ingredients.at(in), r)); } for (long long int out = 0; out < SIZE(inst.products); ++out) { if (is_numeric_location(inst.products.at(out))) numeric_locations_used = true; if (is_named_location(inst.products.at(out))) names_used = true; - if (disqualified(inst.products.at(out), inst, Recipe[r].name)) continue; + if (disqualified(inst.products.at(out), inst, get(Recipe, r).name)) continue; if (names.find(inst.products.at(out).name) == names.end()) { trace(9993, "name") << "assign " << inst.products.at(out).name << " " << curr_idx << end(); names[inst.products.at(out).name] = curr_idx; @@ -63,7 +63,7 @@ void transform_names(const recipe_ordinal r) { } } if (names_used && numeric_locations_used) - raise_error << maybe(Recipe[r].name) << "mixing variable names and numeric addresses\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "mixing variable names and numeric addresses\n" << end(); } bool disqualified(/*mutable*/ reagent& x, const instruction& inst, const string& recipe_name) { @@ -89,7 +89,7 @@ long long int lookup_name(const reagent& r, const recipe_ordinal default_recipe) type_ordinal skip_addresses(type_tree* type, const string& recipe_name) { for (; type; type = type->right) { - if (type->value != Type_ordinal["address"]) + if (type->value != get(Type_ordinal, "address")) return type->value; } raise_error << maybe(recipe_name) << "expected a container" << '\n' << end(); @@ -97,11 +97,11 @@ type_ordinal skip_addresses(type_tree* type, const string& recipe_name) { } int find_element_name(const type_ordinal t, const string& name, const string& recipe_name) { - const type_info& container = Type[t]; + const type_info& container = get(Type, t); for (long long int i = 0; i < SIZE(container.element_names); ++i) { if (container.element_names.at(i) == name) return i; } - raise_error << maybe(recipe_name) << "unknown element " << name << " in container " << Type[t].name << '\n' << end(); + raise_error << maybe(recipe_name) << "unknown element " << name << " in container " << get(Type, t).name << '\n' << end(); return -1; } @@ -180,8 +180,8 @@ $error: 0 //: update our running example container for the next test :(before "End Mu Types Initialization") -Type[point].element_names.push_back("x"); -Type[point].element_names.push_back("y"); +get(Type, point).element_names.push_back("x"); +get(Type, point).element_names.push_back("y"); :(scenario transform_names_transforms_container_elements) recipe main [ p:address:point <- copy 0 # unsafe @@ -195,16 +195,16 @@ recipe main [ // replace element names of containers with offsets if (inst.name == "get" || inst.name == "get-address") { if (SIZE(inst.ingredients) != 2) { - raise_error << maybe(Recipe[r].name) << "exactly 2 ingredients expected in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "exactly 2 ingredients expected in '" << inst.to_string() << "'\n" << end(); break; } if (!is_literal(inst.ingredients.at(1))) - raise_error << maybe(Recipe[r].name) << "expected ingredient 1 of " << (inst.name == "get" ? "'get'" : "'get-address'") << " to have type 'offset'; got " << inst.ingredients.at(1).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "expected ingredient 1 of " << (inst.name == "get" ? "'get'" : "'get-address'") << " to have type 'offset'; got " << inst.ingredients.at(1).original_string << '\n' << end(); if (inst.ingredients.at(1).name.find_first_not_of("0123456789") != string::npos) { // since first non-address in base type must be a container, we don't have to canonize - type_ordinal base_type = skip_addresses(inst.ingredients.at(0).type, Recipe[r].name); - inst.ingredients.at(1).set_value(find_element_name(base_type, inst.ingredients.at(1).name, Recipe[r].name)); - trace(9993, "name") << "element " << inst.ingredients.at(1).name << " of type " << Type[base_type].name << " is at offset " << no_scientific(inst.ingredients.at(1).value) << end(); + type_ordinal base_type = skip_addresses(inst.ingredients.at(0).type, get(Recipe, r).name); + inst.ingredients.at(1).set_value(find_element_name(base_type, inst.ingredients.at(1).name, get(Recipe, r).name)); + trace(9993, "name") << "element " << inst.ingredients.at(1).name << " of type " << get(Type, base_type).name << " is at offset " << no_scientific(inst.ingredients.at(1).value) << end(); } } @@ -235,14 +235,14 @@ recipe main [ // convert variant names of exclusive containers if (inst.name == "maybe-convert") { if (SIZE(inst.ingredients) != 2) { - raise_error << maybe(Recipe[r].name) << "exactly 2 ingredients expected in '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "exactly 2 ingredients expected in '" << inst.to_string() << "'\n" << end(); break; } assert(is_literal(inst.ingredients.at(1))); if (inst.ingredients.at(1).name.find_first_not_of("0123456789") != string::npos) { // since first non-address in base type must be an exclusive container, we don't have to canonize - type_ordinal base_type = skip_addresses(inst.ingredients.at(0).type, Recipe[r].name); - inst.ingredients.at(1).set_value(find_element_name(base_type, inst.ingredients.at(1).name, Recipe[r].name)); - trace(9993, "name") << "variant " << inst.ingredients.at(1).name << " of type " << Type[base_type].name << " has tag " << no_scientific(inst.ingredients.at(1).value) << end(); + type_ordinal base_type = skip_addresses(inst.ingredients.at(0).type, get(Recipe, r).name); + inst.ingredients.at(1).set_value(find_element_name(base_type, inst.ingredients.at(1).name, get(Recipe, r).name)); + trace(9993, "name") << "variant " << inst.ingredients.at(1).name << " of type " << get(Type, base_type).name << " has tag " << no_scientific(inst.ingredients.at(1).value) << end(); } } diff --git a/043new.cc b/043new.cc index a851e3d5..752ee323 100644 --- a/043new.cc +++ b/043new.cc @@ -26,23 +26,23 @@ trace(9999, "new") << "routine allocated memory from " << alloc << " to " << all //:: 'new' takes a weird 'type' as its first ingredient; don't error on it :(before "End Mu Types Initialization") -Type_ordinal["type"] = 0; +put(Type_ordinal, "type", 0); //:: typecheck 'new' instructions :(before "End Primitive Recipe Declarations") NEW, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["new"] = NEW; +put(Recipe_ordinal, "new", NEW); :(before "End Primitive Recipe Checks") case NEW: { if (inst.ingredients.empty() || SIZE(inst.ingredients) > 2) { - raise_error << maybe(Recipe[r].name) << "'new' requires one or two ingredients, but got " << inst.to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'new' requires one or two ingredients, but got " << inst.to_string() << '\n' << end(); break; } // End NEW Check Special-cases reagent type = inst.ingredients.at(0); if (!is_mu_type_literal(type)) { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'new' should be a type, but got " << type.original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'new' should be a type, but got " << type.original_string << '\n' << end(); break; } break; @@ -54,9 +54,9 @@ Transform.push_back(transform_new_to_allocate); :(code) void transform_new_to_allocate(recipe_ordinal r) { - trace(9991, "transform") << "--- convert 'new' to 'allocate' for recipe " << Recipe[r].name << end(); - for (long long int i = 0; i < SIZE(Recipe[r].steps); ++i) { - instruction& inst = Recipe[r].steps.at(i); + trace(9991, "transform") << "--- convert 'new' to 'allocate' for recipe " << get(Recipe, r).name << end(); + for (long long int i = 0; i < SIZE(get(Recipe, r).steps); ++i) { + instruction& inst = get(Recipe, r).steps.at(i); // Convert 'new' To 'allocate' if (inst.name == "new") { inst.operation = ALLOCATE; @@ -80,7 +80,7 @@ void transform_new_to_allocate(recipe_ordinal r) { :(before "End Primitive Recipe Declarations") ALLOCATE, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["allocate"] = ALLOCATE; +put(Recipe_ordinal, "allocate", ALLOCATE); :(before "End Primitive Recipe Implementations") case ALLOCATE: { // compute the space we need @@ -102,10 +102,10 @@ case ALLOCATE: { products.at(0).push_back(result); // initialize allocated space for (long long int address = result; address < result+size; ++address) { - Memory[address] = 0; + put(Memory, address, 0); } if (SIZE(current_instruction().ingredients) > 1) { - Memory[result] = ingredients.at(1).at(0); // array length + put(Memory, result, ingredients.at(1).at(0)); // array length } // bump Current_routine->alloc += size; @@ -158,7 +158,7 @@ void ensure_space(long long int size) { :(scenario new_initializes) % Memory_allocated_until = 10; -% Memory[Memory_allocated_until] = 1; +% put(Memory, Memory_allocated_until, 1); recipe main [ 1:address:number <- new number:type 2:number <- copy *1:address:number @@ -236,17 +236,17 @@ Free_list.clear(); :(before "End Primitive Recipe Declarations") ABANDON, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["abandon"] = ABANDON; +put(Recipe_ordinal, "abandon", ABANDON); :(before "End Primitive Recipe Checks") case ABANDON: { if (SIZE(inst.ingredients) != 1) { - raise_error << maybe(Recipe[r].name) << "'abandon' requires one ingredient, but got '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'abandon' requires one ingredient, but got '" << inst.to_string() << "'\n" << end(); break; } reagent types = inst.ingredients.at(0); canonize_type(types); - if (!types.type || types.type->value != Type_ordinal["address"]) { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'abandon' should be an address, but got " << inst.ingredients.at(0).original_string << '\n' << end(); + if (!types.type || types.type->value != get(Type_ordinal, "address")) { + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'abandon' should be an address, but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } break; @@ -257,7 +257,7 @@ case ABANDON: { reagent types = current_instruction().ingredients.at(0); canonize(types); // lookup_memory without drop_one_lookup { - types.set_value(Memory[types.value]); + types.set_value(get_or_insert(Memory, types.value)); drop_address_from_type(types); // } abandon(address, size_of(types)); @@ -271,26 +271,26 @@ void abandon(long long int address, long long int size) { //? cerr << "abandon: " << size << '\n'; // clear memory for (long long int curr = address; curr < address+size; ++curr) - Memory[curr] = 0; + put(Memory, curr, 0); // append existing free list to address - Memory[address] = Free_list[size]; + put(Memory, address, Free_list[size]); Free_list[size] = address; } :(before "ensure_space(size)" following "case ALLOCATE") if (Free_list[size]) { long long int result = Free_list[size]; - Free_list[size] = Memory[result]; + Free_list[size] = get_or_insert(Memory, result); for (long long int curr = result+1; curr < result+size; ++curr) { - if (Memory[curr] != 0) { + if (get_or_insert(Memory, curr) != 0) { raise_error << maybe(current_recipe_name()) << "memory in free list was not zeroed out: " << curr << '/' << result << "; somebody wrote to us after free!!!\n" << end(); break; // always fatal } } if (SIZE(current_instruction().ingredients) > 1) - Memory[result] = ingredients.at(1).at(0); + put(Memory, result, ingredients.at(1).at(0)); else - Memory[result] = 0; + put(Memory, result, 0); products.resize(1); products.at(0).push_back(result); break; @@ -356,14 +356,14 @@ long long int new_mu_string(const string& contents) { ensure_space(string_length+1); // don't forget the extra location for array size // initialize string long long int result = Current_routine->alloc; - Memory[Current_routine->alloc++] = string_length; + put(Memory, Current_routine->alloc++, string_length); long long int curr = 0; const char* raw_contents = contents.c_str(); for (long long int i = 0; i < string_length; ++i) { uint32_t curr_character; assert(curr < SIZE(contents)); tb_utf8_char_to_unicode(&curr_character, &raw_contents[curr]); - Memory[Current_routine->alloc] = curr_character; + put(Memory, Current_routine->alloc, curr_character); curr += tb_utf8_char_length(raw_contents[curr]); ++Current_routine->alloc; } @@ -430,20 +430,20 @@ long long int unicode_length(const string& s) { bool is_mu_string(const reagent& x) { return x.type - && x.type->value == Type_ordinal["address"] + && x.type->value == get(Type_ordinal, "address") && x.type->right - && x.type->right->value == Type_ordinal["array"] + && x.type->right->value == get(Type_ordinal, "array") && x.type->right->right - && x.type->right->right->value == Type_ordinal["character"] + && x.type->right->right->value == get(Type_ordinal, "character") && x.type->right->right->right == NULL; } string read_mu_string(long long int address) { - long long int size = Memory[address]; + long long int size = get_or_insert(Memory, address); if (size == 0) return ""; ostringstream tmp; for (long long int curr = address+1; curr <= address+size; ++curr) { - tmp << to_unicode(static_cast(Memory[curr])); + tmp << to_unicode(static_cast(get_or_insert(Memory, curr))); } return tmp.str(); } diff --git a/044space.cc b/044space.cc index dd579a4f..0031536d 100644 --- a/044space.cc +++ b/044space.cc @@ -127,7 +127,7 @@ if (curr.name == "new-default-space") { :(after "vector read_memory(reagent x)") if (x.name == "number-of-locals") { vector result; - result.push_back(Name[Recipe_ordinal[current_recipe_name()]][""]); + result.push_back(Name[get(Recipe_ordinal, current_recipe_name())][""]); if (result.back() == 0) raise_error << "no space allocated for default-space in recipe " << current_recipe_name() << "; are you using names?\n" << end(); return result; @@ -170,9 +170,9 @@ if (curr.name == "local-scope") { :(code) void try_reclaim_locals() { // only reclaim routines starting with 'local-scope' - const recipe_ordinal r = Recipe_ordinal[current_recipe_name()]; - if (Recipe[r].steps.empty()) return; - const instruction& inst = Recipe[r].steps.at(0); + const recipe_ordinal r = get(Recipe_ordinal, current_recipe_name()); + if (get(Recipe, r).steps.empty()) return; + const instruction& inst = get(Recipe, r).steps.at(0); if (inst.old_name != "local-scope") return; abandon(current_call().default_space, /*array length*/1+/*number-of-locals*/Name[r][""]); @@ -199,9 +199,9 @@ long long int space_base(const reagent& x) { long long int address(long long int offset, long long int base) { if (base == 0) return offset; // raw - if (offset >= static_cast(Memory[base])) { + if (offset >= static_cast(get_or_insert(Memory, base))) { // todo: test - raise_error << "location " << offset << " is out of bounds " << no_scientific(Memory[base]) << " at " << base << '\n' << end(); + raise_error << "location " << offset << " is out of bounds " << no_scientific(get_or_insert(Memory, base)) << " at " << base << '\n' << end(); } return base+1 + offset; } @@ -210,11 +210,11 @@ long long int address(long long int offset, long long int base) { if (x.name == "default-space") { if (!scalar(data) || !x.type - || x.type->value != Type_ordinal["address"] + || x.type->value != get(Type_ordinal, "address") || !x.type->right - || x.type->right->value != Type_ordinal["array"] + || x.type->right->value != get(Type_ordinal, "array") || !x.type->right->right - || x.type->right->right->value != Type_ordinal["location"] + || x.type->right->right->value != get(Type_ordinal, "location") || x.type->right->right->right) { raise_error << maybe(current_recipe_name()) << "'default-space' should be of type address:array:location, but tried to write " << to_string(data) << '\n' << end(); } diff --git a/045space_surround.cc b/045space_surround.cc index 880c350e..940f82b8 100644 --- a/045space_surround.cc +++ b/045space_surround.cc @@ -34,7 +34,7 @@ long long int space_base(const reagent& x, long long int space_index, long long if (space_index == 0) { return base; } - long long int result = space_base(x, space_index-1, Memory[base+1]); + long long int result = space_base(x, space_index-1, get_or_insert(Memory, base+1)); return result; } diff --git a/046closure_name.cc b/046closure_name.cc index 56b3227a..70c3481e 100644 --- a/046closure_name.cc +++ b/046closure_name.cc @@ -40,38 +40,38 @@ Transform.push_back(collect_surrounding_spaces); :(code) void collect_surrounding_spaces(const recipe_ordinal r) { - trace(9991, "transform") << "--- collect surrounding spaces for recipe " << Recipe[r].name << end(); - for (long long int i = 0; i < SIZE(Recipe[r].steps); ++i) { - const instruction& inst = Recipe[r].steps.at(i); + trace(9991, "transform") << "--- collect surrounding spaces for recipe " << get(Recipe, r).name << end(); + for (long long int i = 0; i < SIZE(get(Recipe, r).steps); ++i) { + const instruction& inst = get(Recipe, r).steps.at(i); if (inst.is_label) continue; for (long long int j = 0; j < SIZE(inst.products); ++j) { if (is_literal(inst.products.at(j))) continue; if (inst.products.at(j).name != "0") continue; type_tree* type = inst.products.at(j).type; if (!type - || type->value != Type_ordinal["address"] + || type->value != get(Type_ordinal, "address") || !type->right - || type->right->value != Type_ordinal["array"] + || type->right->value != get(Type_ordinal, "array") || !type->right->right - || type->right->right->value != Type_ordinal["location"] + || type->right->right->value != get(Type_ordinal, "location") || type->right->right->right) { raise_error << "slot 0 should always have type address:array:location, but is " << inst.products.at(j).to_string() << '\n' << end(); continue; } string_tree* s = property(inst.products.at(j), "names"); if (!s) { - raise_error << "slot 0 requires a /names property in recipe " << Recipe[r].name << end(); + raise_error << "slot 0 requires a /names property in recipe " << get(Recipe, r).name << end(); continue; } if (s->right) raise_error << "slot 0 should have a single value in /names, but got " << inst.products.at(j).to_string() << '\n' << end(); const string& surrounding_recipe_name = s->value; if (Surrounding_space.find(r) != Surrounding_space.end() - && Surrounding_space[r] != Recipe_ordinal[surrounding_recipe_name]) { - raise_error << "recipe " << Recipe[r].name << " can have only one 'surrounding' recipe but has " << Recipe[Surrounding_space[r]].name << " and " << surrounding_recipe_name << '\n' << end(); + && Surrounding_space[r] != get(Recipe_ordinal, surrounding_recipe_name)) { + raise_error << "recipe " << get(Recipe, r).name << " can have only one 'surrounding' recipe but has " << Recipe[Surrounding_space[r]].name << " and " << surrounding_recipe_name << '\n' << end(); continue; } - trace(9993, "name") << "lexically surrounding space for recipe " << Recipe[r].name << " comes from " << surrounding_recipe_name << end(); - Surrounding_space[r] = Recipe_ordinal[surrounding_recipe_name]; + trace(9993, "name") << "lexically surrounding space for recipe " << get(Recipe, r).name << " comes from " << surrounding_recipe_name << end(); + Surrounding_space[r] = get(Recipe_ordinal, surrounding_recipe_name); } } } @@ -117,7 +117,7 @@ long long int lookup_name(const reagent& x, const recipe_ordinal r, setvalue != Type_ordinal["address"] + || x.type->value != get(Type_ordinal, "address") || !x.type->right - || x.type->right->value != Type_ordinal["array"] + || x.type->right->value != get(Type_ordinal, "array") || !x.type->right->right - || x.type->right->right->value != Type_ordinal["location"] + || x.type->right->right->value != get(Type_ordinal, "location") || x.type->right->right->right) { raise_error << maybe(current_recipe_name()) << "'global-space' should be of type address:array:location, but tried to write " << to_string(data) << '\n' << end(); } diff --git a/048check_type_by_name.cc b/048check_type_by_name.cc index 938cacd5..a3deba6c 100644 --- a/048check_type_by_name.cc +++ b/048check_type_by_name.cc @@ -19,11 +19,11 @@ Transform.push_back(check_types_by_name); :(code) void check_types_by_name(const recipe_ordinal r) { - trace(9991, "transform") << "--- deduce types for recipe " << Recipe[r].name << end(); + trace(9991, "transform") << "--- deduce types for recipe " << get(Recipe, r).name << end(); map type; map type_name; - for (long long int i = 0; i < SIZE(Recipe[r].steps); ++i) { - instruction& inst = Recipe[r].steps.at(i); + for (long long int i = 0; i < SIZE(get(Recipe, r).steps); ++i) { + instruction& inst = get(Recipe, r).steps.at(i); for (long long int in = 0; in < SIZE(inst.ingredients); ++in) { deduce_missing_type(type, type_name, inst.ingredients.at(in)); check_type(type, type_name, inst.ingredients.at(in), r); @@ -49,7 +49,7 @@ void check_type(map& type, map& type_n type_name[x.name] = x.properties.at(0).second; } if (!types_match(type[x.name], x.type)) - raise_error << maybe(Recipe[r].name) << x.name << " used with multiple types\n" << end(); + raise_error << maybe(get(Recipe, r).name) << x.name << " used with multiple types\n" << end(); } :(scenario transform_fills_in_missing_types) diff --git a/050scenario.cc b/050scenario.cc index 31398ab8..e60ee771 100644 --- a/050scenario.cc +++ b/050scenario.cc @@ -188,7 +188,7 @@ recipe main [ :(before "End Primitive Recipe Declarations") RUN, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["run"] = RUN; +put(Recipe_ordinal, "run", RUN); :(before "End Primitive Recipe Checks") case RUN: { break; @@ -251,7 +251,7 @@ recipe main [ :(before "End Primitive Recipe Declarations") MEMORY_SHOULD_CONTAIN, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["memory-should-contain"] = MEMORY_SHOULD_CONTAIN; +put(Recipe_ordinal, "memory-should-contain", MEMORY_SHOULD_CONTAIN); :(before "End Primitive Recipe Checks") case MEMORY_SHOULD_CONTAIN: { break; @@ -284,14 +284,14 @@ void check_memory(const string& s) { if (locations_checked.find(address) != locations_checked.end()) raise_error << "duplicate expectation for location " << address << '\n' << end(); trace(9999, "run") << "checking location " << address << end(); - if (Memory[address] != value) { + if (get_or_insert(Memory, address) != value) { if (Current_scenario && !Scenario_testing_scenario) { // genuine test in a mu file - raise_error << "\nF - " << Current_scenario->name << ": expected location " << address << " to contain " << no_scientific(value) << " but saw " << no_scientific(Memory[address]) << '\n' << end(); + raise_error << "\nF - " << Current_scenario->name << ": expected location " << address << " to contain " << no_scientific(value) << " but saw " << no_scientific(get_or_insert(Memory, address)) << '\n' << end(); } else { // just testing scenario support - raise_error << "expected location " << address << " to contain " << no_scientific(value) << " but saw " << no_scientific(Memory[address]) << '\n' << end(); + raise_error << "expected location " << address << " to contain " << no_scientific(value) << " but saw " << no_scientific(get_or_insert(Memory, address)) << '\n' << end(); } if (!Scenario_testing_scenario) { Passed = false; @@ -324,11 +324,11 @@ void check_type(const string& lhs, istream& in) { void check_string(long long int address, const string& literal) { trace(9999, "run") << "checking string length at " << address << end(); - if (Memory[address] != SIZE(literal)) { + if (get_or_insert(Memory, address) != SIZE(literal)) { if (Current_scenario && !Scenario_testing_scenario) - raise_error << "\nF - " << Current_scenario->name << ": expected location " << address << " to contain length " << SIZE(literal) << " of string [" << literal << "] but saw " << no_scientific(Memory[address]) << '\n' << end(); + raise_error << "\nF - " << Current_scenario->name << ": expected location " << address << " to contain length " << SIZE(literal) << " of string [" << literal << "] but saw " << no_scientific(get_or_insert(Memory, address)) << '\n' << end(); else - raise_error << "expected location " << address << " to contain length " << SIZE(literal) << " of string [" << literal << "] but saw " << no_scientific(Memory[address]) << '\n' << end(); + raise_error << "expected location " << address << " to contain length " << SIZE(literal) << " of string [" << literal << "] but saw " << no_scientific(get_or_insert(Memory, address)) << '\n' << end(); if (!Scenario_testing_scenario) { Passed = false; ++Num_failures; @@ -338,14 +338,14 @@ void check_string(long long int address, const string& literal) { ++address; // now skip length for (long long int i = 0; i < SIZE(literal); ++i) { trace(9999, "run") << "checking location " << address+i << end(); - if (Memory[address+i] != literal.at(i)) { + if (get_or_insert(Memory, address+i) != literal.at(i)) { if (Current_scenario && !Scenario_testing_scenario) { // genuine test in a mu file - raise_error << "\nF - " << Current_scenario->name << ": expected location " << (address+i) << " to contain " << literal.at(i) << " but saw " << no_scientific(Memory[address+i]) << '\n' << end(); + raise_error << "\nF - " << Current_scenario->name << ": expected location " << (address+i) << " to contain " << literal.at(i) << " but saw " << no_scientific(get_or_insert(Memory, address+i)) << '\n' << end(); } else { // just testing scenario support - raise_error << "expected location " << (address+i) << " to contain " << literal.at(i) << " but saw " << no_scientific(Memory[address+i]) << '\n' << end(); + raise_error << "expected location " << (address+i) << " to contain " << literal.at(i) << " but saw " << no_scientific(get_or_insert(Memory, address+i)) << '\n' << end(); } if (!Scenario_testing_scenario) { Passed = false; @@ -416,7 +416,7 @@ recipe main [ :(before "End Primitive Recipe Declarations") TRACE_SHOULD_CONTAIN, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["trace-should-contain"] = TRACE_SHOULD_CONTAIN; +put(Recipe_ordinal, "trace-should-contain", TRACE_SHOULD_CONTAIN); :(before "End Primitive Recipe Checks") case TRACE_SHOULD_CONTAIN: { break; @@ -512,7 +512,7 @@ recipe main [ :(before "End Primitive Recipe Declarations") TRACE_SHOULD_NOT_CONTAIN, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["trace-should-not-contain"] = TRACE_SHOULD_NOT_CONTAIN; +put(Recipe_ordinal, "trace-should-not-contain", TRACE_SHOULD_NOT_CONTAIN); :(before "End Primitive Recipe Checks") case TRACE_SHOULD_NOT_CONTAIN: { break; @@ -576,19 +576,19 @@ recipe main [ :(before "End Primitive Recipe Declarations") CHECK_TRACE_COUNT_FOR_LABEL, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["check-trace-count-for-label"] = CHECK_TRACE_COUNT_FOR_LABEL; +put(Recipe_ordinal, "check-trace-count-for-label", CHECK_TRACE_COUNT_FOR_LABEL); :(before "End Primitive Recipe Checks") case CHECK_TRACE_COUNT_FOR_LABEL: { if (SIZE(inst.ingredients) != 2) { - raise_error << maybe(Recipe[r].name) << "'check-trace-for-label' requires exactly two ingredients, but got '" << inst.to_string() << "'\n" << end(); + raise_error << maybe(get(Recipe, r).name) << "'check-trace-for-label' requires exactly two ingredients, but got '" << inst.to_string() << "'\n" << end(); break; } if (!is_mu_number(inst.ingredients.at(0))) { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'check-trace-for-label' should be a number (count), but got " << inst.ingredients.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'check-trace-for-label' should be a number (count), but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } if (!is_literal_string(inst.ingredients.at(1))) { - raise_error << maybe(Recipe[r].name) << "second ingredient of 'check-trace-for-label' should be a literal string (label), but got " << inst.ingredients.at(1).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "second ingredient of 'check-trace-for-label' should be a literal string (label), but got " << inst.ingredients.at(1).original_string << '\n' << end(); break; } break; diff --git a/052tangle.cc b/052tangle.cc index 0582f79f..c3bc7e46 100644 --- a/052tangle.cc +++ b/052tangle.cc @@ -73,8 +73,8 @@ void insert_fragments(const recipe_ordinal r) { made_progress = false; // create a new vector because insertions invalidate iterators vector result; - for (long long int i = 0; i < SIZE(Recipe[r].steps); ++i) { - const instruction& inst = Recipe[r].steps.at(i); + for (long long int i = 0; i < SIZE(get(Recipe, r).steps); ++i) { + const instruction& inst = get(Recipe, r).steps.at(i); if (!inst.is_label || !is_waypoint(inst.label) || inst.tangle_done) { result.push_back(inst); continue; @@ -83,7 +83,7 @@ void insert_fragments(const recipe_ordinal r) { made_progress = true; Fragments_used.insert(inst.label); ostringstream prefix; - prefix << '+' << Recipe[r].name << '_' << pass << '_' << i; + prefix << '+' << get(Recipe, r).name << '_' << pass << '_' << i; if (Before_fragments.find(inst.label) != Before_fragments.end()) { append_fragment(result, Before_fragments[inst.label].steps, prefix.str()); } @@ -92,7 +92,7 @@ void insert_fragments(const recipe_ordinal r) { append_fragment(result, After_fragments[inst.label].steps, prefix.str()); } } - Recipe[r].steps.swap(result); + get(Recipe, r).steps.swap(result); ++pass; } } diff --git a/054dilated_reagent.cc b/054dilated_reagent.cc index 46f5f8ab..5ac1c97e 100644 --- a/054dilated_reagent.cc +++ b/054dilated_reagent.cc @@ -86,9 +86,9 @@ if (s.at(0) == '{') { string type_name = properties.at(0).second->value; if (Type_ordinal.find(type_name) == Type_ordinal.end()) { // this type can't be an integer literal - Type_ordinal[type_name] = Next_type_ordinal++; + put(Type_ordinal, type_name, Next_type_ordinal++); } - type = new type_tree(Type_ordinal[type_name]); + type = new type_tree(get(Type_ordinal, type_name)); return; } diff --git a/056recipe_header.cc b/056recipe_header.cc index bcea6328..cb63b013 100644 --- a/056recipe_header.cc +++ b/056recipe_header.cc @@ -80,7 +80,7 @@ if (result.has_header) { if (curr.name == "load-ingredients") { curr.clear(); for (long long int i = 0; i < SIZE(result.ingredients); ++i) { - curr.operation = Recipe_ordinal["next-ingredient"]; + curr.operation = get(Recipe_ordinal, "next-ingredient"); curr.name = "next-ingredient"; curr.products.push_back(result.ingredients.at(i)); result.steps.push_back(curr); @@ -106,7 +106,7 @@ Transform.push_back(check_header_products); :(code) void check_header_products(const recipe_ordinal r) { - const recipe& rr = Recipe[r]; + const recipe& rr = get(Recipe, r); if (rr.products.empty()) return; trace(9991, "transform") << "--- checking reply instructions against header for " << rr.name << end(); for (long long int i = 0; i < SIZE(rr.steps); ++i) { @@ -143,7 +143,7 @@ Transform.push_back(deduce_types_from_header); :(code) void deduce_types_from_header(const recipe_ordinal r) { - recipe& rr = Recipe[r]; + recipe& rr = get(Recipe, r); if (rr.products.empty()) return; trace(9991, "transform") << "--- deduce types from header for " << rr.name << end(); map header; @@ -197,13 +197,13 @@ Transform.push_back(fill_in_reply_ingredients); :(code) void fill_in_reply_ingredients(recipe_ordinal r) { - if (!Recipe[r].has_header) return; - trace(9991, "transform") << "--- fill in reply ingredients from header for recipe " << Recipe[r].name << end(); - for (long long int i = 0; i < SIZE(Recipe[r].steps); ++i) { - instruction& inst = Recipe[r].steps.at(i); + if (!get(Recipe, r).has_header) return; + trace(9991, "transform") << "--- fill in reply ingredients from header for recipe " << get(Recipe, r).name << end(); + for (long long int i = 0; i < SIZE(get(Recipe, r).steps); ++i) { + instruction& inst = get(Recipe, r).steps.at(i); if (inst.name == "reply" && inst.ingredients.empty()) { - for (long long int i = 0; i < SIZE(Recipe[r].products); ++i) - inst.ingredients.push_back(Recipe[r].products.at(i)); + for (long long int i = 0; i < SIZE(get(Recipe, r).products); ++i) + inst.ingredients.push_back(get(Recipe, r).products.at(i)); } } } @@ -239,7 +239,7 @@ Transform.push_back(deduce_fallthrough_reply); :(code) void deduce_fallthrough_reply(const recipe_ordinal r) { - recipe& rr = Recipe[r]; + recipe& rr = get(Recipe, r); if (rr.products.empty()) return; if (rr.steps.empty()) return; if (rr.steps.at(SIZE(rr.steps)-1).name != "reply") { diff --git a/057static_dispatch.cc b/057static_dispatch.cc index 3bac046e..905cbaf2 100644 --- a/057static_dispatch.cc +++ b/057static_dispatch.cc @@ -29,19 +29,19 @@ for (map >::iterator p = Recipe_variants.begin(); :(before "End Load Recipe Header(result)") if (Recipe_ordinal.find(result.name) != Recipe_ordinal.end()) { - if ((Recipe.find(Recipe_ordinal[result.name]) == Recipe.end() - || Recipe[Recipe_ordinal[result.name]].has_header) + if ((Recipe.find(get(Recipe_ordinal, result.name)) == Recipe.end() + || get(Recipe, get(Recipe_ordinal, result.name)).has_header) && !header_already_exists(result)) { string new_name = next_unused_recipe_name(result.name); - Recipe_ordinal[new_name] = Next_recipe_ordinal++; - Recipe_variants[result.name].push_back(Recipe_ordinal[new_name]); + put(Recipe_ordinal, new_name, Next_recipe_ordinal++); + Recipe_variants[result.name].push_back(get(Recipe_ordinal, new_name)); result.name = new_name; } } else { // save first variant - Recipe_ordinal[result.name] = Next_recipe_ordinal++; - Recipe_variants[result.name].push_back(Recipe_ordinal[result.name]); + put(Recipe_ordinal, result.name, Next_recipe_ordinal++); + Recipe_variants[result.name].push_back(get(Recipe_ordinal, result.name)); } :(code) @@ -49,7 +49,7 @@ bool header_already_exists(const recipe& rr) { const vector& variants = Recipe_variants[rr.name]; for (long long int i = 0; i < SIZE(variants); ++i) { if (Recipe.find(variants.at(i)) != Recipe.end() - && all_reagents_match(rr, Recipe[variants.at(i)])) { + && all_reagents_match(rr, get(Recipe, variants.at(i)))) { return true; } } @@ -108,10 +108,10 @@ Transform.push_back(resolve_ambiguous_calls); :(code) void resolve_ambiguous_calls(recipe_ordinal r) { - if (!Recipe[r].has_header) return; - trace(9991, "transform") << "--- resolve ambiguous calls for recipe " << Recipe[r].name << end(); - for (long long int index = 0; index < SIZE(Recipe[r].steps); ++index) { - instruction& inst = Recipe[r].steps.at(index); + if (!get(Recipe, r).has_header) return; + trace(9991, "transform") << "--- resolve ambiguous calls for recipe " << get(Recipe, r).name << end(); + for (long long int index = 0; index < SIZE(get(Recipe, r).steps); ++index) { + instruction& inst = get(Recipe, r).steps.at(index); if (inst.is_label) continue; if (Recipe_variants.find(inst.name) == Recipe_variants.end()) continue; assert(!Recipe_variants[inst.name].empty()); @@ -122,12 +122,12 @@ void resolve_ambiguous_calls(recipe_ordinal r) { void replace_best_variant(instruction& inst) { trace(9992, "transform") << "instruction " << inst.name << end(); vector& variants = Recipe_variants[inst.name]; - long long int best_score = variant_score(inst, Recipe_ordinal[inst.name]); + long long int best_score = variant_score(inst, get(Recipe_ordinal, inst.name)); for (long long int i = 0; i < SIZE(variants); ++i) { long long int current_score = variant_score(inst, variants.at(i)); trace(9992, "transform") << "checking variant " << i << ": " << current_score << end(); if (current_score > best_score) { - inst.name = Recipe[variants.at(i)].name; + inst.name = get(Recipe, variants.at(i)).name; best_score = current_score; } } @@ -136,7 +136,7 @@ void replace_best_variant(instruction& inst) { long long int variant_score(const instruction& inst, recipe_ordinal variant) { if (variant == -1) return -1; - const vector& header_ingredients = Recipe[variant].ingredients; + const vector& header_ingredients = get(Recipe, variant).ingredients; if (SIZE(inst.ingredients) < SIZE(header_ingredients)) { trace(9993, "transform") << "too few ingredients" << end(); return -1; @@ -147,11 +147,11 @@ long long int variant_score(const instruction& inst, recipe_ordinal variant) { return -1; } } - if (SIZE(inst.products) > SIZE(Recipe[variant].products)) { + if (SIZE(inst.products) > SIZE(get(Recipe, variant).products)) { trace(9993, "transform") << "too few products" << end(); return -1; } - const vector& header_products = Recipe[variant].products; + const vector& header_products = get(Recipe, variant).products; for (long long int i = 0; i < SIZE(inst.products); ++i) { if (!types_match(header_products.at(i), inst.products.at(i))) { trace(9993, "transform") << "mismatch: product " << i << end(); @@ -159,8 +159,8 @@ long long int variant_score(const instruction& inst, recipe_ordinal variant) { } } // the greater the number of unused ingredients, the lower the score - return 100 - (SIZE(Recipe[variant].products)-SIZE(inst.products)) - - (SIZE(inst.ingredients)-SIZE(Recipe[variant].ingredients)); // ok to go negative + return 100 - (SIZE(get(Recipe, variant).products)-SIZE(inst.products)) + - (SIZE(inst.ingredients)-SIZE(get(Recipe, variant).ingredients)); // ok to go negative } :(scenario static_dispatch_disabled_on_headerless_definition) diff --git a/058generic_container.cc b/058generic_container.cc index e757143b..6ba05d5e 100644 --- a/058generic_container.cc +++ b/058generic_container.cc @@ -50,9 +50,9 @@ void read_type_ingredients(string& name) { string save_name = name; istringstream in(save_name); name = slurp_until(in, ':'); - if (Type_ordinal.find(name) == Type_ordinal.end() || Type_ordinal[name] == 0) - Type_ordinal[name] = Next_type_ordinal++; - type_info& info = Type[Type_ordinal[name]]; + if (Type_ordinal.find(name) == Type_ordinal.end() || get(Type_ordinal, name) == 0) + put(Type_ordinal, name, Next_type_ordinal++); + type_info& info = get(Type, get(Type_ordinal, name)); long long int next_type_ordinal = START_TYPE_INGREDIENTS; while (!in.eof()) { string curr = slurp_until(in, ':'); @@ -74,7 +74,7 @@ if (type_name.at(0) == '_') { :(before "End Container Type Checks") if (type->value >= START_TYPE_INGREDIENTS - && (type->value - START_TYPE_INGREDIENTS) < SIZE(Type[type->value].type_ingredient_names)) + && (type->value - START_TYPE_INGREDIENTS) < SIZE(get(Type, type->value).type_ingredient_names)) return; :(before "End size_of(type) Container Cases") @@ -103,7 +103,7 @@ long long int size_of_type_ingredient(const type_tree* element_template, const t } assert(curr); assert(!curr->left); // unimplemented - trace(9999, "type") << "type deduced to be " << Type[curr->value].name << "$" << end(); + trace(9999, "type") << "type deduced to be " << get(Type, curr->value).name << "$" << end(); type_tree tmp(curr->value); if (curr->right) tmp.right = new type_tree(*curr->right); @@ -122,8 +122,8 @@ recipe main [ +mem: storing 16 in location 2 :(before "End GET field Cases") -if (Type[base_type].elements.at(i)->value >= START_TYPE_INGREDIENTS) { - src += size_of_type_ingredient(Type[base_type].elements.at(i), base.type->right); +if (get(Type, base_type).elements.at(i)->value >= START_TYPE_INGREDIENTS) { + src += size_of_type_ingredient(get(Type, base_type).elements.at(i), base.type->right); continue; } @@ -212,8 +212,8 @@ recipe main [ +mem: storing 12 in location 1 :(before "End GET_ADDRESS field Cases") -if (Type[base_type].elements.at(i)->value >= START_TYPE_INGREDIENTS) { - result += size_of_type_ingredient(Type[base_type].elements.at(i), base.type->right); +if (get(Type, base_type).elements.at(i)->value >= START_TYPE_INGREDIENTS) { + result += size_of_type_ingredient(get(Type, base_type).elements.at(i), base.type->right); continue; } diff --git a/059generic_recipe.cc b/059generic_recipe.cc index 2fe08c27..106d5a14 100644 --- a/059generic_recipe.cc +++ b/059generic_recipe.cc @@ -31,9 +31,9 @@ if (best_score == -1) { trace(9992, "transform") << "no variant found; searching for variant with suitable type ingredients" << end(); recipe_ordinal exemplar = pick_matching_generic_variant(variants, inst, best_score); if (exemplar) { - trace(9992, "transform") << "found variant to specialize: " << exemplar << ' ' << Recipe[exemplar].name << end(); + trace(9992, "transform") << "found variant to specialize: " << exemplar << ' ' << get(Recipe, exemplar).name << end(); variants.push_back(new_variant(exemplar, inst)); - inst.name = Recipe[variants.back()].name; + inst.name = get(Recipe, variants.back()).name; trace(9992, "transform") << "new specialization: " << inst.name << end(); } } @@ -65,7 +65,7 @@ long long int generic_variant_score(const instruction& inst, recipe_ordinal vari trace(9993, "transform") << "no type ingredients" << end(); return -1; } - const vector& header_ingredients = Recipe[variant].ingredients; + const vector& header_ingredients = get(Recipe, variant).ingredients; if (SIZE(inst.ingredients) < SIZE(header_ingredients)) { trace(9993, "transform") << "too few ingredients" << end(); return -1; @@ -76,11 +76,11 @@ long long int generic_variant_score(const instruction& inst, recipe_ordinal vari return -1; } } - if (SIZE(inst.products) > SIZE(Recipe[variant].products)) { + if (SIZE(inst.products) > SIZE(get(Recipe, variant).products)) { trace(9993, "transform") << "too few products" << end(); return -1; } - const vector& header_products = Recipe[variant].products; + const vector& header_products = get(Recipe, variant).products; for (long long int i = 0; i < SIZE(inst.products); ++i) { if (!non_type_ingredients_match(header_products.at(i), inst.products.at(i))) { trace(9993, "transform") << "mismatch: product " << i << end(); @@ -88,13 +88,13 @@ long long int generic_variant_score(const instruction& inst, recipe_ordinal vari } } // the greater the number of unused ingredients, the lower the score - return 100 - (SIZE(Recipe[variant].products)-SIZE(inst.products)) - - (SIZE(inst.ingredients)-SIZE(Recipe[variant].ingredients)); // ok to go negative + return 100 - (SIZE(get(Recipe, variant).products)-SIZE(inst.products)) + - (SIZE(inst.ingredients)-SIZE(get(Recipe, variant).ingredients)); // ok to go negative } bool any_type_ingredient_in_header(recipe_ordinal variant) { - for (long long int i = 0; i < SIZE(Recipe[variant].ingredients); ++i) { - if (contains_type_ingredient_name(Recipe[variant].ingredients.at(i))) + for (long long int i = 0; i < SIZE(get(Recipe, variant).ingredients); ++i) { + if (contains_type_ingredient_name(get(Recipe, variant).ingredients.at(i))) return true; } return false; @@ -123,18 +123,18 @@ recipe_ordinal new_variant(recipe_ordinal exemplar, const instruction& inst) { string new_name = next_unused_recipe_name(inst.name); trace(9993, "transform") << "switching " << inst.name << " to " << new_name << end(); assert(Recipe_ordinal.find(new_name) == Recipe_ordinal.end()); - recipe_ordinal result = Recipe_ordinal[new_name] = Next_recipe_ordinal++; + recipe_ordinal result = put(Recipe_ordinal, new_name, Next_recipe_ordinal++); // make a copy assert(Recipe.find(exemplar) != Recipe.end()); assert(Recipe.find(result) == Recipe.end()); recently_added_recipes.push_back(result); - Recipe[result] = Recipe[exemplar]; - recipe& new_recipe = Recipe[result]; + put(Recipe, result, get(Recipe, exemplar)); + recipe& new_recipe = get(Recipe, result); // update its name new_recipe.name = new_name; // update its contents map mappings; // weak references - compute_type_ingredient_mappings(Recipe[exemplar], inst, mappings); + compute_type_ingredient_mappings(get(Recipe, exemplar), inst, mappings); replace_type_ingredients(new_recipe, mappings); return result; } diff --git a/064random.cc b/064random.cc index 12e1b848..69ed8b2c 100644 --- a/064random.cc +++ b/064random.cc @@ -1,7 +1,7 @@ :(before "End Primitive Recipe Declarations") RANDOM, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["random"] = RANDOM; +put(Recipe_ordinal, "random", RANDOM); :(before "End Primitive Recipe Checks") case RANDOM: { break; @@ -18,7 +18,7 @@ case RANDOM: { :(before "End Primitive Recipe Declarations") MAKE_RANDOM_NONDETERMINISTIC, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["make-random-nondeterministic"] = MAKE_RANDOM_NONDETERMINISTIC; +put(Recipe_ordinal, "make-random-nondeterministic", MAKE_RANDOM_NONDETERMINISTIC); :(before "End Primitive Recipe Checks") case MAKE_RANDOM_NONDETERMINISTIC: { break; @@ -32,15 +32,15 @@ case MAKE_RANDOM_NONDETERMINISTIC: { :(before "End Primitive Recipe Declarations") ROUND, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["round"] = ROUND; +put(Recipe_ordinal, "round", ROUND); :(before "End Primitive Recipe Checks") case ROUND: { if (SIZE(inst.ingredients) != 1) { - raise_error << maybe(Recipe[r].name) << "'round' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'round' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end(); break; } if (!is_mu_number(inst.ingredients.at(0))) { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'round' should be a number, but got " << inst.ingredients.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'round' should be a number, but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } break; diff --git a/070display.cc b/070display.cc index 49668a99..970887bd 100644 --- a/070display.cc +++ b/070display.cc @@ -9,7 +9,7 @@ bool Autodisplay = true; :(before "End Primitive Recipe Declarations") OPEN_CONSOLE, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["open-console"] = OPEN_CONSOLE; +put(Recipe_ordinal, "open-console", OPEN_CONSOLE); :(before "End Primitive Recipe Checks") case OPEN_CONSOLE: { break; @@ -31,7 +31,7 @@ case OPEN_CONSOLE: { :(before "End Primitive Recipe Declarations") CLOSE_CONSOLE, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["close-console"] = CLOSE_CONSOLE; +put(Recipe_ordinal, "close-console", CLOSE_CONSOLE); :(before "End Primitive Recipe Checks") case CLOSE_CONSOLE: { break; @@ -48,7 +48,7 @@ tb_shutdown(); :(before "End Primitive Recipe Declarations") CLEAR_DISPLAY, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["clear-display"] = CLEAR_DISPLAY; +put(Recipe_ordinal, "clear-display", CLEAR_DISPLAY); :(before "End Primitive Recipe Checks") case CLEAR_DISPLAY: { break; @@ -63,7 +63,7 @@ case CLEAR_DISPLAY: { :(before "End Primitive Recipe Declarations") SYNC_DISPLAY, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["sync-display"] = SYNC_DISPLAY; +put(Recipe_ordinal, "sync-display", SYNC_DISPLAY); :(before "End Primitive Recipe Checks") case SYNC_DISPLAY: { break; @@ -77,7 +77,7 @@ case SYNC_DISPLAY: { :(before "End Primitive Recipe Declarations") CLEAR_LINE_ON_DISPLAY, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["clear-line-on-display"] = CLEAR_LINE_ON_DISPLAY; +put(Recipe_ordinal, "clear-line-on-display", CLEAR_LINE_ON_DISPLAY); :(before "End Primitive Recipe Checks") case CLEAR_LINE_ON_DISPLAY: { break; @@ -96,26 +96,26 @@ case CLEAR_LINE_ON_DISPLAY: { :(before "End Primitive Recipe Declarations") PRINT_CHARACTER_TO_DISPLAY, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["print-character-to-display"] = PRINT_CHARACTER_TO_DISPLAY; +put(Recipe_ordinal, "print-character-to-display", PRINT_CHARACTER_TO_DISPLAY); :(before "End Primitive Recipe Checks") case PRINT_CHARACTER_TO_DISPLAY: { if (inst.ingredients.empty()) { - raise_error << maybe(Recipe[r].name) << "'print-character-to-display' requires at least one ingredient, but got " << inst.to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'print-character-to-display' requires at least one ingredient, but got " << inst.to_string() << '\n' << end(); break; } if (!is_mu_number(inst.ingredients.at(0))) { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'print-character-to-display' should be a character, but got " << inst.ingredients.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'print-character-to-display' should be a character, but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } if (SIZE(inst.ingredients) > 1) { if (!is_mu_number(inst.ingredients.at(1))) { - raise_error << maybe(Recipe[r].name) << "second ingredient of 'print-character-to-display' should be a foreground color number, but got " << inst.ingredients.at(1).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "second ingredient of 'print-character-to-display' should be a foreground color number, but got " << inst.ingredients.at(1).original_string << '\n' << end(); break; } } if (SIZE(inst.ingredients) > 2) { if (!is_mu_number(inst.ingredients.at(2))) { - raise_error << maybe(Recipe[r].name) << "third ingredient of 'print-character-to-display' should be a background color number, but got " << inst.ingredients.at(2).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "third ingredient of 'print-character-to-display' should be a background color number, but got " << inst.ingredients.at(2).original_string << '\n' << end(); break; } } @@ -166,7 +166,7 @@ case PRINT_CHARACTER_TO_DISPLAY: { :(before "End Primitive Recipe Declarations") CURSOR_POSITION_ON_DISPLAY, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["cursor-position-on-display"] = CURSOR_POSITION_ON_DISPLAY; +put(Recipe_ordinal, "cursor-position-on-display", CURSOR_POSITION_ON_DISPLAY); :(before "End Primitive Recipe Checks") case CURSOR_POSITION_ON_DISPLAY: { break; @@ -182,19 +182,19 @@ case CURSOR_POSITION_ON_DISPLAY: { :(before "End Primitive Recipe Declarations") MOVE_CURSOR_ON_DISPLAY, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["move-cursor-on-display"] = MOVE_CURSOR_ON_DISPLAY; +put(Recipe_ordinal, "move-cursor-on-display", MOVE_CURSOR_ON_DISPLAY); :(before "End Primitive Recipe Checks") case MOVE_CURSOR_ON_DISPLAY: { if (SIZE(inst.ingredients) != 2) { - raise_error << maybe(Recipe[r].name) << "'move-cursor-on-display' requires two ingredients, but got " << inst.to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'move-cursor-on-display' requires two ingredients, but got " << inst.to_string() << '\n' << end(); break; } if (!is_mu_number(inst.ingredients.at(0))) { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'move-cursor-on-display' should be a row number, but got " << inst.ingredients.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'move-cursor-on-display' should be a row number, but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } if (!is_mu_number(inst.ingredients.at(1))) { - raise_error << maybe(Recipe[r].name) << "second ingredient of 'move-cursor-on-display' should be a column number, but got " << inst.ingredients.at(1).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "second ingredient of 'move-cursor-on-display' should be a column number, but got " << inst.ingredients.at(1).original_string << '\n' << end(); break; } break; @@ -211,7 +211,7 @@ case MOVE_CURSOR_ON_DISPLAY: { :(before "End Primitive Recipe Declarations") MOVE_CURSOR_DOWN_ON_DISPLAY, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["move-cursor-down-on-display"] = MOVE_CURSOR_DOWN_ON_DISPLAY; +put(Recipe_ordinal, "move-cursor-down-on-display", MOVE_CURSOR_DOWN_ON_DISPLAY); :(before "End Primitive Recipe Checks") case MOVE_CURSOR_DOWN_ON_DISPLAY: { break; @@ -231,7 +231,7 @@ case MOVE_CURSOR_DOWN_ON_DISPLAY: { :(before "End Primitive Recipe Declarations") MOVE_CURSOR_UP_ON_DISPLAY, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["move-cursor-up-on-display"] = MOVE_CURSOR_UP_ON_DISPLAY; +put(Recipe_ordinal, "move-cursor-up-on-display", MOVE_CURSOR_UP_ON_DISPLAY); :(before "End Primitive Recipe Checks") case MOVE_CURSOR_UP_ON_DISPLAY: { break; @@ -249,7 +249,7 @@ case MOVE_CURSOR_UP_ON_DISPLAY: { :(before "End Primitive Recipe Declarations") MOVE_CURSOR_RIGHT_ON_DISPLAY, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["move-cursor-right-on-display"] = MOVE_CURSOR_RIGHT_ON_DISPLAY; +put(Recipe_ordinal, "move-cursor-right-on-display", MOVE_CURSOR_RIGHT_ON_DISPLAY); :(before "End Primitive Recipe Checks") case MOVE_CURSOR_RIGHT_ON_DISPLAY: { break; @@ -269,7 +269,7 @@ case MOVE_CURSOR_RIGHT_ON_DISPLAY: { :(before "End Primitive Recipe Declarations") MOVE_CURSOR_LEFT_ON_DISPLAY, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["move-cursor-left-on-display"] = MOVE_CURSOR_LEFT_ON_DISPLAY; +put(Recipe_ordinal, "move-cursor-left-on-display", MOVE_CURSOR_LEFT_ON_DISPLAY); :(before "End Primitive Recipe Checks") case MOVE_CURSOR_LEFT_ON_DISPLAY: { break; @@ -287,7 +287,7 @@ case MOVE_CURSOR_LEFT_ON_DISPLAY: { :(before "End Primitive Recipe Declarations") DISPLAY_WIDTH, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["display-width"] = DISPLAY_WIDTH; +put(Recipe_ordinal, "display-width", DISPLAY_WIDTH); :(before "End Primitive Recipe Checks") case DISPLAY_WIDTH: { break; @@ -302,7 +302,7 @@ case DISPLAY_WIDTH: { :(before "End Primitive Recipe Declarations") DISPLAY_HEIGHT, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["display-height"] = DISPLAY_HEIGHT; +put(Recipe_ordinal, "display-height", DISPLAY_HEIGHT); :(before "End Primitive Recipe Checks") case DISPLAY_HEIGHT: { break; @@ -317,7 +317,7 @@ case DISPLAY_HEIGHT: { :(before "End Primitive Recipe Declarations") HIDE_CURSOR_ON_DISPLAY, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["hide-cursor-on-display"] = HIDE_CURSOR_ON_DISPLAY; +put(Recipe_ordinal, "hide-cursor-on-display", HIDE_CURSOR_ON_DISPLAY); :(before "End Primitive Recipe Checks") case HIDE_CURSOR_ON_DISPLAY: { break; @@ -331,7 +331,7 @@ case HIDE_CURSOR_ON_DISPLAY: { :(before "End Primitive Recipe Declarations") SHOW_CURSOR_ON_DISPLAY, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["show-cursor-on-display"] = SHOW_CURSOR_ON_DISPLAY; +put(Recipe_ordinal, "show-cursor-on-display", SHOW_CURSOR_ON_DISPLAY); :(before "End Primitive Recipe Checks") case SHOW_CURSOR_ON_DISPLAY: { break; @@ -345,7 +345,7 @@ case SHOW_CURSOR_ON_DISPLAY: { :(before "End Primitive Recipe Declarations") HIDE_DISPLAY, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["hide-display"] = HIDE_DISPLAY; +put(Recipe_ordinal, "hide-display", HIDE_DISPLAY); :(before "End Primitive Recipe Checks") case HIDE_DISPLAY: { break; @@ -359,7 +359,7 @@ case HIDE_DISPLAY: { :(before "End Primitive Recipe Declarations") SHOW_DISPLAY, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["show-display"] = SHOW_DISPLAY; +put(Recipe_ordinal, "show-display", SHOW_DISPLAY); :(before "End Primitive Recipe Checks") case SHOW_DISPLAY: { break; @@ -376,7 +376,7 @@ case SHOW_DISPLAY: { :(before "End Primitive Recipe Declarations") WAIT_FOR_SOME_INTERACTION, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["wait-for-some-interaction"] = WAIT_FOR_SOME_INTERACTION; +put(Recipe_ordinal, "wait-for-some-interaction", WAIT_FOR_SOME_INTERACTION); :(before "End Primitive Recipe Checks") case WAIT_FOR_SOME_INTERACTION: { break; @@ -391,7 +391,7 @@ case WAIT_FOR_SOME_INTERACTION: { :(before "End Primitive Recipe Declarations") CHECK_FOR_INTERACTION, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["check-for-interaction"] = CHECK_FOR_INTERACTION; +put(Recipe_ordinal, "check-for-interaction", CHECK_FOR_INTERACTION); :(before "End Primitive Recipe Checks") case CHECK_FOR_INTERACTION: { break; @@ -458,7 +458,7 @@ case CHECK_FOR_INTERACTION: { :(before "End Primitive Recipe Declarations") INTERACTIONS_LEFT, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["interactions-left?"] = INTERACTIONS_LEFT; +put(Recipe_ordinal, "interactions-left?", INTERACTIONS_LEFT); :(before "End Primitive Recipe Checks") case INTERACTIONS_LEFT: { break; @@ -475,7 +475,7 @@ case INTERACTIONS_LEFT: { :(before "End Primitive Recipe Declarations") CLEAR_DISPLAY_FROM, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["clear-display-from"] = CLEAR_DISPLAY_FROM; +put(Recipe_ordinal, "clear-display-from", CLEAR_DISPLAY_FROM); :(before "End Primitive Recipe Checks") case CLEAR_DISPLAY_FROM: { break; diff --git a/072scenario_screen.cc b/072scenario_screen.cc index 97002005..a82862c0 100644 --- a/072scenario_screen.cc +++ b/072scenario_screen.cc @@ -151,7 +151,7 @@ if (curr.name == "assume-screen") { :(before "End Primitive Recipe Declarations") SCREEN_SHOULD_CONTAIN, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["screen-should-contain"] = SCREEN_SHOULD_CONTAIN; +put(Recipe_ordinal, "screen-should-contain", SCREEN_SHOULD_CONTAIN); :(before "End Primitive Recipe Checks") case SCREEN_SHOULD_CONTAIN: { break; @@ -166,7 +166,7 @@ case SCREEN_SHOULD_CONTAIN: { :(before "End Primitive Recipe Declarations") SCREEN_SHOULD_CONTAIN_IN_COLOR, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["screen-should-contain-in-color"] = SCREEN_SHOULD_CONTAIN_IN_COLOR; +put(Recipe_ordinal, "screen-should-contain-in-color", SCREEN_SHOULD_CONTAIN_IN_COLOR); :(before "End Primitive Recipe Checks") case SCREEN_SHOULD_CONTAIN_IN_COLOR: { break; @@ -196,15 +196,15 @@ struct raw_string_stream { :(code) void check_screen(const string& expected_contents, const int color) { assert(!current_call().default_space); // not supported - long long int screen_location = Memory[SCREEN]; - int data_offset = find_element_name(Type_ordinal["screen"], "data", ""); + long long int screen_location = get_or_insert(Memory, SCREEN); + int data_offset = find_element_name(get(Type_ordinal, "screen"), "data", ""); assert(data_offset >= 0); long long int screen_data_location = screen_location+data_offset; // type: address:array:character - long long int screen_data_start = Memory[screen_data_location]; // type: array:character - int width_offset = find_element_name(Type_ordinal["screen"], "num-columns", ""); - long long int screen_width = Memory[screen_location+width_offset]; - int height_offset = find_element_name(Type_ordinal["screen"], "num-rows", ""); - long long int screen_height = Memory[screen_location+height_offset]; + long long int screen_data_start = get_or_insert(Memory, screen_data_location); // type: array:character + int width_offset = find_element_name(get(Type_ordinal, "screen"), "num-columns", ""); + long long int screen_width = get_or_insert(Memory, screen_location+width_offset); + int height_offset = find_element_name(get(Type_ordinal, "screen"), "num-rows", ""); + long long int screen_height = get_or_insert(Memory, screen_location+height_offset); raw_string_stream cursor(expected_contents); // todo: too-long expected_contents should fail long long int addr = screen_data_start+1; // skip length @@ -215,21 +215,21 @@ void check_screen(const string& expected_contents, const int color) { for (long long int column = 0; column < screen_width; ++column, addr+= /*size of screen-cell*/2) { const int cell_color_offset = 1; uint32_t curr = cursor.get(); - if (Memory[addr] == 0 && isspace(curr)) continue; - if (curr == ' ' && color != -1 && color != Memory[addr+cell_color_offset]) { + if (get_or_insert(Memory, addr) == 0 && isspace(curr)) continue; + if (curr == ' ' && color != -1 && color != get_or_insert(Memory, addr+cell_color_offset)) { // filter out other colors continue; } - if (Memory[addr] != 0 && Memory[addr] == curr) { - if (color == -1 || color == Memory[addr+cell_color_offset]) continue; + if (get_or_insert(Memory, addr) != 0 && Memory[addr] == curr) { + if (color == -1 || color == get_or_insert(Memory, addr+cell_color_offset)) continue; // contents match but color is off if (Current_scenario && !Scenario_testing_scenario) { // genuine test in a mu file - raise_error << "\nF - " << Current_scenario->name << ": expected screen location (" << row << ", " << column << ", address " << addr << ", value " << no_scientific(Memory[addr]) << ") to be in color " << color << " instead of " << no_scientific(Memory[addr+cell_color_offset]) << "\n" << end(); + raise_error << "\nF - " << Current_scenario->name << ": expected screen location (" << row << ", " << column << ", address " << addr << ", value " << no_scientific(get_or_insert(Memory, addr)) << ") to be in color " << color << " instead of " << no_scientific(Memory[addr+cell_color_offset]) << "\n" << end(); } else { // just testing check_screen - raise_error << "expected screen location (" << row << ", " << column << ") to be in color " << color << " instead of " << no_scientific(Memory[addr+cell_color_offset]) << '\n' << end(); + raise_error << "expected screen location (" << row << ", " << column << ") to be in color " << color << " instead of " << no_scientific(get_or_insert(Memory, addr+cell_color_offset)) << '\n' << end(); } if (!Scenario_testing_scenario) { Passed = false; @@ -246,21 +246,21 @@ void check_screen(const string& expected_contents, const int color) { expected_pretty[0] = ' ', expected_pretty[1] = '(', expected_pretty[2] = '\'', expected_pretty[3] = static_cast(curr), expected_pretty[4] = '\'', expected_pretty[5] = ')', expected_pretty[6] = '\0'; } char actual_pretty[10] = {0}; - if (Memory[addr] < 256 && !iscntrl(Memory[addr])) { + if (get_or_insert(Memory, addr) < 256 && !iscntrl(Memory[addr])) { // " ('')" - actual_pretty[0] = ' ', actual_pretty[1] = '(', actual_pretty[2] = '\'', actual_pretty[3] = static_cast(Memory[addr]), actual_pretty[4] = '\'', actual_pretty[5] = ')', actual_pretty[6] = '\0'; + actual_pretty[0] = ' ', actual_pretty[1] = '(', actual_pretty[2] = '\'', actual_pretty[3] = static_cast(get_or_insert(Memory, addr)), actual_pretty[4] = '\'', actual_pretty[5] = ')', actual_pretty[6] = '\0'; } ostringstream color_phrase; if (color != -1) color_phrase << " in color " << color; if (Current_scenario && !Scenario_testing_scenario) { // genuine test in a mu file - raise_error << "\nF - " << Current_scenario->name << ": expected screen location (" << row << ", " << column << ") to contain " << curr << expected_pretty << color_phrase.str() << " instead of " << no_scientific(Memory[addr]) << actual_pretty << '\n' << end(); + raise_error << "\nF - " << Current_scenario->name << ": expected screen location (" << row << ", " << column << ") to contain " << curr << expected_pretty << color_phrase.str() << " instead of " << no_scientific(get_or_insert(Memory, addr)) << actual_pretty << '\n' << end(); dump_screen(); } else { // just testing check_screen - raise_error << "expected screen location (" << row << ", " << column << ") to contain " << curr << expected_pretty << color_phrase.str() << " instead of " << no_scientific(Memory[addr]) << actual_pretty << '\n' << end(); + raise_error << "expected screen location (" << row << ", " << column << ") to contain " << curr << expected_pretty << color_phrase.str() << " instead of " << no_scientific(get_or_insert(Memory, addr)) << actual_pretty << '\n' << end(); } if (!Scenario_testing_scenario) { Passed = false; @@ -317,7 +317,7 @@ void raw_string_stream::skip_whitespace_and_comments() { :(before "End Primitive Recipe Declarations") _DUMP_SCREEN, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["$dump-screen"] = _DUMP_SCREEN; +put(Recipe_ordinal, "$dump-screen", _DUMP_SCREEN); :(before "End Primitive Recipe Checks") case _DUMP_SCREEN: { break; @@ -331,22 +331,22 @@ case _DUMP_SCREEN: { :(code) void dump_screen() { assert(!current_call().default_space); // not supported - long long int screen_location = Memory[SCREEN]; - int width_offset = find_element_name(Type_ordinal["screen"], "num-columns", ""); - long long int screen_width = Memory[screen_location+width_offset]; - int height_offset = find_element_name(Type_ordinal["screen"], "num-rows", ""); - long long int screen_height = Memory[screen_location+height_offset]; - int data_offset = find_element_name(Type_ordinal["screen"], "data", ""); + long long int screen_location = get_or_insert(Memory, SCREEN); + int width_offset = find_element_name(get(Type_ordinal, "screen"), "num-columns", ""); + long long int screen_width = get_or_insert(Memory, screen_location+width_offset); + int height_offset = find_element_name(get(Type_ordinal, "screen"), "num-rows", ""); + long long int screen_height = get_or_insert(Memory, screen_location+height_offset); + int data_offset = find_element_name(get(Type_ordinal, "screen"), "data", ""); assert(data_offset >= 0); long long int screen_data_location = screen_location+data_offset; // type: address:array:character - long long int screen_data_start = Memory[screen_data_location]; // type: array:character - assert(Memory[screen_data_start] == screen_width*screen_height); + long long int screen_data_start = get_or_insert(Memory, screen_data_location); // type: array:character + assert(get_or_insert(Memory, screen_data_start) == screen_width*screen_height); long long int curr = screen_data_start+1; // skip length for (long long int row = 0; row < screen_height; ++row) { cerr << '.'; for (long long int col = 0; col < screen_width; ++col) { - if (Memory[curr]) - cerr << to_unicode(static_cast(Memory[curr])); + if (get_or_insert(Memory, curr)) + cerr << to_unicode(static_cast(get_or_insert(Memory, curr))); else cerr << ' '; curr += /*size of screen-cell*/2; diff --git a/075scenario_console.cc b/075scenario_console.cc index 47cb5f29..4ed1d583 100644 --- a/075scenario_console.cc +++ b/075scenario_console.cc @@ -41,7 +41,7 @@ if (s == "console") return true; :(before "End Primitive Recipe Declarations") ASSUME_CONSOLE, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["assume-console"] = ASSUME_CONSOLE; +put(Recipe_ordinal, "assume-console", ASSUME_CONSOLE); :(before "End Primitive Recipe Checks") case ASSUME_CONSOLE: { break; @@ -57,31 +57,31 @@ case ASSUME_CONSOLE: { long long int size = num_events*size_of_event() + /*space for length*/1; ensure_space(size); long long int event_data_address = Current_routine->alloc; - Memory[event_data_address] = num_events; + put(Memory, event_data_address, num_events); ++Current_routine->alloc; for (long long int i = 0; i < SIZE(r.steps); ++i) { const instruction& curr = r.steps.at(i); if (curr.name == "left-click") { - Memory[Current_routine->alloc] = /*tag for 'touch-event' variant of 'event' exclusive-container*/2; - Memory[Current_routine->alloc+1+/*offset of 'type' in 'mouse-event'*/0] = TB_KEY_MOUSE_LEFT; - Memory[Current_routine->alloc+1+/*offset of 'row' in 'mouse-event'*/1] = to_integer(curr.ingredients.at(0).name); - Memory[Current_routine->alloc+1+/*offset of 'column' in 'mouse-event'*/2] = to_integer(curr.ingredients.at(1).name); + put(Memory, Current_routine->alloc, /*tag for 'touch-event' variant of 'event' exclusive-container*/2); + put(Memory, Current_routine->alloc+1+/*offset of 'type' in 'mouse-event'*/0, TB_KEY_MOUSE_LEFT); + put(Memory, Current_routine->alloc+1+/*offset of 'row' in 'mouse-event'*/1, to_integer(curr.ingredients.at(0).name)); + put(Memory, Current_routine->alloc+1+/*offset of 'column' in 'mouse-event'*/2, to_integer(curr.ingredients.at(1).name)); Current_routine->alloc += size_of_event(); } else if (curr.name == "press") { string key = curr.ingredients.at(0).name; if (is_integer(key)) - Memory[Current_routine->alloc+1] = to_integer(key); + put(Memory, Current_routine->alloc+1, to_integer(key)); else if (Key.find(key) != Key.end()) - Memory[Current_routine->alloc+1] = Key[key]; + put(Memory, Current_routine->alloc+1, Key[key]); else raise_error << "assume-console: can't press " << key << '\n' << end(); - if (Memory[Current_routine->alloc+1] < 256) + if (get_or_insert(Memory, Current_routine->alloc+1) < 256) // these keys are in ascii - Memory[Current_routine->alloc] = /*tag for 'text' variant of 'event' exclusive-container*/0; + put(Memory, Current_routine->alloc, /*tag for 'text' variant of 'event' exclusive-container*/0); else { // distinguish from unicode - Memory[Current_routine->alloc] = /*tag for 'keycode' variant of 'event' exclusive-container*/1; + put(Memory, Current_routine->alloc, /*tag for 'keycode' variant of 'event' exclusive-container*/1); } Current_routine->alloc += size_of_event(); } @@ -94,11 +94,11 @@ case ASSUME_CONSOLE: { long long int num_keyboard_events = unicode_length(contents); long long int curr = 0; for (long long int i = 0; i < num_keyboard_events; ++i) { - Memory[Current_routine->alloc] = /*tag for 'text' variant of 'event' exclusive-container*/0; + put(Memory, Current_routine->alloc, /*tag for 'text' variant of 'event' exclusive-container*/0); uint32_t curr_character; assert(curr < SIZE(contents)); tb_utf8_char_to_unicode(&curr_character, &raw_contents[curr]); - Memory[Current_routine->alloc+/*skip exclusive container tag*/1] = curr_character; + put(Memory, Current_routine->alloc+/*skip exclusive container tag*/1, curr_character); curr += tb_utf8_char_length(raw_contents[curr]); Current_routine->alloc += size_of_event(); } @@ -107,9 +107,10 @@ case ASSUME_CONSOLE: { assert(Current_routine->alloc == event_data_address+size); // wrap the array of events in a console object ensure_space(size_of_console()); - Memory[CONSOLE] = Current_routine->alloc; + put(Memory, CONSOLE, Current_routine->alloc); Current_routine->alloc += size_of_console(); - Memory[Memory[CONSOLE]+/*offset of 'data' in container 'events'*/1] = event_data_address; + long long int console_address = get_or_insert(Memory, CONSOLE); + put(Memory, console_address+/*offset of 'data' in container 'events'*/1, event_data_address); break; } @@ -227,7 +228,7 @@ scenario events-in-scenario [ :(before "End Primitive Recipe Declarations") REPLACE_IN_CONSOLE, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["replace-in-console"] = REPLACE_IN_CONSOLE; +put(Recipe_ordinal, "replace-in-console", REPLACE_IN_CONSOLE); :(before "End Primitive Recipe Checks") case REPLACE_IN_CONSOLE: { break; @@ -235,17 +236,18 @@ case REPLACE_IN_CONSOLE: { :(before "End Primitive Recipe Implementations") case REPLACE_IN_CONSOLE: { assert(scalar(ingredients.at(0))); - if (!Memory[CONSOLE]) { + if (!get_or_insert(Memory, CONSOLE)) { raise_error << "console not initialized\n" << end(); break; } - long long int console_data = Memory[Memory[CONSOLE]+1]; - long long int size = Memory[console_data]; // array size + long long int console_address = get_or_insert(Memory, CONSOLE); + long long int console_data = get_or_insert(Memory, console_address+1); + long long int size = get_or_insert(Memory, console_data); // array size for (long long int i = 0, curr = console_data+1; i < size; ++i, curr+=size_of_event()) { - if (Memory[curr] != /*text*/0) continue; - if (Memory[curr+1] != ingredients.at(0).at(0)) continue; + if (get_or_insert(Memory, curr) != /*text*/0) continue; + if (get_or_insert(Memory, curr+1) != ingredients.at(0).at(0)) continue; for (long long int n = 0; n < size_of_event(); ++n) - Memory[curr+n] = ingredients.at(1).at(n); + put(Memory, curr+n, ingredients.at(1).at(n)); } break; } @@ -267,7 +269,7 @@ long long int size_of_event() { // memoize result if already computed static long long int result = 0; if (result) return result; - type_tree* type = new type_tree(Type_ordinal["event"]); + type_tree* type = new type_tree(get(Type_ordinal, "event")); result = size_of(type); delete type; return result; @@ -277,8 +279,8 @@ long long int size_of_console() { // memoize result if already computed static long long int result = 0; if (result) return result; - assert(Type_ordinal["console"]); - type_tree* type = new type_tree(Type_ordinal["console"]); + assert(get(Type_ordinal, "console")); + type_tree* type = new type_tree(get(Type_ordinal, "console")); result = size_of(type); delete type; return result; diff --git a/080trace_browser.cc b/080trace_browser.cc index 9c5c5e86..26c856eb 100644 --- a/080trace_browser.cc +++ b/080trace_browser.cc @@ -1,7 +1,7 @@ :(before "End Primitive Recipe Declarations") _BROWSE_TRACE, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["$browse-trace"] = _BROWSE_TRACE; +put(Recipe_ordinal, "$browse-trace", _BROWSE_TRACE); :(before "End Primitive Recipe Checks") case _BROWSE_TRACE: { break; diff --git a/081run_interactive.cc b/081run_interactive.cc index f2a2e331..68225d3c 100644 --- a/081run_interactive.cc +++ b/081run_interactive.cc @@ -26,15 +26,15 @@ recipe main [ :(before "End Primitive Recipe Declarations") RUN_INTERACTIVE, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["run-interactive"] = RUN_INTERACTIVE; +put(Recipe_ordinal, "run-interactive", RUN_INTERACTIVE); :(before "End Primitive Recipe Checks") case RUN_INTERACTIVE: { if (SIZE(inst.ingredients) != 1) { - raise_error << maybe(Recipe[r].name) << "'run-interactive' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'run-interactive' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end(); break; } if (!is_mu_string(inst.ingredients.at(0))) { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'run-interactive' should be a string, but got " << inst.ingredients.at(0).to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'run-interactive' should be a string, but got " << inst.ingredients.at(0).to_string() << '\n' << end(); break; } break; @@ -69,7 +69,7 @@ Track_most_recent_products = false; // all warnings. // returns true if successfully called (no errors found during load and transform) bool run_interactive(long long int address) { - assert(Recipe_ordinal.find("interactive") != Recipe_ordinal.end() && Recipe_ordinal["interactive"] != 0); + assert(Recipe_ordinal.find("interactive") != Recipe_ordinal.end() && get(Recipe_ordinal, "interactive") != 0); // try to sandbox the run as best you can // todo: test this if (!Current_scenario) { @@ -78,8 +78,8 @@ bool run_interactive(long long int address) { } string command = trim(strip_comments(read_mu_string(address))); if (command.empty()) return false; - Recipe.erase(Recipe_ordinal["interactive"]); - Name[Recipe_ordinal["interactive"]].clear(); + Recipe.erase(get(Recipe_ordinal, "interactive")); + Name[get(Recipe_ordinal, "interactive")].clear(); run_code_begin(); // don't kill the current routine on parse errors routine* save_current_routine = Current_routine; @@ -103,7 +103,7 @@ bool run_interactive(long long int address) { trace(9999, "trace") << "run-interactive: incrementing callstack depth to " << Save_trace_stream->callstack_depth << end(); assert(Save_trace_stream->callstack_depth < 9000); // 9998-101 plus cushion } - Current_routine->calls.push_front(call(Recipe_ordinal["sandbox"])); + Current_routine->calls.push_front(call(get(Recipe_ordinal, "sandbox"))); return true; } @@ -167,7 +167,7 @@ add 2, 2] :(before "End Primitive Recipe Declarations") _START_TRACKING_PRODUCTS, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["$start-tracking-products"] = _START_TRACKING_PRODUCTS; +put(Recipe_ordinal, "$start-tracking-products", _START_TRACKING_PRODUCTS); :(before "End Primitive Recipe Checks") case _START_TRACKING_PRODUCTS: { break; @@ -181,7 +181,7 @@ case _START_TRACKING_PRODUCTS: { :(before "End Primitive Recipe Declarations") _STOP_TRACKING_PRODUCTS, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["$stop-tracking-products"] = _STOP_TRACKING_PRODUCTS; +put(Recipe_ordinal, "$stop-tracking-products", _STOP_TRACKING_PRODUCTS); :(before "End Primitive Recipe Checks") case _STOP_TRACKING_PRODUCTS: { break; @@ -195,7 +195,7 @@ case _STOP_TRACKING_PRODUCTS: { :(before "End Primitive Recipe Declarations") _MOST_RECENT_PRODUCTS, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["$most-recent-products"] = _MOST_RECENT_PRODUCTS; +put(Recipe_ordinal, "$most-recent-products", _MOST_RECENT_PRODUCTS); :(before "End Primitive Recipe Checks") case _MOST_RECENT_PRODUCTS: { break; @@ -210,7 +210,7 @@ case _MOST_RECENT_PRODUCTS: { :(before "End Primitive Recipe Declarations") SAVE_ERRORS_WARNINGS, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["save-errors-warnings"] = SAVE_ERRORS_WARNINGS; +put(Recipe_ordinal, "save-errors-warnings", SAVE_ERRORS_WARNINGS); :(before "End Primitive Recipe Checks") case SAVE_ERRORS_WARNINGS: { break; @@ -225,7 +225,7 @@ case SAVE_ERRORS_WARNINGS: { :(before "End Primitive Recipe Declarations") SAVE_APP_TRACE, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["save-app-trace"] = SAVE_APP_TRACE; +put(Recipe_ordinal, "save-app-trace", SAVE_APP_TRACE); :(before "End Primitive Recipe Checks") case SAVE_APP_TRACE: { break; @@ -240,7 +240,7 @@ case SAVE_APP_TRACE: { :(before "End Primitive Recipe Declarations") _CLEANUP_RUN_INTERACTIVE, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["$cleanup-run-interactive"] = _CLEANUP_RUN_INTERACTIVE; +put(Recipe_ordinal, "$cleanup-run-interactive", _CLEANUP_RUN_INTERACTIVE); :(before "End Primitive Recipe Checks") case _CLEANUP_RUN_INTERACTIVE: { break; @@ -356,7 +356,7 @@ string strip_comments(string in) { long long int stringified_value_of_location(long long int address) { // convert to string ostringstream out; - out << no_scientific(Memory[address]); + out << no_scientific(get_or_insert(Memory, address)); return new_mu_string(out.str()); } @@ -403,15 +403,15 @@ void truncate(string& x) { :(before "End Primitive Recipe Declarations") RELOAD, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["reload"] = RELOAD; +put(Recipe_ordinal, "reload", RELOAD); :(before "End Primitive Recipe Checks") case RELOAD: { if (SIZE(inst.ingredients) != 1) { - raise_error << maybe(Recipe[r].name) << "'reload' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'reload' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end(); break; } if (!is_mu_string(inst.ingredients.at(0))) { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'reload' should be a string, but got " << inst.ingredients.at(0).original_string << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'reload' should be a string, but got " << inst.ingredients.at(0).original_string << '\n' << end(); break; } break; @@ -420,7 +420,7 @@ case RELOAD: { case RELOAD: { // clear any containers in advance for (long long int i = 0; i < SIZE(recently_added_types); ++i) { - Type_ordinal.erase(Type[recently_added_types.at(i)].name); + Type_ordinal.erase(get(Type, recently_added_types.at(i)).name); Type.erase(recently_added_types.at(i)); } string code = read_mu_string(ingredients.at(0).at(0)); diff --git a/082persist.cc b/082persist.cc index a43a4395..774ce08f 100644 --- a/082persist.cc +++ b/082persist.cc @@ -5,11 +5,11 @@ :(before "End Primitive Recipe Declarations") RESTORE, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["restore"] = RESTORE; +put(Recipe_ordinal, "restore", RESTORE); :(before "End Primitive Recipe Checks") case RESTORE: { if (SIZE(inst.ingredients) != 1) { - raise_error << maybe(Recipe[r].name) << "'restore' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'restore' requires exactly one ingredient, but got " << inst.to_string() << '\n' << end(); break; } string filename; @@ -20,7 +20,7 @@ case RESTORE: { ; } else { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'restore' should be a string, but got " << inst.ingredients.at(0).to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'restore' should be a string, but got " << inst.ingredients.at(0).to_string() << '\n' << end(); break; } break; @@ -69,11 +69,11 @@ string slurp(const string& filename) { :(before "End Primitive Recipe Declarations") SAVE, :(before "End Primitive Recipe Numbers") -Recipe_ordinal["save"] = SAVE; +put(Recipe_ordinal, "save", SAVE); :(before "End Primitive Recipe Checks") case SAVE: { if (SIZE(inst.ingredients) != 2) { - raise_error << maybe(Recipe[r].name) << "'save' requires exactly two ingredients, but got " << inst.to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "'save' requires exactly two ingredients, but got " << inst.to_string() << '\n' << end(); break; } if (is_literal_string(inst.ingredients.at(0))) { @@ -83,11 +83,11 @@ case SAVE: { ; } else { - raise_error << maybe(Recipe[r].name) << "first ingredient of 'save' should be a string, but got " << inst.ingredients.at(0).to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "first ingredient of 'save' should be a string, but got " << inst.ingredients.at(0).to_string() << '\n' << end(); break; } if (!is_mu_string(inst.ingredients.at(1))) { - raise_error << maybe(Recipe[r].name) << "second ingredient of 'save' should be an address:array:character, but got " << inst.ingredients.at(1).to_string() << '\n' << end(); + raise_error << maybe(get(Recipe, r).name) << "second ingredient of 'save' should be an address:array:character, but got " << inst.ingredients.at(1).to_string() << '\n' << end(); break; } break; -- cgit 1.4.1-2-gfad0