about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--034call.cc6
-rw-r--r--036call_reply.cc6
-rw-r--r--050scenario.cc30
-rw-r--r--072scenario_screen.cc20
-rw-r--r--081run_interactive.cc9
-rw-r--r--edit.mu54
6 files changed, 107 insertions, 18 deletions
diff --git a/034call.cc b/034call.cc
index 4c368bbf..6d820809 100644
--- a/034call.cc
+++ b/034call.cc
@@ -107,8 +107,12 @@ inline const vector<instruction>& routine::steps() const {
 // when we reach the end of one call, we may reach the end of the one below
 // it, and the one below that, and so on
 while (current_step_index() >= SIZE(Current_routine->steps())) {
+  if (current_recipe_name() == "interactive") {
+//?     trace("foo") << "showing warnings again"; //? 1
+    Hide_warnings = false;
+  }
   --Callstack_depth;
-//?   cerr << "reply " << Current_routine->calls.size() << '\n'; //? 1
+//?   cerr << "reply " << Current_routine->calls.size() << '\n'; //? 2
   Current_routine->calls.pop_front();
   if (Current_routine->calls.empty()) return;
   // todo: no results returned warning
diff --git a/036call_reply.cc b/036call_reply.cc
index 0bc46323..d09763fe 100644
--- a/036call_reply.cc
+++ b/036call_reply.cc
@@ -20,6 +20,10 @@ Recipe_ordinal["reply"] = REPLY;
 case REPLY: {
   const instruction& reply_inst = current_instruction();  // save pointer into recipe before pop
   const string& callee = current_recipe_name();
+  if (callee == "interactive") {
+    trace("foo") << "showing warnings again";
+    Hide_warnings = true;
+  }
   --Callstack_depth;
 //?   if (tb_is_active()) { //? 1
 //?     tb_clear(); //? 1
@@ -44,8 +48,6 @@ case REPLY: {
         raise << current_recipe_name() << ": 'same-as-ingredient' result " << caller_instruction.products.at(i).value << " from call to " << callee << " must be location " << caller_instruction.ingredients.at(ingredient_index).value << '\n';
     }
   }
-  if (current_recipe_name() == "interactive") {
-  }
   break;  // continue to process rest of *caller* instruction
 }
 
diff --git a/050scenario.cc b/050scenario.cc
index 836ff9f8..58f4dd81 100644
--- a/050scenario.cc
+++ b/050scenario.cc
@@ -211,7 +211,13 @@ recipe main [
 //: 'memory-should-contain' raises warnings if specific locations aren't as expected
 //: Also includes some special support for checking strings.
 
+:(before "End Globals")
+bool Scenario_testing_scenario = false;
+:(before "End Setup")
+Scenario_testing_scenario = false;
+
 :(scenario memory_check)
+% Scenario_testing_scenario = true;
 % Hide_warnings = true;
 recipe main [
   memory-should-contain [
@@ -255,7 +261,7 @@ void check_memory(const string& s) {
       raise << "duplicate expectation for location " << address << '\n';
     trace(Primitive_recipe_depth, "run") << "checking location " << address;
     if (Memory[address] != value) {
-      if (Current_scenario && !Hide_warnings) {
+      if (Current_scenario && !Scenario_testing_scenario) {
         // genuine test in a mu file
         raise << "\nF - " << Current_scenario->name << ": expected location " << address << " to contain " << value << " but saw " << Memory[address] << '\n';
       }
@@ -263,7 +269,7 @@ void check_memory(const string& s) {
         // just testing scenario support
         raise << "expected location " << address << " to contain " << value << " but saw " << Memory[address] << '\n';
       }
-      if (!Hide_warnings) {
+      if (!Scenario_testing_scenario) {
         Passed = false;
         ++Num_failures;
       }
@@ -295,11 +301,11 @@ void check_type(const string& lhs, istream& in) {
 void check_string(long long int address, const string& literal) {
   trace(Primitive_recipe_depth, "run") << "checking string length at " << address;
   if (Memory[address] != SIZE(literal)) {
-    if (Current_scenario && !Hide_warnings)
+    if (Current_scenario && !Scenario_testing_scenario)
       raise << "\nF - " << Current_scenario->name << ": expected location " << address << " to contain length " << SIZE(literal) << " of string [" << literal << "] but saw " << Memory[address] << '\n';
     else
       raise << "expected location " << address << " to contain length " << SIZE(literal) << " of string [" << literal << "] but saw " << Memory[address] << '\n';
-    if (!Hide_warnings) {
+    if (!Scenario_testing_scenario) {
       Passed = false;
       ++Num_failures;
     }
@@ -309,7 +315,7 @@ void check_string(long long int address, const string& literal) {
   for (long long int i = 0; i < SIZE(literal); ++i) {
     trace(Primitive_recipe_depth, "run") << "checking location " << address+i;
     if (Memory[address+i] != literal.at(i)) {
-      if (Current_scenario && !Hide_warnings) {
+      if (Current_scenario && !Scenario_testing_scenario) {
         // genuine test in a mu file
         raise << "\nF - " << Current_scenario->name << ": expected location " << (address+i) << " to contain " << literal.at(i) << " but saw " << Memory[address+i] << '\n';
       }
@@ -317,7 +323,7 @@ void check_string(long long int address, const string& literal) {
         // just testing scenario support
         raise << "expected location " << (address+i) << " to contain " << literal.at(i) << " but saw " << Memory[address+i] << '\n';
       }
-      if (!Hide_warnings) {
+      if (!Scenario_testing_scenario) {
         Passed = false;
         ++Num_failures;
       }
@@ -327,6 +333,7 @@ void check_string(long long int address, const string& literal) {
 }
 
 :(scenario memory_check_multiple)
+% Scenario_testing_scenario = true;
 % Hide_warnings = true;
 recipe main [
   memory-should-contain [
@@ -337,6 +344,7 @@ recipe main [
 +warn: duplicate expectation for location 1
 
 :(scenario memory_check_string_length)
+% Scenario_testing_scenario = true;
 % Hide_warnings = true;
 recipe main [
   1:number <- copy 3:literal
@@ -369,12 +377,9 @@ recipe main [
 // Like runs of contiguous '+' lines, order is important. The trace checks
 // that the lines are present *and* in the specified sequence. (There can be
 // other lines in between.)
-//
-// Be careful not to mix setting Hide_warnings and checking the trace in .mu
-// files. It'll work in C++ scenarios, but the test failure gets silently
-// hidden in mu scenarios.
 
 :(scenario trace_check_warns_on_failure)
+% Scenario_testing_scenario = true;
 % Hide_warnings = true;
 recipe main [
   trace-should-contain [
@@ -435,6 +440,7 @@ vector<trace_line> parse_trace(const string& expected) {
 }
 
 :(scenario trace_check_warns_on_failure_in_later_line)
+% Scenario_testing_scenario = true;
 % Hide_warnings = true;
 recipe main [
   run [
@@ -448,6 +454,7 @@ recipe main [
 +warn: missing [d] in trace layer a
 
 :(scenario trace_check_passes_silently)
+% Scenario_testing_scenario = true;
 % Hide_warnings = true;
 recipe main [
   run [
@@ -465,6 +472,7 @@ $warn: 0
 //: important, so you can't say things like "B should not exist after A."
 
 :(scenario trace_negative_check_warns_on_failure)
+% Scenario_testing_scenario = true;
 % Hide_warnings = true;
 recipe main [
   run [
@@ -504,6 +512,7 @@ bool check_trace_missing(const string& in) {
 }
 
 :(scenario trace_negative_check_passes_silently)
+% Scenario_testing_scenario = true;
 % Hide_warnings = true;
 recipe main [
   trace-should-not-contain [
@@ -514,6 +523,7 @@ recipe main [
 $warn: 0
 
 :(scenario trace_negative_check_warns_on_any_unexpected_line)
+% Scenario_testing_scenario = true;
 % Hide_warnings = true;
 recipe main [
   run [
diff --git a/072scenario_screen.cc b/072scenario_screen.cc
index 14ac3a36..8e3f0d9c 100644
--- a/072scenario_screen.cc
+++ b/072scenario_screen.cc
@@ -71,6 +71,7 @@ scenario screen-in-scenario-color [
 ]
 
 :(scenario screen_in_scenario_error)
+% Scenario_testing_scenario = true;
 % Hide_warnings = true;
 scenario screen-in-scenario-error [
   assume-screen 5:literal/width, 3:literal/height
@@ -87,6 +88,7 @@ scenario screen-in-scenario-error [
 +warn: expected screen location (0, 0) to contain 98 ('b') instead of 97 ('a')
 
 :(scenario screen_in_scenario_color_error)
+% Scenario_testing_scenario = true;
 % Hide_warnings = true;
 # screen-should-contain can check unicode characters in the fake screen
 scenario screen-in-scenario-color [
@@ -109,6 +111,7 @@ if (s == "screen") return true;
 
 :(scenarios run)
 :(scenario convert_names_does_not_warn_when_mixing_special_names_and_numeric_locations)
+% Scenario_testing_scenario = true;
 % Hide_warnings = true;
 recipe main [
   screen:number <- copy 1:number
@@ -209,23 +212,29 @@ void check_screen(const string& expected_contents, const int color) {
   long long int addr = screen_data_start+1;  // skip length
 //?   cerr << "screen height " << screen_height << '\n'; //? 1
   for (long long int row = 0; row < screen_height; ++row) {
-//?     cerr << "row: " << row << '\n'; //? 1
+//?     cerr << "row: " << row << '\n'; //? 3
+//?     cerr << "contents: " << cursor.buf+cursor.index << "$\n"; //? 1
     cursor.skip_whitespace_and_comments();
     if (cursor.at_end()) break;
+//?     cerr << "row2\n"; //? 2
     assert(cursor.get() == '.');
     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();
+//?       cerr << "col: " << column << '\n'; //? 1
       if (Memory[addr] == 0 && isspace(curr)) continue;
 //?       cerr << color << " vs " << Memory[addr+1] << '\n'; //? 1
       if (curr == ' ' && color != -1 && color != Memory[addr+cell_color_offset]) {
         // filter out other colors
         continue;
       }
+//?       cerr << "col3 " << column << ": " << Memory[addr] << " " << curr << '\n'; //? 1
       if (Memory[addr] != 0 && Memory[addr] == curr) {
+//?         cerr << "col4\n"; //? 1
         if (color == -1 || color == Memory[addr+cell_color_offset]) continue;
+//?         cerr << "col5: " << column << '\n'; //? 1
         // contents match but color is off
-        if (Current_scenario && !Hide_warnings) {
+        if (Current_scenario && !Scenario_testing_scenario) {
           // genuine test in a mu file
           raise << "\nF - " << Current_scenario->name << ": expected screen location (" << row << ", " << column << ", address " << addr << ", value " << Memory[addr] << ") to be in color " << color << " instead of " << Memory[addr+cell_color_offset] << "\n";
         }
@@ -233,13 +242,14 @@ void check_screen(const string& expected_contents, const int color) {
           // just testing check_screen
           raise << "expected screen location (" << row << ", " << column << ") to be in color " << color << " instead of " << Memory[addr+cell_color_offset] << '\n';
         }
-        if (!Hide_warnings) {
+        if (!Scenario_testing_scenario) {
           Passed = false;
           ++Num_failures;
         }
         return;
       }
 
+//?       cerr << "col6 " << column << ": " << Memory[addr] << " " << curr << '\n'; //? 1
       // really a mismatch
       // can't print multi-byte unicode characters in warnings just yet. not very useful for debugging anyway.
       char expected_pretty[10] = {0};
@@ -253,7 +263,7 @@ void check_screen(const string& expected_contents, const int color) {
         actual_pretty[0] = ' ', actual_pretty[1] = '(', actual_pretty[2] = '\'', actual_pretty[3] = static_cast<unsigned char>(Memory[addr]), actual_pretty[4] = '\'', actual_pretty[5] = ')', actual_pretty[6] = '\0';
       }
 
-      if (Current_scenario && !Hide_warnings) {
+      if (Current_scenario && !Scenario_testing_scenario) {
         // genuine test in a mu file
         raise << "\nF - " << Current_scenario->name << ": expected screen location (" << row << ", " << column << ") to contain " << curr << expected_pretty << " instead of " << Memory[addr] << actual_pretty << '\n';
         dump_screen();
@@ -262,7 +272,7 @@ void check_screen(const string& expected_contents, const int color) {
         // just testing check_screen
         raise << "expected screen location (" << row << ", " << column << ") to contain " << curr << expected_pretty << " instead of " << Memory[addr] << actual_pretty << '\n';
       }
-      if (!Hide_warnings) {
+      if (!Scenario_testing_scenario) {
         Passed = false;
         ++Num_failures;
       }
diff --git a/081run_interactive.cc b/081run_interactive.cc
index 5e6f3f1a..abb67b17 100644
--- a/081run_interactive.cc
+++ b/081run_interactive.cc
@@ -71,6 +71,7 @@ case RUN_INTERACTIVE: {
 // reads a string. if it's a variable, stores its value as a string and returns false.
 // if it's lines of code, calls them and returns true (no result available yet to be stored)
 bool run_interactive(long long int address, long long int* result) {
+//?   cerr << "run interactive\n"; //? 1
   long long int size = Memory[address];
   if (size == 0) {
 //?     trace(1, "foo") << "AAA"; //? 2
@@ -99,9 +100,17 @@ bool run_interactive(long long int address, long long int* result) {
   }
 //?   trace(1, "foo") << "DDD"; //? 2
   Recipe.erase(Recipe_ordinal["interactive"]);
+//?   trace("foo") << "hiding warnings\n"; //? 2
+  Hide_warnings = true;
   // call run(string) but without the scheduling
   load("recipe interactive [\n"+command+"\n]\n");
   transform_all();
+  if (trace_count("warn") > 0) {
+    Hide_warnings = false;
+    *result = 0;
+    return false;
+  }
+//?   cerr << "call interactive: " << Current_routine->calls.size() << '\n'; //? 1
   Current_routine->calls.push_front(call(Recipe_ordinal["interactive"]));
   *result = 0;
   return true;
diff --git a/edit.mu b/edit.mu
index 38c9dc78..2500991f 100644
--- a/edit.mu
+++ b/edit.mu
@@ -1888,6 +1888,8 @@ recipe run-sandboxes [
   default-space:address:array:location <- new location:type, 30:literal
   editor:address:editor-data <- next-ingredient
   screen:address <- next-ingredient
+#?   $print [run sandboxes
+#? ] #? 2
   # todo: load code in left editor
   # compute result of running editor contents
   curr:address:editor-data <- get editor:address:editor-data/deref, next-editor:offset
@@ -1929,6 +1931,58 @@ scenario run-instruction-silently [
   ]
 ]
 
+scenario run-instruction-and-print-warnings [
+#?   $print [=====
+#? ] #? 2
+  assume-screen 60:literal/width, 5:literal/height
+  # left editor is empty
+  1:address:array:character <- new []
+  2:address:editor-data <- new-editor 1:address:array:character, screen:address, 0:literal/top, 0:literal/left, 5:literal/right
+  # right editor contains an illegal instruction
+  3:address:array:character <- new [get 1234:number, foo:offset]
+  4:address:address:editor-data <- get-address 2:address:editor-data/deref, next-editor:offset
+  4:address:address:editor-data/deref <- new-editor 3:address:array:character, screen:address, 0:literal/top, 5:literal/left, 40:literal/right
+  reset-focus 2:address:editor-data
+  # run the code in the editors
+  assume-console [
+    press 65527  # F9
+  ]
+  run [
+    # now run query for it
+#?     $print [about to start event loop
+#? ] #? 1
+    event-loop screen:address, console:address, 2:address:editor-data
+  ]
+  # check that screen prints the value in location 12
+#?   $print [a0
+#? ] #? 1
+#?   $dump-screen #? 1
+#?   get 1234:number, foo:offset #? 1
+  screen-should-contain [
+    .     get 1234:number, foo:offset                            .
+    .     unknown element foo in container number                .
+    .                                                            .
+  ]
+#?   $print [a1
+#? ] #? 1
+#?   $dump-trace #? 1
+#?   $exit #? 2
+  screen-should-contain-in-color 7:literal/white, [
+    .     get 1234:number, foo:offset                            .
+    .                                                            .
+    .                                                            .
+  ]
+#?   $print [a2
+#? ] #? 1
+  screen-should-contain-in-color, 1:literal/red, [
+    .                                                            .
+    .     unknown element foo in container number                .
+    .                                                            .
+  ]
+#?   $print [a3
+#? ] #? 1
+]
+
 ## helpers for drawing editor borders
 
 recipe draw-box [