about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-07-25 00:20:35 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-07-25 00:23:15 -0700
commitc5e965d87fe2ef50ac70722eea73e89095b9178d (patch)
tree9be8da3096747e6bd2542e5d44e97c12caf254b7
parent35064671ef90ec6e35eafd9b15363058bf4f23f4 (diff)
downloadmu-c5e965d87fe2ef50ac70722eea73e89095b9178d.tar.gz
1845 - never ever redefine the scenario's recipe
A couple of times now I've accidentally named a scenario the same thing
as a recipe inside it that I define using 'run' or something. The
resulting infinite loop is invariably non-trivial to debug.
-rw-r--r--011load.cc13
-rw-r--r--050scenario.cc21
2 files changed, 27 insertions, 7 deletions
diff --git a/011load.cc b/011load.cc
index 9142429c..7135b548 100644
--- a/011load.cc
+++ b/011load.cc
@@ -33,7 +33,10 @@ vector<recipe_ordinal> load(istream& in) {
       if (Recipe_ordinal.find(recipe_name) == Recipe_ordinal.end()) {
         Recipe_ordinal[recipe_name] = Next_recipe_ordinal++;
       }
-      // Warn On Redefinition
+      if (warn_on_redefine(recipe_name)
+          && Recipe.find(Recipe_ordinal[recipe_name]) != Recipe.end()) {
+        raise << "redefining recipe " << Recipe[Recipe_ordinal[recipe_name]].name << "\n" << end();
+      }
       // todo: save user-defined recipes to mu's memory
       Recipe[Recipe_ordinal[recipe_name]] = slurp_recipe(in);
 //?       cerr << Recipe_ordinal[recipe_name] << ": " << recipe_name << '\n'; //? 1
@@ -204,10 +207,10 @@ void skip_comma(istream& in) {
 bool Hide_redefine_warnings = false;
 :(before "End Setup")
 Hide_redefine_warnings = false;
-:(after "Warn On Redefinition")
-if (!Hide_redefine_warnings
-    && Recipe.find(Recipe_ordinal[recipe_name]) != Recipe.end()) {
-  raise << "redefining recipe " << Recipe[Recipe_ordinal[recipe_name]].name << "\n" << end();
+:(code)
+bool warn_on_redefine(const string& recipe_name) {
+  if (Hide_redefine_warnings) return false;
+  return true;
 }
 
 // for debugging
diff --git a/050scenario.cc b/050scenario.cc
index 358c767c..b0322917 100644
--- a/050scenario.cc
+++ b/050scenario.cc
@@ -138,7 +138,7 @@ void run_mu_scenario(const scenario& s) {
     setup();
   }
   assert(Routines.empty());
-  vector<recipe_ordinal> tmp = load("recipe "+s.name+" [ "+s.to_run+" ]");
+  vector<recipe_ordinal> tmp = load("recipe scenario-"+s.name+" [ "+s.to_run+" ]");
   bind_special_scenario_names(tmp.at(0));
   transform_all();
   run(tmp.front());
@@ -154,12 +154,29 @@ void run_mu_scenario(const scenario& s) {
   Current_scenario = NULL;
 }
 
+//: Watch out for redefinitions of scenario routines. We should never ever be
+//: doing that, regardless of anything else.
+:(scenarios run)
+:(scenario warn_on_redefine_scenario)
+% Hide_warnings = true;
+% Hide_redefine_warnings = true;
+recipe scenario-foo [
+  1:number <- copy 34:literal
+]
+
+recipe scenario-foo [
+  1:number <- copy 35:literal
+]
++warn: redefining recipe scenario-foo
+
+:(after "bool warn_on_redefine(const string& recipe_name)")
+if (recipe_name.find("scenario-") == 0) return true;
+
 //:: The special instructions we want to support inside scenarios.
 //: In a compiler for the mu VM these will require more work.
 
 //: 'run' interprets a string as a set of instructions
 
-:(scenarios run)
 :(scenario run)
 #? % Trace_stream->dump_layer = "all";
 recipe main [