about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-08-12 18:00:47 -0700
committerKartik K. Agaram <vc@akkartik.com>2016-08-12 18:00:47 -0700
commite07cbe5edfef74005a56205586202e9a224f0500 (patch)
tree28f15db3a56d77e1716fcc7e82f451f097d0ee1a
parent32983f88e46082ebdbf3357ea488beda9497ce38 (diff)
downloadmu-e07cbe5edfef74005a56205586202e9a224f0500.tar.gz
3174
-rw-r--r--html/001help.cc.html70
-rw-r--r--html/002test.cc.html2
-rw-r--r--html/011load.cc.html8
-rw-r--r--html/020run.cc.html13
-rw-r--r--html/029tools.cc.html10
-rw-r--r--html/050scenario.cc.html50
-rw-r--r--html/080display.cc.html22
-rw-r--r--html/091run_sandboxed.cc.html (renamed from html/091run_interactive.cc.html)72
-rw-r--r--html/edit/005-sandbox.mu.html2
-rw-r--r--html/edit/010-sandbox-trace.mu.html2
-rw-r--r--html/edit/011-errors.mu.html2
-rw-r--r--html/lambda-to-mu.mu.html18
12 files changed, 178 insertions, 93 deletions
diff --git a/html/001help.cc.html b/html/001help.cc.html
index 09f1e4c9..cf4c82ec 100644
--- a/html/001help.cc.html
+++ b/html/001help.cc.html
@@ -40,28 +40,52 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
 <span class="Normal">if</span> <span class="Delimiter">(</span>argc &lt;= <span class="Constant">1</span> || is_equal<span class="Delimiter">(</span>argv[<span class="Constant">1</span>]<span class="Delimiter">,</span> <span class="Constant">&quot;--help&quot;</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
   <span class="Comment">// this is the functionality later layers will provide</span>
   <span class="Comment">// currently no automated tests for commandline arg parsing</span>
-  cerr &lt;&lt; <span class="Constant">&quot;To load files and run 'main':</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
-       &lt;&lt; <span class="Constant">&quot;  mu file1.mu file2.mu ...</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
-       &lt;&lt; <span class="Constant">&quot;To run all tests:</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
-       &lt;&lt; <span class="Constant">&quot;  mu test</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
-       &lt;&lt; <span class="Constant">&quot;To load files and then run all tests:</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
-       &lt;&lt; <span class="Constant">&quot;  mu test file1.mu file2.mu ...</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
-       &lt;&lt; <span class="Constant">&quot;To load files and run only the tests in explicitly loaded files (for apps):</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
-       &lt;&lt; <span class="Constant">&quot;  mu --test-only-app test file1.mu file2.mu ...</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
-       &lt;&lt; <span class="Constant">&quot;'--test-only-app' must come before all other args</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
-       &lt;&lt; <span class="Constant">&quot;'test' must come before all other args except '--test-only-app'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
-       &lt;&lt; <span class="Constant">&quot;To load all files with a numeric prefix in a directory:</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
-       &lt;&lt; <span class="Constant">&quot;  mu directory1</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
-       &lt;&lt; <span class="Constant">&quot;You can test directories just like files.</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
-       &lt;&lt; <span class="Constant">&quot;To pass ingredients to a mu program, provide them after '--':</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
-       &lt;&lt; <span class="Constant">&quot;  mu file_or_dir1 file_or_dir2 ... -- ingredient1 ingredient2 ...</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>argc &lt;= <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    cerr &lt;&lt; <span class="Constant">&quot;Please provide a Mu program to run.</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+         &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
+  cerr &lt;&lt; <span class="Constant">&quot;Usage:</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;  mu [options] [test] [files]</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;or:</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;  mu [options] [test] [files] -- [ingredients for function/recipe 'main']</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;Square brackets surround optional arguments.</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;Examples:</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;  To load files and run 'main':</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;    mu file1.mu file2.mu ...</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;  To run all tests:</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;    mu test</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;  To load files and then run all tests:</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;    mu test file1.mu file2.mu ...</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;  To load files and run only the tests in explicitly loaded files (for apps):</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;    mu --test-only-app test file1.mu file2.mu ...</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;  To load all files with a numeric prefix in a directory:</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;    mu directory1 directory2 ...</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;  You can test directories just like files.</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;    mu test directory1 directory2 ...</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;  To pass ingredients to a mu program, provide them after '--':</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;    mu file_or_dir1 file_or_dir2 ... -- ingredient1 ingredient2 ...</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
        &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
-       &lt;&lt; <span class="Constant">&quot;To browse a trace generated by a previous run:</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
-       &lt;&lt; <span class="Constant">&quot;  mu browse-trace file</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;  To browse a trace generated by a previous run:</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;    mu browse-trace file</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
        <span class="Delimiter">;</span>
   <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
+<span class="Comment">//: Support for option parsing.</span>
+<span class="Comment">//: Options always begin with '--' and are always the first arguments. An</span>
+<span class="Comment">//: option will never follow a non-option.</span>
+<span class="Delimiter">:(before &quot;End Commandline Parsing&quot;)</span>
+<span class="Normal">char</span>** arg = &amp;argv[<span class="Constant">1</span>]<span class="Delimiter">;</span>
+<span class="Normal">while</span> <span class="Delimiter">(</span>argc &gt; <span class="Constant">1</span> &amp;&amp; starts_with<span class="Delimiter">(</span>*arg<span class="Delimiter">,</span> <span class="Constant">&quot;--&quot;</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span><span class="Constant">false</span><span class="Delimiter">)</span>
+    <span class="Delimiter">;</span>  <span class="Comment">// no-op branch just so any further additions can consistently always start with 'else'</span>
+  <span class="Comment">// End Commandline Options(*arg)</span>
+  <span class="Normal">else</span>
+    cerr &lt;&lt; <span class="Constant">&quot;skipping unknown option &quot;</span> &lt;&lt; *arg &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
+  --argc<span class="Delimiter">;</span> ++argv<span class="Delimiter">;</span> ++arg<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
 <span class="SalientComment">//:: Helper function used by the above fragment of code (and later layers too,</span>
 <span class="SalientComment">//:: who knows?).</span>
 <span class="Comment">//: The :(code) directive appends function definitions to the end of the</span>
@@ -76,6 +100,10 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
   <span class="Identifier">return</span> strncmp<span class="Delimiter">(</span>s<span class="Delimiter">,</span> lit<span class="Delimiter">,</span> strlen<span class="Delimiter">(</span>lit<span class="Delimiter">))</span> == <span class="Constant">0</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
+<span class="Normal">bool</span> starts_with<span class="Delimiter">(</span><span class="Normal">const</span> string&amp; s<span class="Delimiter">,</span> <span class="Normal">const</span> string&amp; pat<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  <span class="Identifier">return</span> s<span class="Delimiter">.</span>substr<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> pat<span class="Delimiter">.</span>size<span class="Delimiter">())</span> == pat<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
 <span class="Comment">//: I'll throw some style conventions here for want of a better place for them.</span>
 <span class="Comment">//: As a rule I hate style guides. Do what you want, that's my motto. But since</span>
 <span class="Comment">//: we're dealing with C/C++, the one big thing we want to avoid is undefined</span>
@@ -233,14 +261,6 @@ feenableexcept<span class="Delimiter">(</span>FE_OVERFLOW | FE_UNDERFLOW<span cl
   <span class="Identifier">return</span> in &amp;&amp; !in<span class="Delimiter">.</span>eof<span class="Delimiter">();</span>
 <span class="Delimiter">}</span>
 
-<span class="SalientComment">////: A hack to support faster debugging.</span>
-<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
-<span class="Normal">bool</span> Test_only_app = <span class="Constant">false</span><span class="Delimiter">;</span>
-<span class="Delimiter">:(before &quot;End Commandline Parsing&quot;)</span>
-<span class="Normal">if</span> <span class="Delimiter">(</span>argc &gt; <span class="Constant">1</span> &amp;&amp; is_equal<span class="Delimiter">(</span>argv[<span class="Constant">1</span>]<span class="Delimiter">,</span> <span class="Constant">&quot;--test-only-app&quot;</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
-  Test_only_app = <span class="Constant">true</span><span class="Delimiter">;</span>  --argc<span class="Delimiter">;</span>  ++argv<span class="Delimiter">;</span>
-<span class="Delimiter">}</span>
-
 <span class="Delimiter">:(before &quot;End Includes&quot;)</span>
 <span class="PreProc">#include </span><span class="Constant">&lt;assert.h&gt;</span>
 
diff --git a/html/002test.cc.html b/html/002test.cc.html
index c01063f8..84903a24 100644
--- a/html/002test.cc.html
+++ b/html/002test.cc.html
@@ -34,7 +34,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
 <pre id='vimCodeElement'>
 <span class="Comment">//: A simple test harness. To create new tests define functions starting with</span>
 <span class="Comment">//: 'test_'. To run all tests so defined, run:</span>
-<span class="Comment">//:   $ wart test</span>
+<span class="Comment">//:   $ mu test</span>
 <span class="Comment">//:</span>
 <span class="Comment">//: So far it seems tasteful for layers to never ever reach back to modify</span>
 <span class="Comment">//: previously-defined tests. Every test is a contract once written, and should</span>
diff --git a/html/011load.cc.html b/html/011load.cc.html
index 184151d4..b9194212 100644
--- a/html/011load.cc.html
+++ b/html/011load.cc.html
@@ -60,11 +60,13 @@ vector&lt;recipe_ordinal&gt; load<span class="Delimiter">(</span>istream&amp; in
     string command = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
     <span class="Comment">// Command Handlers</span>
     <span class="Normal">if</span> <span class="Delimiter">(</span>command == <span class="Constant">&quot;recipe&quot;</span> || command == <span class="Constant">&quot;def&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
-      result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>slurp_recipe<span class="Delimiter">(</span>in<span class="Delimiter">));</span>
+      recipe_ordinal r = slurp_recipe<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+      <span class="Normal">if</span> <span class="Delimiter">(</span>r &gt; <span class="Constant">0</span><span class="Delimiter">)</span> result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>r<span class="Delimiter">);</span>
     <span class="Delimiter">}</span>
     <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>command == <span class="Constant">&quot;recipe!&quot;</span> || command == <span class="Constant">&quot;def!&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
       Disable_redefine_checks = <span class="Constant">true</span><span class="Delimiter">;</span>
-      result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>slurp_recipe<span class="Delimiter">(</span>in<span class="Delimiter">));</span>
+      recipe_ordinal r = slurp_recipe<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+      <span class="Normal">if</span> <span class="Delimiter">(</span>r &gt; <span class="Constant">0</span><span class="Delimiter">)</span> result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>r<span class="Delimiter">);</span>
       Disable_redefine_checks = <span class="Constant">false</span><span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
     <span class="Comment">// End Command Handlers</span>
@@ -75,6 +77,8 @@ vector&lt;recipe_ordinal&gt; load<span class="Delimiter">(</span>istream&amp; in
   <span class="Identifier">return</span> result<span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
+<span class="Comment">// return the recipe ordinal slurped, or -1 if it failed</span>
+<span class="Comment">// (later layers will cause failures)</span>
 <span class="Normal">int</span> slurp_recipe<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   recipe result<span class="Delimiter">;</span>
   result<span class="Delimiter">.</span>name = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
diff --git a/html/020run.cc.html b/html/020run.cc.html
index 77f00c93..f3a54f18 100644
--- a/html/020run.cc.html
+++ b/html/020run.cc.html
@@ -207,19 +207,28 @@ save_snapshots<span class="Delimiter">();</span>
   <span class="Comment">// Running Main</span>
   setup<span class="Delimiter">();</span>
 <span class="CommentedCode">//?   Save_trace = true;</span>
-<span class="CommentedCode">//?   START_TRACING_UNTIL_END_OF_SCOPE;</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>Trace_main<span class="Delimiter">)</span> Trace_stream = <span class="Normal">new</span> trace_stream<span class="Delimiter">;</span>
   trace<span class="Delimiter">(</span><span class="Constant">9990</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;=== Starting to run&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
   assert<span class="Delimiter">(</span>Num_calls_to_transform_all == <span class="Constant">1</span><span class="Delimiter">);</span>
   run_main<span class="Delimiter">(</span>argc<span class="Delimiter">,</span> argv<span class="Delimiter">);</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>Trace_main<span class="Delimiter">)</span> <span class="Normal">delete</span> Trace_stream<span class="Delimiter">,</span> Trace_stream = <span class="Constant">NULL</span><span class="Delimiter">;</span>
   teardown<span class="Delimiter">();</span>
 <span class="Delimiter">}</span>
-
 <span class="Delimiter">:(code)</span>
 <span class="Normal">void</span> run_main<span class="Delimiter">(</span><span class="Normal">int</span> argc<span class="Delimiter">,</span> <span class="Normal">char</span>* argv[]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   recipe_ordinal r = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;main&quot;</span><span class="Delimiter">);</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">)</span> run<span class="Delimiter">(</span>r<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 
+<span class="Comment">//: By default we don't maintain the trace while running main because its</span>
+<span class="Comment">//: overheads can grow rapidly. However, it's useful when debugging.</span>
+<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
+<span class="Normal">bool</span> Trace_main = <span class="Constant">false</span><span class="Delimiter">;</span>
+<span class="Delimiter">:(before &quot;End Commandline Options(*arg)&quot;)</span>
+<span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_equal<span class="Delimiter">(</span>*arg<span class="Delimiter">,</span> <span class="Constant">&quot;--trace&quot;</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
+  Trace_main = <span class="Constant">true</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
 <span class="Delimiter">:(code)</span>
 <span class="Normal">void</span> dump_profile<span class="Delimiter">()</span> <span class="Delimiter">{</span>
   <span class="Normal">for</span> <span class="Delimiter">(</span>map&lt;string<span class="Delimiter">,</span> <span class="Normal">int</span>&gt;::iterator p = Instructions_running<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Instructions_running<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
diff --git a/html/029tools.cc.html b/html/029tools.cc.html
index 1b4ee2f3..0d861715 100644
--- a/html/029tools.cc.html
+++ b/html/029tools.cc.html
@@ -275,10 +275,14 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span
   <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
       trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;$print: &quot;</span> &lt;&lt; current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name &lt;&lt; end<span class="Delimiter">();</span>
-      <span class="Normal">if</span> <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> <span class="Constant">&quot;newline&quot;</span><span class="Delimiter">))</span>
-        cout &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
-      <span class="Normal">else</span>
+      <span class="Normal">if</span> <span class="Delimiter">(</span>!has_property<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> <span class="Constant">&quot;newline&quot;</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
         cout &lt;&lt; current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">;</span>
+      <span class="Delimiter">}</span>
+      <span class="Comment">// hack: '$print 10' prints '10', but '$print 10/newline' prints '\n'</span>
+      <span class="Comment">// End $print 10/newline Special-cases</span>
+      <span class="Normal">else</span> <span class="Delimiter">{</span>
+        cout &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
+      <span class="Delimiter">}</span>
     <span class="Delimiter">}</span>
     <span class="Normal">else</span> <span class="Delimiter">{</span>
       <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> j = <span class="Constant">0</span><span class="Delimiter">;</span> j &lt; SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span>
diff --git a/html/050scenario.cc.html b/html/050scenario.cc.html
index d6805cfd..0727ae0e 100644
--- a/html/050scenario.cc.html
+++ b/html/050scenario.cc.html
@@ -99,7 +99,6 @@ scenario foo [
 
 <span class="Delimiter">:(before &quot;End Globals&quot;)</span>
 vector&lt;scenario&gt; Scenarios<span class="Delimiter">;</span>
-set&lt;string&gt; Scenario_names<span class="Delimiter">;</span>
 
 <span class="SalientComment">//:: Parse the 'scenario' form.</span>
 <span class="Comment">//: Simply store the text of the scenario.</span>
@@ -113,9 +112,6 @@ set&lt;string&gt; Scenario_names<span class="Delimiter">;</span>
 scenario parse_scenario<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   scenario result<span class="Delimiter">;</span>
   result<span class="Delimiter">.</span>name = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
-  <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Scenario_names<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">))</span>
-    raise &lt;&lt; <span class="Constant">&quot;duplicate scenario name: '&quot;</span> &lt;&lt; result<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
-  Scenario_names<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>result<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
   skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
     raise &lt;&lt; <span class="Constant">&quot;Expected '[' after scenario '&quot;</span> &lt;&lt; result<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
@@ -149,30 +145,41 @@ scenario foo [
 <span class="Comment">//: Treat the text of the scenario as a regular series of instructions.</span>
 
 <span class="Delimiter">:(before &quot;End Globals&quot;)</span>
-<span class="Normal">int</span> Num_core_mu_tests = <span class="Constant">0</span><span class="Delimiter">;</span>
+<span class="Normal">int</span> Num_core_mu_scenarios = <span class="Constant">0</span><span class="Delimiter">;</span>
 <span class="Delimiter">:(after &quot;Check For .mu Files&quot;)</span>
-Num_core_mu_tests = SIZE<span class="Delimiter">(</span>Scenarios<span class="Delimiter">);</span>
+Num_core_mu_scenarios = SIZE<span class="Delimiter">(</span>Scenarios<span class="Delimiter">);</span>
 <span class="Delimiter">:(before &quot;End Tests&quot;)</span>
 Hide_missing_default_space_errors = <span class="Constant">false</span><span class="Delimiter">;</span>
-<span class="Normal">time_t</span> mu_time<span class="Delimiter">;</span> time<span class="Delimiter">(</span>&amp;mu_time<span class="Delimiter">);</span>
-cerr &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">Mu tests: &quot;</span> &lt;&lt; ctime<span class="Delimiter">(</span>&amp;mu_time<span class="Delimiter">);</span>
-<span class="Normal">run_mu_scenarios</span>:
-<span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>Scenarios<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+time<span class="Delimiter">(</span>&amp;t<span class="Delimiter">);</span>
+cerr &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">Mu tests: &quot;</span> &lt;&lt; ctime<span class="Delimiter">(</span>&amp;t<span class="Delimiter">);</span>
+<span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; Num_core_mu_scenarios<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
 <span class="CommentedCode">//?   cerr &lt;&lt; i &lt;&lt; &quot;: &quot; &lt;&lt; Scenarios.at(i).name &lt;&lt; '\n';</span>
-  <span class="Normal">if</span> <span class="Delimiter">(</span>i == Num_core_mu_tests<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    time<span class="Delimiter">(</span>&amp;t<span class="Delimiter">);</span>
-    cerr &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">App tests: &quot;</span> &lt;&lt; ctime<span class="Delimiter">(</span>&amp;t<span class="Delimiter">);</span>
-  <span class="Delimiter">}</span>
   run_mu_scenario<span class="Delimiter">(</span>Scenarios<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>Passed<span class="Delimiter">)</span> cerr &lt;&lt; <span class="Constant">&quot;.&quot;</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
+cerr &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">;</span>
+<span class="Normal">run_app_scenarios</span>:
+<span class="Normal">if</span> <span class="Delimiter">(</span>Num_core_mu_scenarios != SIZE<span class="Delimiter">(</span>Scenarios<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+  time<span class="Delimiter">(</span>&amp;t<span class="Delimiter">);</span>
+  cerr &lt;&lt; <span class="Constant">&quot;App tests: &quot;</span> &lt;&lt; ctime<span class="Delimiter">(</span>&amp;t<span class="Delimiter">);</span>
+  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = Num_core_mu_scenarios<span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>Scenarios<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; i &lt;&lt; &quot;: &quot; &lt;&lt; Scenarios.at(i).name &lt;&lt; '\n';</span>
+    run_mu_scenario<span class="Delimiter">(</span>Scenarios<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
+    <span class="Normal">if</span> <span class="Delimiter">(</span>Passed<span class="Delimiter">)</span> cerr &lt;&lt; <span class="Constant">&quot;.&quot;</span><span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
 
+<span class="Comment">//: For faster debugging, support running tests for just the Mu app(s) we are</span>
+<span class="Comment">//: loading.</span>
+<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
+<span class="Normal">bool</span> Test_only_app = <span class="Constant">false</span><span class="Delimiter">;</span>
+<span class="Delimiter">:(before &quot;End Commandline Options(*arg)&quot;)</span>
+<span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_equal<span class="Delimiter">(</span>*arg<span class="Delimiter">,</span> <span class="Constant">&quot;--test-only-app&quot;</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
+  Test_only_app = <span class="Constant">true</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
 <span class="Delimiter">:(after &quot;End Test Run Initialization&quot;)</span>
-<span class="Normal">if</span> <span class="Delimiter">(</span>Test_only_app &amp;&amp; Num_core_mu_tests &lt; SIZE<span class="Delimiter">(</span>Scenarios<span class="Delimiter">))</span> <span class="Delimiter">{</span>
-  <span class="Comment">// we have app tests; skip core mu tests</span>
-  Scenarios<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>Scenarios<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> Scenarios<span class="Delimiter">.</span>begin<span class="Delimiter">()</span>+Num_core_mu_tests<span class="Delimiter">);</span>
-  <span class="Comment">// skip C tests</span>
-  <span class="Identifier">goto</span> run_mu_scenarios<span class="Delimiter">;</span>
+<span class="Normal">if</span> <span class="Delimiter">(</span>Test_only_app &amp;&amp; Num_core_mu_scenarios &lt; SIZE<span class="Delimiter">(</span>Scenarios<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+  <span class="Identifier">goto</span> run_app_scenarios<span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
 <span class="Comment">//: Convenience: run a single named scenario.</span>
@@ -789,7 +796,6 @@ is_autogenerated = <span class="Constant">false</span><span class="Delimiter">;<
 <span class="Delimiter">:(code)</span>
 <span class="Comment">// just for the scenarios running scenarios in C++ layers</span>
 <span class="Normal">void</span> run_mu_scenario<span class="Delimiter">(</span><span class="Normal">const</span> string&amp; form<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  Scenario_names<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
   istringstream in<span class="Delimiter">(</span>form<span class="Delimiter">);</span>
   in &gt;&gt; std::noskipws<span class="Delimiter">;</span>
   skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
@@ -798,10 +804,6 @@ is_autogenerated = <span class="Constant">false</span><span class="Delimiter">;<
   scenario s = parse_scenario<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
   run_mu_scenario<span class="Delimiter">(</span>s<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
-
-<span class="Normal">bool</span> starts_with<span class="Delimiter">(</span><span class="Normal">const</span> string&amp; s<span class="Delimiter">,</span> <span class="Normal">const</span> string&amp; pat<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  <span class="Identifier">return</span> s<span class="Delimiter">.</span>substr<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> pat<span class="Delimiter">.</span>size<span class="Delimiter">())</span> == pat<span class="Delimiter">;</span>
-<span class="Delimiter">}</span>
 </pre>
 </body>
 </html>
diff --git a/html/080display.cc.html b/html/080display.cc.html
index d85a3f5b..fc7d0e22 100644
--- a/html/080display.cc.html
+++ b/html/080display.cc.html
@@ -31,7 +31,9 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
 </head>
 <body>
 <pre id='vimCodeElement'>
-<span class="Comment">//: Take charge of the text-mode display and console.</span>
+<span class="Comment">//: Take raw control of the text-mode display and console, putting it in</span>
+<span class="Comment">//: 'console' mode rather than the usual automatically-scrolling 'typewriter'</span>
+<span class="Comment">//: mode.</span>
 
 <span class="SalientComment">//:: Display management</span>
 
@@ -55,9 +57,9 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span
   <span class="Normal">int</span> height = tb_height<span class="Delimiter">();</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>width &gt; <span class="Constant">222</span> || height &gt; <span class="Constant">222</span><span class="Delimiter">)</span> tb_shutdown<span class="Delimiter">();</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>width &gt; <span class="Constant">222</span><span class="Delimiter">)</span>
-    raise &lt;&lt; <span class="Constant">&quot;sorry, mu doesn't support windows wider than 222 characters. Please resize your window.</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+    raise &lt;&lt; <span class="Constant">&quot;sorry, mu doesn't support windows wider than 222 characters in console mode. Please resize your window.</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>height &gt; <span class="Constant">222</span><span class="Delimiter">)</span>
-    raise &lt;&lt; <span class="Constant">&quot;sorry, mu doesn't support windows taller than 222 characters. Please resize your window.</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+    raise &lt;&lt; <span class="Constant">&quot;sorry, mu doesn't support windows taller than 222 characters in console mode. Please resize your window.</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
@@ -317,6 +319,20 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
+<span class="Comment">//: as a convenience, make $print mostly work in console mode</span>
+<span class="Delimiter">:(before &quot;End $print 10/newline Special-cases&quot;)</span>
+<span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>tb_is_active<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+  move_cursor_to_start_of_next_line_on_display<span class="Delimiter">();</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(code)</span>
+<span class="Normal">void</span> move_cursor_to_start_of_next_line_on_display<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>Display_row &lt; tb_height<span class="Delimiter">()</span>-<span class="Constant">1</span><span class="Delimiter">)</span> Display_row++<span class="Delimiter">;</span>
+  <span class="Normal">else</span> Display_row = <span class="Constant">0</span><span class="Delimiter">;</span>
+  Display_column = <span class="Constant">0</span><span class="Delimiter">;</span>
+  tb_set_cursor<span class="Delimiter">(</span>Display_column<span class="Delimiter">,</span> Display_row<span class="Delimiter">);</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span>
+<span class="Delimiter">}</span>
+
 <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
 DISPLAY_WIDTH<span class="Delimiter">,</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
diff --git a/html/091run_interactive.cc.html b/html/091run_sandboxed.cc.html
index 85cbf97d..375b6beb 100644
--- a/html/091run_interactive.cc.html
+++ b/html/091run_sandboxed.cc.html
@@ -2,7 +2,7 @@
 <html>
 <head>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
-<title>Mu - 091run_interactive.cc</title>
+<title>Mu - 091run_sandboxed.cc</title>
 <meta name="Generator" content="Vim/7.4">
 <meta name="plugin-version" content="vim7.4_v2">
 <meta name="syntax" content="cpp">
@@ -39,7 +39,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
 def main [
   <span class="Constant">1</span>:number/<span class="Special">raw &lt;- </span>copy <span class="Constant">0</span>
   <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span><span class="Normal">new</span> [<span class="Constant">1</span>:number/<span class="Special">raw &lt;- </span>copy <span class="Constant">34</span>]
-  run-interactive <span class="Constant">2</span>:address:array:character
+  run-sandboxed <span class="Constant">2</span>:address:array:character
   <span class="Constant">3</span>:number/<span class="Special">raw &lt;- </span>copy <span class="Constant">1</span>:number/<span class="Special">raw</span>
 ]
 <span class="traceContains">+mem: storing 34 in location 3</span>
@@ -47,34 +47,45 @@ def main [
 <span class="Delimiter">:(scenario run_interactive_empty)</span>
 def main [
   <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/unsafe
-  <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>run-interactive <span class="Constant">1</span>:address:array:character
+  <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>run-sandboxed <span class="Constant">1</span>:address:array:character
 ]
 <span class="Comment"># result is null</span>
 <span class="traceContains">+mem: storing 0 in location 2</span>
 
+<span class="Comment">//: As the name suggests, 'run-sandboxed' will prevent certain operations that</span>
+<span class="Comment">//: regular Mu code can perform.</span>
+<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
+<span class="Normal">bool</span> Sandbox_mode = <span class="Constant">false</span><span class="Delimiter">;</span>
+<span class="Comment">//: for starters, users can't override 'main' when the environment is running</span>
+<span class="Delimiter">:(before &quot;End Load Recipe Name&quot;)</span>
+<span class="Normal">if</span> <span class="Delimiter">(</span>Sandbox_mode &amp;&amp; result<span class="Delimiter">.</span>name == <span class="Constant">&quot;main&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  slurp_balanced_bracket<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+  <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
 <span class="Comment">//: run code in 'interactive mode', i.e. with errors off and return:</span>
 <span class="Comment">//:   stringified output in case we want to print it to screen</span>
 <span class="Comment">//:   any errors encountered</span>
 <span class="Comment">//:   simulated screen any prints went to</span>
 <span class="Comment">//:   any 'app' layer traces generated</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
-RUN_INTERACTIVE<span class="Delimiter">,</span>
+RUN_SANDBOXED<span class="Delimiter">,</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
-put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;run-interactive&quot;</span><span class="Delimiter">,</span> RUN_INTERACTIVE<span class="Delimiter">);</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;run-sandboxed&quot;</span><span class="Delimiter">,</span> RUN_SANDBOXED<span class="Delimiter">);</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span>
-<span class="Normal">case</span> RUN_INTERACTIVE: <span class="Delimiter">{</span>
+<span class="Normal">case</span> RUN_SANDBOXED: <span class="Delimiter">{</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    raise &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'run-interactive' requires exactly one ingredient, but got '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+    raise &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'run-sandboxed' requires exactly one ingredient, but got '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">break</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
-    raise &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;first ingredient of 'run-interactive' should be a string, but got '&quot;</span> &lt;&lt; to_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+    raise &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;first ingredient of 'run-sandboxed' should be a string, but got '&quot;</span> &lt;&lt; to_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">break</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
-<span class="Normal">case</span> RUN_INTERACTIVE: <span class="Delimiter">{</span>
+<span class="Normal">case</span> RUN_SANDBOXED: <span class="Delimiter">{</span>
   <span class="Normal">bool</span> new_code_pushed_to_stack = run_interactive<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>!new_code_pushed_to_stack<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">5</span><span class="Delimiter">);</span>
@@ -133,7 +144,7 @@ Track_most_recent_products = <span class="Constant">false</span><span class="Del
   <span class="Comment">// and wait for it</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>Save_trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     ++Save_trace_stream<span class="Delimiter">-&gt;</span>callstack_depth<span class="Delimiter">;</span>
-    trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">&quot;trace&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;run-interactive: incrementing callstack depth to &quot;</span> &lt;&lt; Save_trace_stream<span class="Delimiter">-&gt;</span>callstack_depth &lt;&lt; end<span class="Delimiter">();</span>
+    trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">&quot;trace&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;run-sandboxed: incrementing callstack depth to &quot;</span> &lt;&lt; Save_trace_stream<span class="Delimiter">-&gt;</span>callstack_depth &lt;&lt; end<span class="Delimiter">();</span>
     assert<span class="Delimiter">(</span>Save_trace_stream<span class="Delimiter">-&gt;</span>callstack_depth &lt; <span class="Constant">9000</span><span class="Delimiter">);</span>  <span class="Comment">// 9998-101 plus cushion</span>
   <span class="Delimiter">}</span>
   Current_routine<span class="Delimiter">-&gt;</span>calls<span class="Delimiter">.</span>push_front<span class="Delimiter">(</span>call<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;sandbox&quot;</span><span class="Delimiter">)));</span>
@@ -149,6 +160,7 @@ map&lt;string<span class="Delimiter">,</span> type_ordinal&gt; Type_ordinal_snap
 map&lt;type_ordinal<span class="Delimiter">,</span> type_info&gt; Type_snapshot_stash<span class="Delimiter">;</span>
 map&lt;recipe_ordinal<span class="Delimiter">,</span> map&lt;string<span class="Delimiter">,</span> <span class="Normal">int</span>&gt; &gt; Name_snapshot_stash<span class="Delimiter">;</span>
 map&lt;string<span class="Delimiter">,</span> vector&lt;recipe_ordinal&gt; &gt; Recipe_variants_snapshot_stash<span class="Delimiter">;</span>
+
 <span class="Delimiter">:(code)</span>
 <span class="Normal">void</span> run_code_begin<span class="Delimiter">(</span><span class="Normal">bool</span> should_stash_snapshots<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   <span class="Comment">// stuff to undo later, in run_code_end()</span>
@@ -175,11 +187,17 @@ map&lt;string<span class="Delimiter">,</span> vector&lt;recipe_ordinal&gt; &gt;
 
 <span class="Comment">// keep sync'd with save_snapshots and restore_snapshots</span>
 <span class="Normal">void</span> stash_snapshots<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+  assert<span class="Delimiter">(</span>Recipe_ordinal_snapshot_stash<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
   Recipe_ordinal_snapshot_stash = Recipe_ordinal_snapshot<span class="Delimiter">;</span>
+  assert<span class="Delimiter">(</span>Recipe_snapshot_stash<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
   Recipe_snapshot_stash = Recipe_snapshot<span class="Delimiter">;</span>
+  assert<span class="Delimiter">(</span>Type_ordinal_snapshot_stash<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
   Type_ordinal_snapshot_stash = Type_ordinal_snapshot<span class="Delimiter">;</span>
+  assert<span class="Delimiter">(</span>Type_snapshot_stash<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
   Type_snapshot_stash = Type_snapshot<span class="Delimiter">;</span>
+  assert<span class="Delimiter">(</span>Name_snapshot_stash<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
   Name_snapshot_stash = Name_snapshot<span class="Delimiter">;</span>
+  assert<span class="Delimiter">(</span>Recipe_variants_snapshot_stash<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
   Recipe_variants_snapshot_stash = Recipe_variants_snapshot<span class="Delimiter">;</span>
   save_snapshots<span class="Delimiter">();</span>
 <span class="Delimiter">}</span>
@@ -210,7 +228,7 @@ load<span class="Delimiter">(</span>string<span class="Delimiter">(</span>
   <span class="Constant">&quot;output:address:array:character &lt;- $most-recent-products</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
   <span class="Constant">&quot;errors:address:array:character &lt;- save-errors</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
   <span class="Constant">&quot;stashes:address:array:character &lt;- save-app-trace</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
-  <span class="Constant">&quot;$cleanup-run-interactive</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
+  <span class="Constant">&quot;$cleanup-run-sandboxed</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
   <span class="Constant">&quot;return output, errors, screen, stashes, completed?</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
 <span class="Constant">&quot;]</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">);</span>
 
@@ -222,7 +240,7 @@ load<span class="Delimiter">(</span>string<span class="Delimiter">(</span>
 def main [
   <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span><span class="Normal">new</span> [<span class="Comment"># ab</span>
 add <span class="Constant">2</span><span class="Delimiter">,</span> <span class="Constant">2</span>]
-  <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>run-interactive <span class="Constant">1</span>:address:array:character
+  <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>run-sandboxed <span class="Constant">1</span>:address:array:character
   <span class="Constant">3</span>:array:character<span class="Special"> &lt;- </span>copy *<span class="Constant">2</span>:address:array:character
 ]
 <span class="traceContains">+mem: storing 52 in location 4</span>
@@ -301,15 +319,15 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span
 <span class="Delimiter">}</span>
 
 <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
-_CLEANUP_RUN_INTERACTIVE<span class="Delimiter">,</span>
+_CLEANUP_RUN_SANDBOXED<span class="Delimiter">,</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
-put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;$cleanup-run-interactive&quot;</span><span class="Delimiter">,</span> _CLEANUP_RUN_INTERACTIVE<span class="Delimiter">);</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;$cleanup-run-sandboxed&quot;</span><span class="Delimiter">,</span> _CLEANUP_RUN_SANDBOXED<span class="Delimiter">);</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span>
-<span class="Normal">case</span> _CLEANUP_RUN_INTERACTIVE: <span class="Delimiter">{</span>
+<span class="Normal">case</span> _CLEANUP_RUN_SANDBOXED: <span class="Delimiter">{</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
-<span class="Normal">case</span> _CLEANUP_RUN_INTERACTIVE: <span class="Delimiter">{</span>
+<span class="Normal">case</span> _CLEANUP_RUN_SANDBOXED: <span class="Delimiter">{</span>
   run_code_end<span class="Delimiter">();</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
@@ -318,7 +336,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span
 def main [
   <span class="Comment"># try to interactively add 2 and 2</span>
   <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span><span class="Normal">new</span> [add <span class="Constant">2</span><span class="Delimiter">,</span> <span class="Constant">2</span>]
-  <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>run-interactive <span class="Constant">1</span>:address:array:character
+  <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>run-sandboxed <span class="Constant">1</span>:address:array:character
   <span class="Constant">10</span>:array:character<span class="Special"> &lt;- </span>copy <span class="Constant">2</span>:address:array:character/lookup
 ]
 <span class="Comment"># first letter in the output should be '4' in unicode</span>
@@ -332,7 +350,7 @@ def main [
     <span class="Normal">y</span>:address:array:character<span class="Special"> &lt;- </span><span class="Normal">new</span> [b]
     <span class="Normal">z</span>:address:array:character<span class="Special"> &lt;- </span>append x:address:array:character<span class="Delimiter">,</span> y:address:array:character
   ]
-  <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>run-interactive <span class="Constant">1</span>:address:array:character
+  <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>run-sandboxed <span class="Constant">1</span>:address:array:character
   <span class="Constant">10</span>:array:character<span class="Special"> &lt;- </span>copy <span class="Constant">2</span>:address:array:character/lookup
 ]
 <span class="Comment"># output contains &quot;ab&quot;</span>
@@ -344,7 +362,7 @@ def main [
   <span class="Comment"># run a command that generates an error</span>
   <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span><span class="Normal">new</span> [x:number<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
 get x:number<span class="Delimiter">,</span> foo:offset]
-  <span class="Constant">2</span>:address:array:character<span class="Delimiter">,</span> <span class="Constant">3</span>:address:array:character<span class="Special"> &lt;- </span>run-interactive <span class="Constant">1</span>:address:array:character
+  <span class="Constant">2</span>:address:array:character<span class="Delimiter">,</span> <span class="Constant">3</span>:address:array:character<span class="Special"> &lt;- </span>run-sandboxed <span class="Constant">1</span>:address:array:character
   <span class="Constant">10</span>:array:character<span class="Special"> &lt;- </span>copy <span class="Constant">3</span>:address:array:character/lookup
 ]
 <span class="Comment"># error should be &quot;unknown element foo in container number&quot;</span>
@@ -360,7 +378,7 @@ def main [
   <span class="Constant">1</span>:address:array:number<span class="Special"> &lt;- </span><span class="Normal">new</span> [a:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>  <span class="Comment"># abc</span>
 <span class="Normal">b</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
 ]
-  <span class="Constant">2</span>:address:array:character<span class="Delimiter">,</span> <span class="Constant">3</span>:address:array:character<span class="Special"> &lt;- </span>run-interactive <span class="Constant">1</span>:address:array:character
+  <span class="Constant">2</span>:address:array:character<span class="Delimiter">,</span> <span class="Constant">3</span>:address:array:character<span class="Special"> &lt;- </span>run-sandboxed <span class="Constant">1</span>:address:array:character
 ]
 <span class="Comment"># no errors</span>
 <span class="traceContains">+mem: storing 0 in location 3</span>
@@ -380,15 +398,7 @@ Most_recent_products = <span class="Constant">&quot;&quot;</span><span class="De
     <span class="Comment">// string</span>
     <span class="Normal">if</span> <span class="Delimiter">(</span>i &lt; SIZE<span class="Delimiter">(</span>instruction<span class="Delimiter">.</span>products<span class="Delimiter">))</span> <span class="Delimiter">{</span>
       <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_string<span class="Delimiter">(</span>instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
-        <span class="Normal">if</span> <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
-          tb_shutdown<span class="Delimiter">();</span>
-          cerr &lt;&lt; read_mu_string<span class="Delimiter">(</span>trace_error_contents<span class="Delimiter">())</span> &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
-          cerr &lt;&lt; SIZE<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;: &quot;</span><span class="Delimiter">;</span>
-          <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> j = <span class="Constant">0</span><span class="Delimiter">;</span> j &lt; SIZE<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> ++j<span class="Delimiter">)</span>
-            cerr &lt;&lt; no_scientific<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span>j<span class="Delimiter">))</span> &lt;&lt; <span class="Constant">' '</span><span class="Delimiter">;</span>
-          cerr &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
-        <span class="Delimiter">}</span>
-        assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)));</span>
+        <span class="Normal">if</span> <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>  <span class="Comment">// error handled elsewhere</span>
         out &lt;&lt; read_mu_string<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
         <span class="Identifier">continue</span><span class="Delimiter">;</span>
       <span class="Delimiter">}</span>
@@ -460,7 +470,7 @@ string strip_comments<span class="Delimiter">(</span>string in<span class="Delim
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
 
-<span class="Comment">//: simpler version of run-interactive: doesn't do any running, just loads</span>
+<span class="Comment">//: simpler version of run-sandboxed: doesn't do any running, just loads</span>
 <span class="Comment">//: recipes and reports errors.</span>
 
 <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
@@ -496,9 +506,11 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span
   run_code_begin<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">should_stash_snapshots</span><span class="Comment">*/</span><span class="Constant">false</span><span class="Delimiter">);</span>
   routine* save_current_routine = Current_routine<span class="Delimiter">;</span>
   Current_routine = <span class="Constant">NULL</span><span class="Delimiter">;</span>
+  Sandbox_mode = <span class="Constant">true</span><span class="Delimiter">;</span>
   vector&lt;recipe_ordinal&gt; recipes_reloaded = load<span class="Delimiter">(</span>code<span class="Delimiter">);</span>
   transform_all<span class="Delimiter">();</span>
   Trace_stream<span class="Delimiter">-&gt;</span>newline<span class="Delimiter">();</span>  <span class="Comment">// flush trace</span>
+  Sandbox_mode = <span class="Constant">false</span><span class="Delimiter">;</span>
   Current_routine = save_current_routine<span class="Delimiter">;</span>
   products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
   products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>trace_error_contents<span class="Delimiter">());</span>
diff --git a/html/edit/005-sandbox.mu.html b/html/edit/005-sandbox.mu.html
index a4aa964c..7c4fe9e8 100644
--- a/html/edit/005-sandbox.mu.html
+++ b/html/edit/005-sandbox.mu.html
@@ -237,7 +237,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   data:address:array:character<span class="Special"> &lt;- </span>get *sandbox, <span class="Constant">data:offset</span>
-  response:address:array:character, _, fake-screen:address:screen<span class="Special"> &lt;- </span>run-interactive data
+  response:address:array:character, _, fake-screen:address:screen<span class="Special"> &lt;- </span>run-sandboxed data
   *sandbox<span class="Special"> &lt;- </span>put *sandbox, <span class="Constant">response:offset</span>, response
   *sandbox<span class="Special"> &lt;- </span>put *sandbox, <span class="Constant">screen:offset</span>, fake-screen
 ]
diff --git a/html/edit/010-sandbox-trace.mu.html b/html/edit/010-sandbox-trace.mu.html
index 608bd63c..a5c77f15 100644
--- a/html/edit/010-sandbox-trace.mu.html
+++ b/html/edit/010-sandbox-trace.mu.html
@@ -213,7 +213,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   data:address:array:character<span class="Special"> &lt;- </span>get *sandbox, <span class="Constant">data:offset</span>
-  response:address:array:character, _, fake-screen:address:screen, trace:address:array:character<span class="Special"> &lt;- </span>run-interactive data
+  response:address:array:character, _, fake-screen:address:screen, trace:address:array:character<span class="Special"> &lt;- </span>run-sandboxed data
   *sandbox<span class="Special"> &lt;- </span>put *sandbox, <span class="Constant">response:offset</span>, response
   *sandbox<span class="Special"> &lt;- </span>put *sandbox, <span class="Constant">screen:offset</span>, fake-screen
   *sandbox<span class="Special"> &lt;- </span>put *sandbox, <span class="Constant">trace:offset</span>, trace
diff --git a/html/edit/011-errors.mu.html b/html/edit/011-errors.mu.html
index 521006e4..b9db2f50 100644
--- a/html/edit/011-errors.mu.html
+++ b/html/edit/011-errors.mu.html
@@ -116,7 +116,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   data:address:array:character<span class="Special"> &lt;- </span>get *sandbox, <span class="Constant">data:offset</span>
-  response:address:array:character, errors:address:array:character, fake-screen:address:screen, trace:address:array:character, completed?:boolean<span class="Special"> &lt;- </span>run-interactive data
+  response:address:array:character, errors:address:array:character, fake-screen:address:screen, trace:address:array:character, completed?:boolean<span class="Special"> &lt;- </span>run-sandboxed data
   *sandbox<span class="Special"> &lt;- </span>put *sandbox, <span class="Constant">response:offset</span>, response
   *sandbox<span class="Special"> &lt;- </span>put *sandbox, <span class="Constant">errors:offset</span>, errors
   *sandbox<span class="Special"> &lt;- </span>put *sandbox, <span class="Constant">screen:offset</span>, fake-screen
diff --git a/html/lambda-to-mu.mu.html b/html/lambda-to-mu.mu.html
index 0478a1b7..d93a8b00 100644
--- a/html/lambda-to-mu.mu.html
+++ b/html/lambda-to-mu.mu.html
@@ -599,6 +599,24 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
     <span class="Constant">40</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[ghi]</span>  <span class="Comment"># result.rest.rest</span>
   ]
 ]
+
+<span class="SalientComment">## convert tree of cells to mu text</span>
+
+<span class="muRecipe">def</span> to-mu in:address:cell<span class="muRecipe"> -&gt; </span>out:address:array:character [
+  <span class="Constant">local-scope</span>
+  <span class="Constant">load-ingredients</span>
+  buf:address:buffer<span class="Special"> &lt;- </span>new-buffer <span class="Constant">30</span>
+  buf<span class="Special"> &lt;- </span>to-mu in, buf
+  out<span class="Special"> &lt;- </span>buffer-to-array buf
+]
+
+<span class="muRecipe">def</span> to-mu in:address:cell, buf:address:buffer<span class="muRecipe"> -&gt; </span>buf:address:buffer, result-name:address:array:character [
+  <span class="Constant">local-scope</span>
+  <span class="Constant">load-ingredients</span>
+  <span class="Comment"># null cell? no change.</span>
+  <span class="Comment"># pair with all atoms? gensym a new variable</span>
+  <span class="Comment"># pair containing other pairs? recurse</span>
+]
 </pre>
 </body>
 </html>