From ea5ff2d46cb4e15add0dd48b660d0a200824db00 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Fri, 27 May 2016 09:50:39 -0700 Subject: 3022 Clean up 3020. --- 042name.cc | 15 ++------- 050scenario.cc | 82 ++++++++++++++++++++++++++++++++++++++++----- 054static_dispatch.cc | 1 + 056shape_shifting_recipe.cc | 1 + 4 files changed, 79 insertions(+), 20 deletions(-) diff --git a/042name.cc b/042name.cc index 2dcfd524..fc341832 100644 --- a/042name.cc +++ b/042name.cc @@ -59,12 +59,7 @@ void transform_names(const recipe_ordinal r) { int v = lookup_name(inst.ingredients.at(in), r); if (v >= 0) { inst.ingredients.at(in).set_value(v); - // HACK: belongs in a later layer, either in the scenario layer which - // introduces the 'run' pseudo-instruction which is translated to - // run_* recipes, or later when we start using screens and consoles in - // scenarios. - if (is_special_name(inst.ingredients.at(in).name) && caller.name.substr(0, 4) == "run_") - inst.ingredients.at(in).properties.push_back(pair("raw", NULL)); + // Done Placing Ingredient(inst, in, caller) } else { raise << maybe(caller.name) << "can't find a place to store '" << inst.ingredients.at(in).name << "'\n" << end(); @@ -84,12 +79,7 @@ void transform_names(const recipe_ordinal r) { int v = lookup_name(inst.products.at(out), r); if (v >= 0) { inst.products.at(out).set_value(v); - // HACK: belongs in a later layer, either in the scenario layer which - // introduces the 'run' pseudo-instruction which is translated to - // run_* recipes, or later when we start using screens and consoles in - // scenarios. - if (is_special_name(inst.products.at(out).name) && caller.name.substr(0, 4) == "run_") - inst.products.at(out).properties.push_back(pair("raw", NULL)); + // Done Placing Product(inst, out, caller) } else { raise << maybe(caller.name) << "can't find a place to store '" << inst.products.at(out).name << "'\n" << end(); @@ -153,6 +143,7 @@ bool is_named_location(const reagent& x) { return !is_integer(x.name); } +// all names here should either be disqualified or also in bind_special_scenario_names bool is_special_name(const string& s) { if (s == "_") return true; if (s == "0") return true; diff --git a/050scenario.cc b/050scenario.cc index c7d57d96..8a9a57d4 100644 --- a/050scenario.cc +++ b/050scenario.cc @@ -150,6 +150,7 @@ void run_mu_scenario(const scenario& s) { setup(); } vector tmp = load("recipe scenario_"+s.name+" [ "+s.to_run+" ]"); + mark_autogenerated(tmp.at(0)); bind_special_scenario_names(tmp.at(0)); transform_all(); run(tmp.front()); @@ -170,6 +171,46 @@ void run_mu_scenario(const scenario& s) { Current_scenario = NULL; } +//: Some variables for fake resources always get special /raw addresses in scenarios. + +// Should contain everything passed by is_special_name but failed by is_disqualified. +void bind_special_scenario_names(recipe_ordinal r) { + // Special Scenario Variable Names(r) + // End Special Scenario Variable Names(r) +} +:(before "Done Placing Ingredient(inst, in, caller)") +maybe_make_raw(inst.ingredients.at(in), caller); +:(before "Done Placing Product(inst, out, caller)") +maybe_make_raw(inst.products.at(out), caller); +:(code) +void maybe_make_raw(reagent& r, const recipe& caller) { + if (!is_special_name(r.name)) return; + if (starts_with(caller.name, "scenario_")) + r.properties.push_back(pair("raw", NULL)); + // End maybe_make_raw +} + +//: Test. +:(before "End is_special_name Cases") +if (s == "__maybe_make_raw_test__") return true; +:(before "End Special Scenario Variable Names(r)") +//: ugly: we only need this for this one test, but need to define it for all time +Name[r]["__maybe_make_raw_test__"] = Reserved_for_tests-1; +:(code) +void test_maybe_make_raw() { + // check that scenarios can use local-scope and special variables together + vector tmp = load( + "def scenario_foo [\n" + " local-scope\n" + " __maybe_make_raw_test__:number <- copy 34\n" + "]\n"); + mark_autogenerated(tmp.at(0)); + bind_special_scenario_names(tmp.at(0)); + transform_all(); + run(tmp.at(0)); + CHECK(trace_count("error") == 0); +} + //: Watch out for redefinitions of scenario routines. We should never ever be //: doing that, regardless of anything else. :(scenarios run) @@ -215,6 +256,7 @@ case RUN: { ostringstream tmp; tmp << "recipe run_" << Next_recipe_ordinal << " [ " << current_instruction().ingredients.at(0).name << " ]"; vector tmp_recipe = load(tmp.str()); + mark_autogenerated(tmp_recipe.at(0)); bind_special_scenario_names(tmp_recipe.at(0)); transform_all(); if (Trace_stream) { @@ -225,14 +267,9 @@ case RUN: { Current_routine->calls.push_front(call(tmp_recipe.at(0))); continue; // not done with caller; don't increment current_step_index() } - -// Some variables for fake resources always get special addresses in -// scenarios. -:(code) -void bind_special_scenario_names(recipe_ordinal r) { - // Special Scenario Variable Names(r) - // End Special Scenario Variable Names(r) -} +:(before "End maybe_make_raw") +if (starts_with(caller.name, "run_")) + r.properties.push_back(pair("raw", NULL)); :(scenario run_multiple) def main [ @@ -683,6 +720,31 @@ def main [ :(after "case _SYSTEM:") if (Current_scenario) break; +//:: Warn if people use '_' manually in function names. They're reserved for internal use. + +:(scenario recipe_name_with_underscore) +% Hide_errors = true; +def foo_bar [ +] ++error: foo_bar: don't create recipes with '_' in the name + +:(before "End recipe Fields") +bool is_autogenerated; +:(before "End recipe Constructor") +is_autogenerated = false; +:(code) +void mark_autogenerated(recipe_ordinal r) { + get(Recipe, r).is_autogenerated = true; +} + +:(after "void transform_all()") + for (map::iterator p = Recipe.begin(); p != Recipe.end(); ++p) { + const recipe& r = p->second; + if (r.name.find('_') == string::npos) continue; + if (r.is_autogenerated) continue; // created by previous call to transform_all() + raise << r.name << ": don't create recipes with '_' in the name\n" << end(); + } + //:: Helpers :(code) @@ -697,3 +759,7 @@ void run_mu_scenario(const string& form) { scenario s = parse_scenario(in); run_mu_scenario(s); } + +bool starts_with(const string& s, const string& pat) { + return s.substr(0, pat.size()) == pat; +} diff --git a/054static_dispatch.cc b/054static_dispatch.cc index dd9fc84b..db9546e8 100644 --- a/054static_dispatch.cc +++ b/054static_dispatch.cc @@ -43,6 +43,7 @@ if (result.name != "main" && contains_key(Recipe_ordinal, result.name)) { } trace(9999, "load") << "switching " << result.name << " to " << new_name << end(); result.name = new_name; + result.is_autogenerated = true; } } else { diff --git a/056shape_shifting_recipe.cc b/056shape_shifting_recipe.cc index 74b6c53f..eae7b96f 100644 --- a/056shape_shifting_recipe.cc +++ b/056shape_shifting_recipe.cc @@ -238,6 +238,7 @@ recipe_ordinal new_variant(recipe_ordinal exemplar, const instruction& inst, con assert(!contains_key(Recipe, new_recipe_ordinal)); recipe new_recipe = get(Recipe, exemplar); new_recipe.name = new_name; + new_recipe.is_autogenerated = true; trace(9993, "transform") << "switching " << inst.name << " to specialized " << header_label(new_recipe) << end(); // Replace type ingredients with concrete types in new_recipe. -- cgit 1.4.1-2-gfad0