about summary refs log tree commit diff stats
path: root/html/081run_interactive.cc.html
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-07-12 00:11:56 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-07-12 00:11:56 -0700
commitd5d908dda655c791329563522faad42d7e4ee618 (patch)
tree628b8a23e13878c45ef39dfbffb860c676da5304 /html/081run_interactive.cc.html
parent9864bdd0792b697d7b03e692ba7f82cf5669c41c (diff)
downloadmu-d5d908dda655c791329563522faad42d7e4ee618.tar.gz
1766
Diffstat (limited to 'html/081run_interactive.cc.html')
-rw-r--r--html/081run_interactive.cc.html298
1 files changed, 218 insertions, 80 deletions
diff --git a/html/081run_interactive.cc.html b/html/081run_interactive.cc.html
index cdd3a5b7..5183cee6 100644
--- a/html/081run_interactive.cc.html
+++ b/html/081run_interactive.cc.html
@@ -13,11 +13,12 @@
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 * { font-size: 1.05em; }
+.traceContains { color: #008000; }
 .cSpecial { color: #008000; }
 .Constant { color: #00a0a0; }
 .Comment { color: #9090ff; }
 .Delimiter { color: #a04060; }
-.SalientComment { color: #00ffff; }
+.Special { color: #ff6060; }
 .CommentedCode { color: #6c6c6c; }
 .Identifier { color: #804000; }
 -->
@@ -31,79 +32,180 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 </head>
 <body>
 <pre id='vimCodeElement'>
-<span class="Comment">//: Helper for the repl.</span>
+<span class="Comment">//: Helper for various programming environments: run arbitrary mu code and</span>
+<span class="Comment">//: return some result in string form.</span>
 
+<span class="Delimiter">:(scenario run_interactive_code)</span>
+recipe main [
+  <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>new [<span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>:literal]
+  run-interactive <span class="Constant">2</span>:address:array:character
+]
+<span class="traceContains">+mem: storing 34 in location 1</span>
+
+<span class="Delimiter">:(scenario run_interactive_empty)</span>
+recipe main [
+  <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>run-interactive <span class="Constant">0</span>:literal
+]
+<span class="Comment"># result is null</span>
+<span class="traceContains">+mem: storing 0 in location 1</span>
+
+<span class="Comment">//: run code in 'interactive mode', i.e. with warnings off, and recording</span>
+<span class="Comment">//: output in case we want to print it to screen</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
 RUN_INTERACTIVE<span class="Delimiter">,</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
-Recipe_number[<span class="Constant">&quot;run-interactive&quot;</span>] = RUN_INTERACTIVE<span class="Delimiter">;</span>
+Recipe_ordinal[<span class="Constant">&quot;run-interactive&quot;</span>] = RUN_INTERACTIVE<span class="Delimiter">;</span>
 <span class="CommentedCode">//? cerr &lt;&lt; &quot;run-interactive: &quot; &lt;&lt; RUN_INTERACTIVE &lt;&lt; '\n'; //? 1</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
 case RUN_INTERACTIVE: <span class="Delimiter">{</span>
   assert<span class="Delimiter">(</span>scalar<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="CommentedCode">//?   cerr &lt;&lt; &quot;AAA 0\n&quot;; //? 1</span>
-  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="CommentedCode">//?   cerr &lt;&lt; &quot;ZZZ\n&quot;; //? 1</span>
-  <span class="Identifier">continue</span><span class="Delimiter">;</span>  <span class="Comment">// not done with caller; don't increment current_step_index()</span>
+  products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">);</span>
+  bool 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>
+  if <span class="Delimiter">(</span>!new_code_pushed_to_stack<span class="Delimiter">)</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><span class="Constant">0</span><span class="Delimiter">);</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>warnings_from_trace<span class="Delimiter">());</span>
+    <span class="Identifier">break</span><span class="Delimiter">;</span>  <span class="Comment">// done with this instruction</span>
+  <span class="Delimiter">}</span>
+  else <span class="Delimiter">{</span>
+    <span class="Identifier">continue</span><span class="Delimiter">;</span>  <span class="Comment">// not done with caller; don't increment current_step_index()</span>
+  <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
 
+<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
+bool Running_interactive = <span class="Constant">false</span><span class="Delimiter">;</span>
+<span class="Delimiter">:(before &quot;End Setup&quot;)</span>
+Running_interactive = <span class="Constant">false</span><span class="Delimiter">;</span>
 <span class="Delimiter">:(code)</span>
-<span class="Comment">// manual tests:</span>
-<span class="Comment">//  empty string (excluding whitespace and comments) does nothing</span>
-<span class="Comment">//  ctrl-d</span>
-<span class="Comment">//  just an integer (excluding whitespace and comments) prints value of that location in memory</span>
-<span class="Comment">//  instruction executes</span>
-<span class="Comment">//  backspace at start begins new attempt</span>
-void run_interactive<span class="Delimiter">(</span>long long int address<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="Comment">// reads a string, tries to call it as code, saving all warnings.</span>
+<span class="Comment">// returns true if successfully called (no errors found during load and transform)</span>
+bool run_interactive<span class="Delimiter">(</span>long long int address<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">&quot;interactive&quot;</span><span class="Delimiter">)</span> == Recipe_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
+    Recipe_ordinal[<span class="Constant">&quot;interactive&quot;</span>] = Next_recipe_ordinal++<span class="Delimiter">;</span>
+  string command = trim<span class="Delimiter">(</span>strip_comments<span class="Delimiter">(</span>to_string<span class="Delimiter">(</span>address<span class="Delimiter">)));</span>
+  if <span class="Delimiter">(</span>command<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
 <span class="CommentedCode">//?   tb_shutdown(); //? 1</span>
-  long long int size = Memory[address]<span class="Delimiter">;</span>
-  if <span class="Delimiter">(</span>size == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    ++current_step_index<span class="Delimiter">();</span>
-    <span class="Identifier">return</span><span class="Delimiter">;</span>
-  <span class="Delimiter">}</span>
-  ostringstream tmp<span class="Delimiter">;</span>
-  for <span class="Delimiter">(</span>long long int curr = address+<span class="Constant">1</span><span class="Delimiter">;</span> curr &lt; address+size<span class="Delimiter">;</span> ++curr<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    <span class="Comment">// todo: unicode</span>
-    tmp &lt;&lt; <span class="Delimiter">(</span>char<span class="Delimiter">)(</span>int<span class="Delimiter">)</span>Memory[curr]<span class="Delimiter">;</span>
-  <span class="Delimiter">}</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; size &lt;&lt; ' ' &lt;&lt; Memory[address+size] &lt;&lt; '\n'; //? 1</span>
-  assert<span class="Delimiter">(</span>Memory[address+size] == <span class="Constant">10</span><span class="Delimiter">);</span>  <span class="Comment">// skip the newline</span>
-  if <span class="Delimiter">(</span>Recipe_number<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">&quot;interactive&quot;</span><span class="Delimiter">)</span> == Recipe_number<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
-    Recipe_number[<span class="Constant">&quot;interactive&quot;</span>] = Next_recipe_number++<span class="Delimiter">;</span>
-  string command = trim<span class="Delimiter">(</span>strip_comments<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>str<span class="Delimiter">()));</span>
-  if <span class="Delimiter">(</span>command<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
-    ++current_step_index<span class="Delimiter">();</span>
-    <span class="Identifier">return</span><span class="Delimiter">;</span>
-  <span class="Delimiter">}</span>
-  if <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>command<span class="Delimiter">))</span> <span class="Delimiter">{</span>
-    print_value_of_location_as_response<span class="Delimiter">(</span>to_integer<span class="Delimiter">(</span>command<span class="Delimiter">));</span>
-    ++current_step_index<span class="Delimiter">();</span>
-    <span class="Identifier">return</span><span class="Delimiter">;</span>
-  <span class="Delimiter">}</span>
-<span class="CommentedCode">//?   exit(0); //? 1</span>
-  if <span class="Delimiter">(</span>Name[Recipe_number[<span class="Constant">&quot;interactive&quot;</span>]]<span class="Delimiter">.</span>find<span class="Delimiter">(</span>command<span class="Delimiter">)</span> != Name[Recipe_number[<span class="Constant">&quot;interactive&quot;</span>]]<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
-    print_value_of_location_as_response<span class="Delimiter">(</span>Name[Recipe_number[<span class="Constant">&quot;interactive&quot;</span>]][command]<span class="Delimiter">);</span>
-    ++current_step_index<span class="Delimiter">();</span>
-    <span class="Identifier">return</span><span class="Delimiter">;</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; command &lt;&lt; '\n'; //? 2</span>
+  Recipe<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>Recipe_ordinal[<span class="Constant">&quot;interactive&quot;</span>]<span class="Delimiter">);</span>
+  Hide_warnings = <span class="Constant">true</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>!Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    Trace_file = <span class="Constant">&quot;&quot;</span><span class="Delimiter">;</span>  <span class="Comment">// if there wasn't already a stream we don't want to save it</span>
+    Trace_stream = new trace_stream<span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
-<span class="CommentedCode">//?   tb_shutdown(); //? 1</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; command; //? 1</span>
-<span class="CommentedCode">//?   exit(0); //? 1</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; &quot;AAA 1\n&quot;; //? 1</span>
-  Recipe<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>Recipe_number[<span class="Constant">&quot;interactive&quot;</span>]<span class="Delimiter">);</span>
   <span class="Comment">// call run(string) but without the scheduling</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; (&quot;recipe interactive [\n&quot;+command+&quot;\n]\n&quot;); //? 1</span>
   load<span class="Delimiter">(</span><span class="Constant">&quot;recipe interactive [</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>+command+<span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">]</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">);</span>
   transform_all<span class="Delimiter">();</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; &quot;names: &quot; &lt;&lt; Name[Recipe_number[&quot;interactive&quot;]].size() &lt;&lt; &quot;; &quot;; //? 1</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; &quot;steps: &quot; &lt;&lt; Recipe[Recipe_number[&quot;interactive&quot;]].steps.size() &lt;&lt; &quot;; &quot;; //? 1</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; &quot;interactive transformed_until: &quot; &lt;&lt; Recipe[Recipe_number[&quot;interactive&quot;]].transformed_until &lt;&lt; '\n'; //? 1</span>
-  Current_routine<span class="Delimiter">-&gt;</span>calls<span class="Delimiter">.</span>push_front<span class="Delimiter">(</span>call<span class="Delimiter">(</span>Recipe_number[<span class="Constant">&quot;interactive&quot;</span>]<span class="Delimiter">));</span>
+  if <span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span><span class="Constant">&quot;warn&quot;</span><span class="Delimiter">)</span> &gt; <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    Hide_warnings = <span class="Constant">false</span><span class="Delimiter">;</span>
+    <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
+  Running_interactive = <span class="Constant">true</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>Recipe_ordinal[<span class="Constant">&quot;interactive&quot;</span>]<span class="Delimiter">));</span>
+  <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(after &quot;Starting Reply&quot;)</span>
+if <span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">()</span> == <span class="Constant">&quot;interactive&quot;</span><span class="Delimiter">)</span> clean_up_interactive<span class="Delimiter">();</span>
+<span class="Delimiter">:(after &quot;Falling Through End Of Recipe&quot;)</span>
+if <span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">()</span> == <span class="Constant">&quot;interactive&quot;</span><span class="Delimiter">)</span> clean_up_interactive<span class="Delimiter">();</span>
+<span class="Delimiter">:(code)</span>
+void clean_up_interactive<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?   static int foo = 0; //? 1</span>
+  Hide_warnings = <span class="Constant">false</span><span class="Delimiter">;</span>
+  Running_interactive = <span class="Constant">false</span><span class="Delimiter">;</span>
+<span class="CommentedCode">//?   ++foo; //? 1</span>
+<span class="CommentedCode">//?   if (foo == 1) tb_init(); //? 1</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario &quot;run_interactive_returns_stringified_result&quot;)</span>
+recipe 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>new [add <span class="Constant">2</span>:literal<span class="Delimiter">,</span> <span class="Constant">2</span>:literal]
+  <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">10</span>:array:character<span class="Special"> &lt;- </span>copy <span class="Constant">2</span>:address:array:character/deref
+]
+<span class="Comment"># first letter in the output should be '4' in unicode</span>
+<span class="traceContains">+mem: storing 52 in location 11</span>
+
+<span class="Delimiter">:(scenario &quot;run_interactive_returns_string&quot;)</span>
+recipe 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>new [
+    <span class="Constant">100</span>:address:array:character<span class="Special"> &lt;- </span>new [a]
+    <span class="Constant">101</span>:address:array:character<span class="Special"> &lt;- </span>new [b]
+    <span class="Constant">102</span>:address:array:character<span class="Special"> &lt;- </span>string-append <span class="Constant">100</span>:address:array:character<span class="Delimiter">,</span> <span class="Constant">101</span>: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">10</span>:array:character<span class="Special"> &lt;- </span>copy <span class="Constant">2</span>:address:array:character/deref
+]
+<span class="Comment"># output contains &quot;ab&quot;</span>
+<span class="traceContains">+mem: storing 97 in location 11</span>
+<span class="traceContains">+mem: storing 98 in location 12</span>
+
+<span class="Delimiter">:(scenario &quot;run_interactive_returns_warnings&quot;)</span>
+recipe main [
+  <span class="Comment"># run a command that generates a warning</span>
+  <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new [get <span class="Constant">1234</span>: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">10</span>:array:character<span class="Special"> &lt;- </span>copy <span class="Constant">3</span>:address:array:character/deref
+]
+<span class="Comment"># warning should be &quot;unknown element foo in container number&quot;</span>
+<span class="traceContains">+mem: storing 117 in location 11</span>
+<span class="traceContains">+mem: storing 110 in location 12</span>
+<span class="traceContains">+mem: storing 107 in location 13</span>
+<span class="traceContains">+mem: storing 110 in location 14</span>
+
+<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
+string Most_recent_results<span class="Delimiter">;</span>
+<span class="Delimiter">:(before &quot;End Setup&quot;)</span>
+Most_recent_results = <span class="Constant">&quot;&quot;</span><span class="Delimiter">;</span>
+<span class="Delimiter">:(before &quot;End of Instruction&quot;)</span>
+if <span class="Delimiter">(</span>Running_interactive<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  record_products<span class="Delimiter">(</span>current_instruction<span class="Delimiter">(),</span> products<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(code)</span>
+void record_products<span class="Delimiter">(</span>const instruction&amp; instruction<span class="Delimiter">,</span> const vector&lt;vector&lt;double&gt; &gt;&amp; products<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  ostringstream out<span class="Delimiter">;</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; current_instruction().to_string() &lt;&lt; '\n'; //? 1</span>
+  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    <span class="Comment">// string</span>
+    if <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="CommentedCode">//?       cerr &lt;&lt; &quot;AA\n&quot;; //? 1</span>
+<span class="CommentedCode">//?       cerr &lt;&lt; instruction.products.size() &lt;&lt; &quot; vs &quot; &lt;&lt; i &lt;&lt; '\n'; //? 1</span>
+      if <span class="Delimiter">(</span>is_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="CommentedCode">//?         cerr &lt;&lt; &quot;BB\n&quot;; //? 1</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>
+        out &lt;&lt; to_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>
+      <span class="Comment">// End Record Product Special-cases</span>
+    <span class="Delimiter">}</span>
+    for <span class="Delimiter">(</span>long long int 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> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?       cerr &lt;&lt; &quot;aa: &quot; &lt;&lt; i &lt;&lt; &quot;, &quot; &lt;&lt; j &lt;&lt; &quot;: &quot; &lt;&lt; products.at(i).at(j) &lt;&lt; '\n'; //? 1</span>
+        out &lt;&lt; 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>
+    <span class="Delimiter">}</span>
+    out &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;aa: {\n&quot; &lt;&lt; out.str() &lt;&lt; &quot;}\n&quot;; //? 2</span>
+  Most_recent_results = out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before &quot;Complete Call Fallthrough&quot;)</span>
+if <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>operation == RUN_INTERACTIVE &amp;&amp; !current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+  assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">)</span> &lt;= <span class="Constant">2</span><span class="Delimiter">);</span>
+  <span class="Comment">// Send the results of the most recently executed instruction, regardless of</span>
+  <span class="Comment">// call depth, to be converted to string and potentially printed to string.</span>
+  vector&lt;double&gt; result<span class="Delimiter">;</span>
+  result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_string<span class="Delimiter">(</span>Most_recent_results<span class="Delimiter">));</span>
+  write_memory<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> result<span class="Delimiter">);</span>
+  if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">)</span> == <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    vector&lt;double&gt; warnings<span class="Delimiter">;</span>
+    warnings<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>warnings_from_trace<span class="Delimiter">());</span>
+    write_memory<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">),</span> warnings<span class="Delimiter">);</span>
+  <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
 
+<span class="Delimiter">:(code)</span>
 string strip_comments<span class="Delimiter">(</span>string in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   ostringstream result<span class="Delimiter">;</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; in; //? 1</span>
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>in<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> != <span class="Constant">'#'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
       result &lt;&lt; in<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
@@ -114,43 +216,79 @@ string strip_comments<span class="Delimiter">(</span>string in<span class="Delim
       if <span class="Delimiter">(</span>i &lt; SIZE<span class="Delimiter">(</span>in<span class="Delimiter">)</span> &amp;&amp; in<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> ++i<span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
   <span class="Delimiter">}</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; &quot;ZZZ&quot;; //? 1</span>
   <span class="Identifier">return</span> result<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
 <span class="Delimiter">}</span>
 
-void print_value_of_location_as_response<span class="Delimiter">(</span>long long int address<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+string to_string<span class="Delimiter">(</span>long long int address<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  long long int size = Memory[address]<span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>size == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">&quot;&quot;</span><span class="Delimiter">;</span>
+  ostringstream tmp<span class="Delimiter">;</span>
+  for <span class="Delimiter">(</span>long long int curr = address+<span class="Constant">1</span><span class="Delimiter">;</span> curr &lt;= address+size<span class="Delimiter">;</span> ++curr<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    <span class="Comment">// todo: unicode</span>
+    tmp &lt;&lt; <span class="Delimiter">(</span>char<span class="Delimiter">)(</span>int<span class="Delimiter">)</span>Memory[curr]<span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
+<span class="CommentedCode">//?   tb_shutdown(); //? 1</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; tmp.str() &lt;&lt; '\n'; //? 1</span>
+  <span class="Identifier">return</span> tmp<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
+<span class="Delimiter">}</span>
+
+long long int stringified_value_of_location<span class="Delimiter">(</span>long long int address<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   <span class="Comment">// convert to string</span>
   ostringstream out<span class="Delimiter">;</span>
-  out &lt;&lt; <span class="Constant">&quot;=&gt; &quot;</span> &lt;&lt; Memory[address]<span class="Delimiter">;</span>
-  string result = out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
-  <span class="Comment">// handle regular I/O</span>
-  if <span class="Delimiter">(</span>!tb_is_active<span class="Delimiter">())</span> <span class="Delimiter">{</span>
-    cerr &lt;&lt; result &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
-    <span class="Identifier">return</span><span class="Delimiter">;</span>
-  <span class="Delimiter">}</span>
-  <span class="Comment">// raw I/O; use termbox to print</span>
-  long long int bound = SIZE<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
-  if <span class="Delimiter">(</span>bound &gt; tb_width<span class="Delimiter">())</span> bound = tb_width<span class="Delimiter">();</span>
-  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; bound<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    tb_change_cell<span class="Delimiter">(</span>i<span class="Delimiter">,</span> Display_row<span class="Delimiter">,</span> result<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> <span class="Comment">/*</span><span class="Comment">computer's color</span><span class="Comment">*/</span><span class="Constant">245</span><span class="Delimiter">,</span> TB_BLACK<span class="Delimiter">);</span>
-  <span class="Delimiter">}</span>
-  <span class="Comment">// newline</span>
-  if <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>
-  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>
-  tb_present<span class="Delimiter">();</span>
+<span class="CommentedCode">//?   trace(1, &quot;foo&quot;) &lt;&lt; &quot;a: &quot; &lt;&lt; address; //? 1</span>
+  out &lt;&lt; Memory[address]<span class="Delimiter">;</span>
+<span class="CommentedCode">//?   trace(1, &quot;foo&quot;) &lt;&lt; &quot;b: &quot; &lt;&lt; Memory[address]; //? 1</span>
+  <span class="Identifier">return</span> new_string<span class="Delimiter">(</span>out<span class="Delimiter">.</span>str<span class="Delimiter">());</span>
+<span class="Delimiter">}</span>
+
+bool is_string<span class="Delimiter">(</span>const reagent&amp; x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  <span class="Identifier">return</span> x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>size<span class="Delimiter">()</span> == <span class="Constant">3</span>
+      &amp;&amp; x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == Type_ordinal[<span class="Constant">&quot;address&quot;</span>]
+      &amp;&amp; x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)</span> == Type_ordinal[<span class="Constant">&quot;array&quot;</span>]
+      &amp;&amp; x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">)</span> == Type_ordinal[<span class="Constant">&quot;character&quot;</span>]<span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
-<span class="SalientComment">//:: debugging tool</span>
+long long int warnings_from_trace<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>!Trace_stream<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span><span class="Constant">&quot;warn&quot;</span><span class="Delimiter">)</span> &lt;= <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
+  ostringstream out<span class="Delimiter">;</span>
+  for <span class="Delimiter">(</span>vector&lt;trace_line&gt;::iterator p = Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    if <span class="Delimiter">(</span>p<span class="Delimiter">-&gt;</span>label != <span class="Constant">&quot;warn&quot;</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+    out &lt;&lt; p<span class="Delimiter">-&gt;</span>contents<span class="Delimiter">;</span>
+    if <span class="Delimiter">(</span>*--p<span class="Delimiter">-&gt;</span>contents<span class="Delimiter">.</span>end<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> out &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
+  assert<span class="Delimiter">(</span>!out<span class="Delimiter">.</span>str<span class="Delimiter">().</span>empty<span class="Delimiter">());</span>
+  <span class="Identifier">return</span> new_string<span class="Delimiter">(</span>out<span class="Delimiter">.</span>str<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">//: recipes and reports warnings.</span>
+<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
+bool Loading_interactive = <span class="Constant">false</span><span class="Delimiter">;</span>
+<span class="Delimiter">:(before &quot;End Setup&quot;)</span>
+Loading_interactive = <span class="Constant">false</span><span class="Delimiter">;</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
-_RUN_DEPTH<span class="Delimiter">,</span>
+RELOAD<span class="Delimiter">,</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
-Recipe_number[<span class="Constant">&quot;$run-depth&quot;</span>] = _RUN_DEPTH<span class="Delimiter">;</span>
+Recipe_ordinal[<span class="Constant">&quot;reload&quot;</span>] = RELOAD<span class="Delimiter">;</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
-case _RUN_DEPTH: <span class="Delimiter">{</span>
-  cerr &lt;&lt; Current_routine<span class="Delimiter">-&gt;</span>calls<span class="Delimiter">.</span>size<span class="Delimiter">();</span>
+case RELOAD: <span class="Delimiter">{</span>
+  assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
+  Loading_interactive = <span class="Constant">true</span><span class="Delimiter">;</span>
+  Hide_warnings = <span class="Constant">true</span><span class="Delimiter">;</span>
+  load<span class="Delimiter">(</span>to_string<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="CommentedCode">//?   static int foo = 0;</span>
+<span class="CommentedCode">//?   if (++foo == 2) {</span>
+<span class="CommentedCode">//?     tb_shutdown();</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; Recipe_ordinal[&quot;new-add&quot;] &lt;&lt; '\n';</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; Recipe[Recipe_ordinal[&quot;new-add&quot;]].steps[2].to_string() &lt;&lt; '\n';</span>
+<span class="CommentedCode">//?     exit(0);</span>
+<span class="CommentedCode">//?   }</span>
+  transform_all<span class="Delimiter">();</span>
+  Hide_warnings = <span class="Constant">false</span><span class="Delimiter">;</span>
+  Loading_interactive = <span class="Constant">false</span><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>warnings_from_trace<span class="Delimiter">());</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 </pre>