about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--081run_interactive.cc8
-rw-r--r--edit.mu39
2 files changed, 44 insertions, 3 deletions
diff --git a/081run_interactive.cc b/081run_interactive.cc
index b3746321..e290024d 100644
--- a/081run_interactive.cc
+++ b/081run_interactive.cc
@@ -37,11 +37,12 @@ case RUN_INTERACTIVE: {
   }
   bool new_code_pushed_to_stack = run_interactive(ingredients.at(0).at(0));
   if (!new_code_pushed_to_stack) {
-    products.resize(4);
+    products.resize(5);
     products.at(0).push_back(0);
     products.at(1).push_back(trace_contents("warn"));
     products.at(2).push_back(0);
     products.at(3).push_back(trace_contents("app"));
+    products.at(4).push_back(1);  // completed
     cleanup_run_interactive();
     break;  // done with this instruction
   }
@@ -103,12 +104,15 @@ load(string(
   "local-scope\n" +
   "screen:address/shared <- new-fake-screen 30, 5\n" +
   "r:number/routine_id <- start-running interactive:recipe, screen:address\n" +
+  "limit-time r, 750/instructions\n" +
   "wait-for-routine r\n" +
+  "sandbox-state:number <- routine-state r/routine_id\n" +
+  "completed?:boolean <- equal sandbox-state, 1/completed\n" +
   "output:address:array:character <- $most-recent-products\n" +
   "warnings:address:array:character <- save-trace [warn]\n" +
   "stashes:address:array:character <- save-trace [app]\n" +
   "$cleanup-run-interactive\n" +
-  "reply output, warnings, screen, stashes\n" +
+  "reply output, warnings, screen, stashes, completed?\n" +
 "]\n");
 transform_all();
 recently_added_recipes.clear();
diff --git a/edit.mu b/edit.mu
index ab22d0ad..935b2c62 100644
--- a/edit.mu
+++ b/edit.mu
@@ -4621,7 +4621,13 @@ recipe run-sandboxes [
     warnings:address:address:array:character <- get-address *curr, warnings:offset
     trace:address:address:array:character <- get-address *curr, trace:offset
     fake-screen:address:address:screen <- get-address *curr, screen:offset
-    *response, *warnings, *fake-screen, *trace <- run-interactive *data
+    *response, *warnings, *fake-screen, *trace, completed?:boolean <- run-interactive *data
+    {
+      break-if *warnings
+      break-if completed?:boolean
+      *warnings <- new [took too long!
+]
+    }
     curr <- get *curr, next-sandbox:offset
     loop
   }
@@ -5059,6 +5065,37 @@ scenario sandbox-with-print-can-be-edited [
   ]
 ]
 
+scenario sandbox-can-handle-infinite-loop [
+  $close-trace
+  assume-screen 100/width, 20/height
+  # left editor is empty
+  1:address:array:character <- new [recipe foo [
+  {
+    loop
+  }
+]]
+  # right editor contains an instruction
+  2:address:array:character <- new [foo]
+  3:address:programming-environment-data <- new-programming-environment screen:address, 1:address:array:character, 2:address:array:character
+  # run the sandbox
+  assume-console [
+    press 65532  # F4
+  ]
+  run [
+    event-loop screen:address, console:address, 3:address:programming-environment-data
+  ]
+  screen-should-contain [
+    .                                                                                 run (F4)           .
+    .recipe foo [                                      ┊                                                 .
+    .  {                                               ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
+    .    loop                                          ┊                                                x.
+    .  }                                               ┊foo                                              .
+    .]                                                 ┊took too long!                                   .
+    .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
+    .                                                  ┊                                                 .
+  ]
+]
+
 recipe editor-contents [
   local-scope
   editor:address:editor-data <- next-ingredient