about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-05-27 09:50:39 -0700
committerKartik K. Agaram <vc@akkartik.com>2016-05-27 09:50:39 -0700
commitea5ff2d46cb4e15add0dd48b660d0a200824db00 (patch)
treeada3ef3086dab6f3fcbaebedcfe8b9747e7b0fe7
parent4698dc0002c671b15eb0cb7d52d2a0fa470c5fde (diff)
downloadmu-ea5ff2d46cb4e15add0dd48b660d0a200824db00.tar.gz
3022
Clean up 3020.
-rw-r--r--042name.cc15
-rw-r--r--050scenario.cc82
-rw-r--r--054static_dispatch.cc1
-rw-r--r--056shape_shifting_recipe.cc1
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<string, string_tree*>("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<string, string_tree*>("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<recipe_ordinal> 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<string, string_tree*>("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<recipe_ordinal> 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<recipe_ordinal> 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<string, string_tree*>("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<recipe_ordinal, recipe>::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.