about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-07-20 18:05:56 -0700
committerKartik K. Agaram <vc@akkartik.com>2016-07-20 18:05:56 -0700
commite81da299fb49bd79cd460d477ec0bb673035620a (patch)
treee4b162be797dcb6d2793a5f7831c6c39bd099a85
parentedfc4cf8ac21a30307cd36bb9cff6a4a8b92dee7 (diff)
downloadmu-e81da299fb49bd79cd460d477ec0bb673035620a.tar.gz
3117
-rw-r--r--html/020run.cc.html2
-rw-r--r--html/025compare.cc.html54
-rw-r--r--html/026call.cc.html2
-rw-r--r--html/030container.cc.html2
-rw-r--r--html/031merge.cc.html1
-rw-r--r--html/032array.cc.html21
-rw-r--r--html/033exclusive_container.cc.html1
-rw-r--r--html/045closure_name.cc.html3
-rw-r--r--html/047check_type_by_name.cc.html5
-rw-r--r--html/050scenario.cc.html34
-rw-r--r--html/052tangle.cc.html1
-rw-r--r--html/054static_dispatch.cc.html1
-rw-r--r--html/055shape_shifting_container.cc.html21
-rw-r--r--html/056shape_shifting_recipe.cc.html2
-rw-r--r--html/060rewrite_literal_string.cc.html1
-rw-r--r--html/071scheduler.cc.html58
-rw-r--r--html/082scenario_screen.cc.html3
-rw-r--r--html/091run_interactive.cc.html10
-rw-r--r--html/edit/010-sandbox-trace.mu.html7
-rw-r--r--html/edit/011-errors.mu.html7
20 files changed, 199 insertions, 37 deletions
diff --git a/html/020run.cc.html b/html/020run.cc.html
index 1a8359bd..6674be65 100644
--- a/html/020run.cc.html
+++ b/html/020run.cc.html
@@ -317,7 +317,7 @@ vector&lt;<span class="Normal">double</span>&gt; read_memory<span class="Delimit
   <span class="Comment">// End Preprocess write_memory(x, data)</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>size_mismatch<span class="Delimiter">(</span>x<span class="Delimiter">,</span> data<span class="Delimiter">))</span> <span class="Delimiter">{</span>
-    raise &lt;&lt; maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> &lt;&lt; <span class="Constant">&quot;size mismatch in storing to '&quot;</span> &lt;&lt; x<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;' (&quot;</span> &lt;&lt; size_of<span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; vs &quot;</span> &lt;&lt; SIZE<span class="Delimiter">(</span>data<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;) at '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>current_instruction<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>current_recipe_name<span class="Delimiter">())</span> &lt;&lt; <span class="Constant">&quot;size mismatch in storing to '&quot;</span> &lt;&lt; x<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;' (&quot;</span> &lt;&lt; size_of<span class="Delimiter">(</span>x<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; vs &quot;</span> &lt;&lt; SIZE<span class="Delimiter">(</span>data<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;) at '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>current_instruction<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">return</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   <span class="Comment">// End write_memory(x) Special-cases</span>
diff --git a/html/025compare.cc.html b/html/025compare.cc.html
index 56e90d10..37c7c8c5 100644
--- a/html/025compare.cc.html
+++ b/html/025compare.cc.html
@@ -109,6 +109,60 @@ def main [
 <span class="traceContains">+mem: storing 0 in location 1</span>
 
 <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
+NOT_EQUAL<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;not-equal&quot;</span><span class="Delimiter">,</span> NOT_EQUAL<span class="Delimiter">);</span>
+<span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span>
+<span class="Normal">case</span> NOT_EQUAL: <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">2</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;'equal' needs two ingredients to compare in '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>inst<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="Normal">const</span> reagent&amp; exemplar = 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="Normal">if</span> <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">),</span> exemplar<span class="Delimiter">)</span> &amp;&amp; !types_match<span class="Delimiter">(</span>exemplar<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<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;'equal' expects ingredients to be all of the same type, but got '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>inst<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">goto</span> finish_checking_instruction<span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">)</span> &gt; <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;'equal' yields exactly one product in '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>inst<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="Normal">if</span> <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> &amp;&amp; !is_dummy<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> &amp;&amp; !is_mu_boolean<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<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;'equal' should yield a boolean, but got '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><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="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> NOT_EQUAL: <span class="Delimiter">{</span>
+  vector&lt;<span class="Normal">double</span>&gt;&amp; exemplar = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+  products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
+  <span class="Normal">bool</span> equal_ingredients = equal<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>begin<span class="Delimiter">(),</span> ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>end<span class="Delimiter">(),</span> exemplar<span class="Delimiter">.</span>begin<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>!equal_ingredients<span class="Delimiter">);</span>
+  <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario not_equal)</span>
+def main [
+  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
+  <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">33</span>
+  <span class="Constant">3</span>:boolean<span class="Special"> &lt;- </span><span class="Normal">not</span>-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number
+]
+<span class="traceContains">+mem: location 1 is 34</span>
+<span class="traceContains">+mem: location 2 is 33</span>
+<span class="traceContains">+mem: storing 1 in location 3</span>
+
+<span class="Delimiter">:(scenario not_equal_2)</span>
+def main [
+  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
+  <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
+  <span class="Constant">3</span>:boolean<span class="Special"> &lt;- </span><span class="Normal">not</span>-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number
+]
+<span class="traceContains">+mem: location 1 is 34</span>
+<span class="traceContains">+mem: location 2 is 34</span>
+<span class="traceContains">+mem: storing 0 in location 3</span>
+
+<span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
 GREATER_THAN<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;greater-than&quot;</span><span class="Delimiter">,</span> GREATER_THAN<span class="Delimiter">);</span>
diff --git a/html/026call.cc.html b/html/026call.cc.html
index 229f0fc8..83224e28 100644
--- a/html/026call.cc.html
+++ b/html/026call.cc.html
@@ -196,7 +196,7 @@ def main [
     assert<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-&gt;</span>callstack_depth &gt;= <span class="Constant">0</span><span class="Delimiter">);</span>
   <span class="Delimiter">}</span>
   Current_routine<span class="Delimiter">-&gt;</span>calls<span class="Delimiter">.</span>pop_front<span class="Delimiter">();</span>
-  <span class="Normal">if</span> <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-&gt;</span>calls<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-&gt;</span>calls<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">goto</span> stop_running_current_routine<span class="Delimiter">;</span>
   <span class="Comment">// Complete Call Fallthrough</span>
   <span class="Comment">// todo: fail if no products returned</span>
   ++current_step_index<span class="Delimiter">();</span>
diff --git a/html/030container.cc.html b/html/030container.cc.html
index a7f5d552..49fcef97 100644
--- a/html/030container.cc.html
+++ b/html/030container.cc.html
@@ -527,7 +527,6 @@ container foo [
   <span class="Normal">x</span>:number
   <span class="Normal">y</span>:bar
 ]
-
 container bar [
   <span class="Normal">x</span>:number
   <span class="Normal">y</span>:number
@@ -690,7 +689,6 @@ def main [
 def main [
   <span class="Constant">1</span>:bar<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/unsafe
 ]
-
 container bar [
   <span class="Normal">x</span>:number
 ]
diff --git a/html/031merge.cc.html b/html/031merge.cc.html
index 34dc65a9..4d590cd2 100644
--- a/html/031merge.cc.html
+++ b/html/031merge.cc.html
@@ -40,7 +40,6 @@ container foo [
   <span class="Normal">x</span>:number
   <span class="Normal">y</span>:number
 ]
-
 def main [
   <span class="Constant">1</span>:foo<span class="Special"> &lt;- </span>merge <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">4</span>
 ]
diff --git a/html/032array.cc.html b/html/032array.cc.html
index fb9bb0d5..c432da93 100644
--- a/html/032array.cc.html
+++ b/html/032array.cc.html
@@ -147,7 +147,7 @@ def main [
 <span class="Comment">//: arrays are disallowed inside containers unless their length is fixed in</span>
 <span class="Comment">//: advance</span>
 
-<span class="Delimiter">:(scenario container_contains_array)</span>
+<span class="Delimiter">:(scenario container_permits_static_array_element)</span>
 container foo [
   <span class="Normal">x</span>:array:number:<span class="Constant">3</span>
 ]
@@ -160,6 +160,25 @@ container foo [
 ]
 <span class="traceContains">+error: container 'foo' cannot determine size of element 'x'</span>
 
+<span class="Comment">//: disable the size mismatch check for 'merge' instructions since containers</span>
+<span class="Comment">//: can contain arrays, and since we already do plenty of checking for them</span>
+<span class="Delimiter">:(before &quot;End size_mismatch(x) Cases&quot;)</span>
+<span class="Normal">if</span> <span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>running_step_index &lt; SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> current_call<span class="Delimiter">().</span>running_recipe<span class="Delimiter">).</span>steps<span class="Delimiter">)</span>
+    &amp;&amp; current_instruction<span class="Delimiter">().</span>operation == MERGE<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario merge_static_array_into_container)</span>
+container foo [
+  <span class="Normal">x</span>:number
+  <span class="Normal">y</span>:array:number:<span class="Constant">3</span>
+]
+def main [
+  <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> &lt;- </span>create-array
+  <span class="Constant">10</span>:foo<span class="Special"> &lt;- </span>merge <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">1</span>:array:number:<span class="Constant">3</span>
+]
+<span class="Comment"># no errors</span>
+
 <span class="Delimiter">:(before &quot;End Load Container Element Definition&quot;)</span>
 <span class="Delimiter">{</span>
   <span class="Normal">const</span> type_tree* type = info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>back<span class="Delimiter">().</span>type<span class="Delimiter">;</span>
diff --git a/html/033exclusive_container.cc.html b/html/033exclusive_container.cc.html
index 70af4cac..5dfe9521 100644
--- a/html/033exclusive_container.cc.html
+++ b/html/033exclusive_container.cc.html
@@ -266,7 +266,6 @@ exclusive-container foo [
   <span class="Normal">x</span>:number
   <span class="Normal">y</span>:number
 ]
-
 def main [
   <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
   <span class="Constant">2</span>:foo<span class="Special"> &lt;- </span>merge <span class="Constant">0</span>/x<span class="Delimiter">,</span> <span class="Constant">1</span>:number  <span class="Comment"># tag must be a literal when merging exclusive containers</span>
diff --git a/html/045closure_name.cc.html b/html/045closure_name.cc.html
index 66b899f0..210327f6 100644
--- a/html/045closure_name.cc.html
+++ b/html/045closure_name.cc.html
@@ -45,14 +45,12 @@ def main [
   <span class="Constant">2</span>:number/<span class="Special">raw &lt;- </span>increment-counter <span class="Constant">1</span>:address:array:location/names:<span class="Normal">new</span>-counter
   <span class="Constant">3</span>:number/<span class="Special">raw &lt;- </span>increment-counter <span class="Constant">1</span>:address:array:location/names:<span class="Normal">new</span>-counter
 ]
-
 def <span class="Normal">new</span>-counter [
   <span class="Normal">default</span>-space:address:array:location<span class="Special"> &lt;- </span><span class="Normal">new</span> location:type<span class="Delimiter">,</span> <span class="Constant">30</span>
   <span class="Normal">x</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">23</span>
   <span class="Normal">y</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">3</span>  <span class="Comment"># variable that will be incremented</span>
   <span class="Identifier">return</span> <span class="Normal">default</span>-space:address:array:location
 ]
-
 def increment-counter [
   <span class="Normal">default</span>-space:address:array:location<span class="Special"> &lt;- </span><span class="Normal">new</span> location:type<span class="Delimiter">,</span> <span class="Constant">30</span>
   <span class="Constant">0</span>:address:array:location/names:<span class="Normal">new</span>-counter<span class="Special"> &lt;- </span>next-ingredient  <span class="Comment"># outer space must be created by 'new-counter' above</span>
@@ -60,7 +58,6 @@ def increment-counter [
   <span class="Normal">y</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">234</span>  <span class="Comment"># dummy</span>
   <span class="Identifier">return</span> y:number/space:<span class="Constant">1</span>
 ]
-
 <span class="traceContains">+name: lexically surrounding space for recipe increment-counter comes from new-counter</span>
 <span class="traceContains">+mem: storing 5 in location 3</span>
 
diff --git a/html/047check_type_by_name.cc.html b/html/047check_type_by_name.cc.html
index d1c5bae4..b67e8b36 100644
--- a/html/047check_type_by_name.cc.html
+++ b/html/047check_type_by_name.cc.html
@@ -105,18 +105,23 @@ def main [
   <span class="Normal">x</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>
   <span class="Normal">y</span>:number<span class="Special"> &lt;- </span>add x<span class="Delimiter">,</span> <span class="Constant">1</span>
 ]
+<span class="Comment"># x is in location 1, y in location 2</span>
+<span class="traceContains">+mem: storing 2 in location 2</span>
 
 <span class="Delimiter">:(scenario transform_fills_in_missing_types_in_product)</span>
 def main [
   <span class="Normal">x</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>
   x<span class="Special"> &lt;- </span>copy <span class="Constant">2</span>
 ]
+<span class="Comment"># x is in location 1</span>
+<span class="traceContains">+mem: storing 2 in location 1</span>
 
 <span class="Delimiter">:(scenario transform_fills_in_missing_types_in_product_and_ingredient)</span>
 def main [
   <span class="Normal">x</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>
   x<span class="Special"> &lt;- </span>add x<span class="Delimiter">,</span> <span class="Constant">1</span>
 ]
+<span class="Comment"># x is in location 1</span>
 <span class="traceContains">+mem: storing 2 in location 1</span>
 
 <span class="Delimiter">:(scenario transform_fails_on_missing_types_in_first_mention)</span>
diff --git a/html/050scenario.cc.html b/html/050scenario.cc.html
index e8a8d028..213874ff 100644
--- a/html/050scenario.cc.html
+++ b/html/050scenario.cc.html
@@ -69,6 +69,7 @@ scenario foo [
     <span class="Constant">2</span><span class="Special"> &lt;- </span><span class="Constant">13</span>
   ]
 ]
+<span class="Comment"># checks are inside scenario</span>
 
 <span class="Delimiter">:(scenario scenario_check_memory_and_trace)</span>
 scenario foo [
@@ -86,6 +87,7 @@ scenario foo [
     <span class="Normal">a</span>: x y z
   ]
 ]
+<span class="Comment"># checks are inside scenario</span>
 
 <span class="SalientComment">//:: Core data structure</span>
 
@@ -257,7 +259,6 @@ Name[r][<span class="Constant">&quot;__maybe_make_raw_test__&quot;</span>] = Res
 def scenario-foo [
   <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
 ]
-
 def scenario-foo [
   <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">35</span>
 ]
@@ -540,7 +541,7 @@ def main [
     <span class="Normal">a</span>: d
   ]
 ]
-<span class="traceContains">+error: missing [b] in trace with label a</span>
+<span class="traceContains">+error: missing [b] in trace with label 'a'</span>
 
 <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
 TRACE_SHOULD_CONTAIN<span class="Delimiter">,</span>
@@ -573,8 +574,14 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span
     <span class="Normal">if</span> <span class="Delimiter">(</span>curr_expected_line == SIZE<span class="Delimiter">(</span>expected_lines<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
 
-  raise &lt;&lt; <span class="Constant">&quot;missing [&quot;</span> &lt;&lt; expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>contents &lt;&lt; <span class="Constant">&quot;] &quot;</span>
-              &lt;&lt; <span class="Constant">&quot;in trace with label &quot;</span> &lt;&lt; expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>label &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>Current_scenario &amp;&amp; !Scenario_testing_scenario<span class="Delimiter">)</span>
+    raise &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">F - &quot;</span> &lt;&lt; Current_scenario<span class="Delimiter">-&gt;</span>name &lt;&lt; <span class="Constant">&quot;: missing [&quot;</span> &lt;&lt; expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>contents &lt;&lt; <span class="Constant">&quot;] &quot;</span>
+          &lt;&lt; <span class="Constant">&quot;in trace with label '&quot;</span> &lt;&lt; expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>label &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="Normal">else</span>
+    raise &lt;&lt; <span class="Constant">&quot;missing [&quot;</span> &lt;&lt; expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>contents &lt;&lt; <span class="Constant">&quot;] &quot;</span>
+          &lt;&lt; <span class="Constant">&quot;in trace with label '&quot;</span> &lt;&lt; expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>label &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="Normal">if</span> <span class="Delimiter">(</span>!Hide_errors<span class="Delimiter">)</span>
+    DUMP<span class="Delimiter">(</span>expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>label<span class="Delimiter">);</span>
   Passed = <span class="Constant">false</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
@@ -602,7 +609,7 @@ def main [
     <span class="Normal">a</span>: d
   ]
 ]
-<span class="traceContains">+error: missing [d] in trace with label a</span>
+<span class="traceContains">+error: missing [d] in trace with label 'a'</span>
 
 <span class="Delimiter">:(scenario trace_check_passes_silently)</span>
 <span class="Special">% Scenario_testing_scenario = true;</span>
@@ -614,7 +621,7 @@ def main [
     <span class="Normal">a</span>: b
   ]
 ]
-<span class="traceAbsent">-error: missing [b] in trace with label a</span>
+<span class="traceAbsent">-error: missing [b] in trace with label 'a'</span>
 $error: <span class="Constant">0</span>
 
 <span class="Comment">//: 'trace-should-not-contain' is like the '-' lines in our scenarios so far</span>
@@ -632,7 +639,7 @@ def main [
     <span class="Normal">a</span>: b
   ]
 ]
-<span class="traceContains">+error: unexpected [b] in trace with label a</span>
+<span class="traceContains">+error: unexpected [b] in trace with label 'a'</span>
 
 <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
 TRACE_SHOULD_NOT_CONTAIN<span class="Delimiter">,</span>
@@ -657,7 +664,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span
   vector&lt;trace_line&gt; lines = parse_trace<span class="Delimiter">(</span>in<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>lines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     <span class="Normal">if</span> <span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span>lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>label<span class="Delimiter">,</span> lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>contents<span class="Delimiter">)</span> != <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
-      raise &lt;&lt; <span class="Constant">&quot;unexpected [&quot;</span> &lt;&lt; lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>contents &lt;&lt; <span class="Constant">&quot;] in trace with label &quot;</span> &lt;&lt; lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>label &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+      raise &lt;&lt; <span class="Constant">&quot;unexpected [&quot;</span> &lt;&lt; lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>contents &lt;&lt; <span class="Constant">&quot;] in trace with label '&quot;</span> &lt;&lt; lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>label &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
       Passed = <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>
@@ -672,7 +679,7 @@ def main [
     <span class="Normal">a</span>: b
   ]
 ]
-<span class="traceAbsent">-error: unexpected [b] in trace with label a</span>
+<span class="traceAbsent">-error: unexpected [b] in trace with label 'a'</span>
 $error: <span class="Constant">0</span>
 
 <span class="Delimiter">:(scenario trace_negative_check_fails_on_any_unexpected_line)</span>
@@ -687,7 +694,7 @@ def main [
     <span class="Normal">a</span>: d
   ]
 ]
-<span class="traceContains">+error: unexpected [d] in trace with label a</span>
+<span class="traceContains">+error: unexpected [d] in trace with label 'a'</span>
 
 <span class="Delimiter">:(scenario trace_count_check)</span>
 def main [
@@ -696,6 +703,7 @@ def main [
   ]
   check-trace-count-<span class="Normal">for</span>-label <span class="Constant">1</span><span class="Delimiter">,</span> [a]
 ]
+<span class="Comment"># checks are inside scenario</span>
 
 <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
 CHECK_TRACE_COUNT_FOR_LABEL<span class="Delimiter">,</span>
@@ -726,12 +734,12 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span
   <span class="Normal">if</span> <span class="Delimiter">(</span>count != expected_count<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     <span class="Normal">if</span> <span class="Delimiter">(</span>Current_scenario &amp;&amp; !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span>
       <span class="Comment">// genuine test in a mu file</span>
-      raise &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">F - &quot;</span> &lt;&lt; Current_scenario<span class="Delimiter">-&gt;</span>name &lt;&lt; <span class="Constant">&quot;: &quot;</span> &lt;&lt; maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> &lt;&lt; <span class="Constant">&quot;expected &quot;</span> &lt;&lt; expected_count &lt;&lt; <span class="Constant">&quot; lines in trace with label &quot;</span> &lt;&lt; label &lt;&lt; <span class="Constant">&quot; in trace: &quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+      raise &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">F - &quot;</span> &lt;&lt; Current_scenario<span class="Delimiter">-&gt;</span>name &lt;&lt; <span class="Constant">&quot;: &quot;</span> &lt;&lt; maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> &lt;&lt; <span class="Constant">&quot;expected &quot;</span> &lt;&lt; expected_count &lt;&lt; <span class="Constant">&quot; lines in trace with label '&quot;</span> &lt;&lt; label &lt;&lt; <span class="Constant">&quot;' in trace: &quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
       DUMP<span class="Delimiter">(</span>label<span class="Delimiter">);</span>
     <span class="Delimiter">}</span>
     <span class="Normal">else</span> <span class="Delimiter">{</span>
       <span class="Comment">// just testing scenario support</span>
-      raise &lt;&lt; maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> &lt;&lt; <span class="Constant">&quot;expected &quot;</span> &lt;&lt; expected_count &lt;&lt; <span class="Constant">&quot; lines in trace with label &quot;</span> &lt;&lt; label &lt;&lt; <span class="Constant">&quot; in trace</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>current_recipe_name<span class="Delimiter">())</span> &lt;&lt; <span class="Constant">&quot;expected &quot;</span> &lt;&lt; expected_count &lt;&lt; <span class="Constant">&quot; lines in trace with label '&quot;</span> &lt;&lt; label &lt;&lt; <span class="Constant">&quot;' in trace</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Delimiter">}</span>
     <span class="Normal">if</span> <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span>
       Passed = <span class="Constant">false</span><span class="Delimiter">;</span>
@@ -750,7 +758,7 @@ def main [
   ]
   check-trace-count-<span class="Normal">for</span>-label <span class="Constant">2</span><span class="Delimiter">,</span> [a]
 ]
-<span class="traceContains">+error: main: expected 2 lines in trace with label a in trace</span>
+<span class="traceContains">+error: main: expected 2 lines in trace with label 'a' in trace</span>
 
 <span class="Comment">//: Minor detail: ignore 'system' calls in scenarios, since anything we do</span>
 <span class="Comment">//: with them is by definition impossible to test through mu.</span>
diff --git a/html/052tangle.cc.html b/html/052tangle.cc.html
index 3deeb260..03a0fd92 100644
--- a/html/052tangle.cc.html
+++ b/html/052tangle.cc.html
@@ -47,7 +47,6 @@ def main [
   &lt;label1&gt;
   <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
 ]
-
 before &lt;label1&gt; [
   <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
 ]
diff --git a/html/054static_dispatch.cc.html b/html/054static_dispatch.cc.html
index 7e922bef..e90b81f7 100644
--- a/html/054static_dispatch.cc.html
+++ b/html/054static_dispatch.cc.html
@@ -457,7 +457,6 @@ def main [
   <span class="Constant">5</span>:boolean<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/<span class="Constant">false</span>
   <span class="Constant">6</span>:boolean<span class="Special"> &lt;- </span>equal <span class="Constant">4</span>:boolean<span class="Delimiter">,</span> <span class="Constant">5</span>:boolean
 ]
-
 <span class="Comment"># temporarily hardcode number equality to always fail</span>
 def equal x:number<span class="Delimiter">,</span> y:number <span class="Delimiter">-&gt;</span> z:boolean [
   local-scope
diff --git a/html/055shape_shifting_container.cc.html b/html/055shape_shifting_container.cc.html
index abce7ede..fd9e9029 100644
--- a/html/055shape_shifting_container.cc.html
+++ b/html/055shape_shifting_container.cc.html
@@ -107,6 +107,13 @@ container foo:_b [
 ]
 <span class="traceContains">+error: headers of container 'foo' must use identical type ingredients</span>
 
+<span class="Delimiter">:(scenario type_ingredient_must_start_with_underscore)</span>
+<span class="Special">% Hide_errors = true;</span>
+container foo:t [
+  <span class="Normal">x</span>:number
+]
+<span class="traceContains">+error: foo: type ingredient 't' must begin with an underscore</span>
+
 <span class="Delimiter">:(before &quot;End Globals&quot;)</span>
 <span class="Comment">// We'll use large type ordinals to mean &quot;the following type of the variable&quot;.</span>
 <span class="Comment">// For example, if we have a generic type called foo:_elem, the type</span>
@@ -141,7 +148,7 @@ map&lt;string<span class="Delimiter">,</span> type_ordinal&gt; type_ingredient_n
   istringstream in<span class="Delimiter">(</span>save_name<span class="Delimiter">);</span>
   name = slurp_until<span class="Delimiter">(</span>in<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">);</span>
   map&lt;string<span class="Delimiter">,</span> type_ordinal&gt; type_ingredient_names<span class="Delimiter">;</span>
-  <span class="Normal">if</span> <span class="Delimiter">(</span>!slurp_type_ingredients<span class="Delimiter">(</span>in<span class="Delimiter">,</span> type_ingredient_names<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>!slurp_type_ingredients<span class="Delimiter">(</span>in<span class="Delimiter">,</span> type_ingredient_names<span class="Delimiter">,</span> name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">)</span>
@@ -162,12 +169,20 @@ map&lt;string<span class="Delimiter">,</span> type_ordinal&gt; type_ingredient_n
   <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
-<span class="Normal">bool</span> slurp_type_ingredients<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">,</span> map&lt;string<span class="Delimiter">,</span> type_ordinal&gt;&amp; out<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="Normal">bool</span> slurp_type_ingredients<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">,</span> map&lt;string<span class="Delimiter">,</span> type_ordinal&gt;&amp; out<span class="Delimiter">,</span> <span class="Normal">const</span> string&amp; container_name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   <span class="Normal">int</span> next_type_ordinal = START_TYPE_INGREDIENTS<span class="Delimiter">;</span>
   <span class="Normal">while</span> <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     string curr = slurp_until<span class="Delimiter">(</span>in<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">);</span>
+    <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+      raise &lt;&lt; container_name &lt;&lt; <span class="Constant">&quot;: empty type ingredients not permitted</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+      <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+    <span class="Delimiter">}</span>
+    <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> != <span class="Constant">'_'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      raise &lt;&lt; container_name &lt;&lt; <span class="Constant">&quot;: type ingredient '&quot;</span> &lt;&lt; curr &lt;&lt; <span class="Constant">&quot;' must begin with an underscore</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+      <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+    <span class="Delimiter">}</span>
     <span class="Normal">if</span> <span class="Delimiter">(</span>out<span class="Delimiter">.</span>find<span class="Delimiter">(</span>curr<span class="Delimiter">)</span> != out<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
-      raise &lt;&lt; <span class="Constant">&quot;can't repeat type ingredient names in a single container definition: '&quot;</span> &lt;&lt; curr &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; container_name &lt;&lt; <span class="Constant">&quot;: can't repeat type ingredient name'&quot;</span> &lt;&lt; curr &lt;&lt; <span class="Constant">&quot;' in a single container definition</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
       <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
     put<span class="Delimiter">(</span>out<span class="Delimiter">,</span> curr<span class="Delimiter">,</span> next_type_ordinal++<span class="Delimiter">);</span>
diff --git a/html/056shape_shifting_recipe.cc.html b/html/056shape_shifting_recipe.cc.html
index be795d37..240ffa5b 100644
--- a/html/056shape_shifting_recipe.cc.html
+++ b/html/056shape_shifting_recipe.cc.html
@@ -641,6 +641,7 @@ def foo x:c:_bar:_baz [
   local-scope
   load-ingredients
 ]
+<span class="Comment"># no errors</span>
 
 <span class="Delimiter">:(scenario shape_shifting_recipe_type_deduction_ignores_offsets)</span>
 def main [
@@ -1139,7 +1140,6 @@ $error: <span class="Constant">0</span>
 def add a:address:foo:_elem [
   assert <span class="Constant">0</span><span class="Delimiter">,</span> [should <span class="Normal">not</span> get here]
 ]
-
 def main [
   <span class="Comment"># call primitive add with literal 0</span>
   add <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">0</span>
diff --git a/html/060rewrite_literal_string.cc.html b/html/060rewrite_literal_string.cc.html
index 6596dd01..275a8fc3 100644
--- a/html/060rewrite_literal_string.cc.html
+++ b/html/060rewrite_literal_string.cc.html
@@ -53,6 +53,7 @@ set&lt;string&gt; recipes_taking_literal_strings<span class="Delimiter">;</span>
 <span class="Delimiter">:(code)</span>
 <span class="Normal">void</span> initialize_transform_rewrite_literal_string_to_text<span class="Delimiter">()</span> <span class="Delimiter">{</span>
   recipes_taking_literal_strings<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">&quot;$print&quot;</span><span class="Delimiter">);</span>
+  recipes_taking_literal_strings<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">&quot;$dump-trace&quot;</span><span class="Delimiter">);</span>
   recipes_taking_literal_strings<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">&quot;$system&quot;</span><span class="Delimiter">);</span>
   recipes_taking_literal_strings<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">&quot;trace&quot;</span><span class="Delimiter">);</span>
   recipes_taking_literal_strings<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">&quot;stash&quot;</span><span class="Delimiter">);</span>
diff --git a/html/071scheduler.cc.html b/html/071scheduler.cc.html
index 4f556a1e..18fc91b8 100644
--- a/html/071scheduler.cc.html
+++ b/html/071scheduler.cc.html
@@ -568,6 +568,43 @@ 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="Delimiter">:(before &quot;End routine Fields&quot;)</span>
+<span class="Normal">int</span> ninstrs<span class="Delimiter">;</span>
+<span class="Delimiter">:(before &quot;End routine Constructor&quot;)</span>
+ninstrs = <span class="Constant">0</span><span class="Delimiter">;</span>
+<span class="Delimiter">:(after &quot;stop_running_current_routine:&quot;)</span>
+Current_routine<span class="Delimiter">-&gt;</span>ninstrs = Current_routine<span class="Delimiter">-&gt;</span>ninstrs + ninstrs<span class="Delimiter">;</span>
+<span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
+NUMBER_OF_INSTRUCTIONS<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;number-of-instructions&quot;</span><span class="Delimiter">,</span> NUMBER_OF_INSTRUCTIONS<span class="Delimiter">);</span>
+<span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span>
+<span class="Normal">case</span> NUMBER_OF_INSTRUCTIONS: <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;'number-of-instructions' requires exactly one ingredient, but got '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>inst<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="Normal">if</span> <span class="Delimiter">(</span>!is_mu_number<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 'number-of-instructions' should be a routine id generated by 'start-running', but got '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><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="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> NUMBER_OF_INSTRUCTIONS: <span class="Delimiter">{</span>
+  <span class="Normal">int</span> id = 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">int</span> result = -<span class="Constant">1</span><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>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    <span class="Normal">if</span> <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-&gt;</span>id == id<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      result = Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-&gt;</span>ninstrs<span class="Delimiter">;</span>
+      <span class="Identifier">break</span><span class="Delimiter">;</span>
+    <span class="Delimiter">}</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>result<span class="Delimiter">);</span>
+  <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
 <span class="SalientComment">//:: make sure that each routine gets a different alloc to start</span>
 
 <span class="Delimiter">:(scenario new_concurrent)</span>
@@ -587,6 +624,27 @@ def f2 [
   <span class="Constant">4</span>:number/<span class="Special">raw &lt;- </span>copy <span class="Constant">1</span>
 ]
 <span class="traceContains">+mem: storing 0 in location 3</span>
+
+<span class="Delimiter">:(scenario number_of_instructions)</span>
+<span class="Special">% Scheduling_interval = 1;</span>
+def f1 [
+  <span class="Constant">10</span>:number/child-id<span class="Special"> &lt;- </span>start-running f2
+  <span class="Delimiter">{</span>
+    loop-unless <span class="Constant">20</span>:number
+  <span class="Delimiter">}</span>
+  <span class="Constant">11</span>:number<span class="Special"> &lt;- </span>number-of-instructions <span class="Constant">10</span>:number
+]
+def f2 [
+  <span class="Comment"># 4 instructions worth of work</span>
+  <span class="Comment"># Should take 2 scheduling intervals</span>
+  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
+  <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>
+  <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">3</span>
+  <span class="Constant">20</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>
+]
+<span class="Comment"># f2 runs an extra instruction for the implicit return added by the</span>
+<span class="Comment"># fill_in_reply_ingredients transform</span>
+<span class="traceContains">+mem: storing 5 in location 11</span>
 </pre>
 </body>
 </html>
diff --git a/html/082scenario_screen.cc.html b/html/082scenario_screen.cc.html
index 090a0daa..54980d17 100644
--- a/html/082scenario_screen.cc.html
+++ b/html/082scenario_screen.cc.html
@@ -54,6 +54,7 @@ scenario screen-in-scenario [
     <span class="Delimiter">.</span>     <span class="Delimiter">.</span>
   ]
 ]
+<span class="Comment"># checks are inside scenario</span>
 
 <span class="Delimiter">:(scenario screen_in_scenario_unicode)</span>
 scenario screen-in-scenario-unicode-color [
@@ -71,6 +72,7 @@ scenario screen-in-scenario-unicode-color [
     <span class="Delimiter">.</span>     <span class="Delimiter">.</span>
   ]
 ]
+<span class="Comment"># checks are inside scenario</span>
 
 <span class="Delimiter">:(scenario screen_in_scenario_color)</span>
 <span class="Comment"># screen-should-contain can check unicode characters in the fake screen</span>
@@ -105,6 +107,7 @@ scenario screen-in-scenario-color [
     <span class="Delimiter">.</span>     <span class="Delimiter">.</span>
   ]
 ]
+<span class="Comment"># checks are inside scenario</span>
 
 <span class="Delimiter">:(scenario screen_in_scenario_error)</span>
 <span class="Special">% Scenario_testing_scenario = true;</span>
diff --git a/html/091run_interactive.cc.html b/html/091run_interactive.cc.html
index 6bd254b0..6633d65e 100644
--- a/html/091run_interactive.cc.html
+++ b/html/091run_interactive.cc.html
@@ -200,10 +200,12 @@ load<span class="Delimiter">(</span>string<span class="Delimiter">(</span>
 <span class="Constant">&quot;recipe sandbox [</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
   <span class="Constant">&quot;local-scope</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
   <span class="Constant">&quot;screen:address:screen &lt;- new-fake-screen 30, 5</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
-  <span class="Constant">&quot;r:number/routine_id &lt;- start-running interactive, screen</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
-  <span class="Constant">&quot;limit-time r, 100000/instructions</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
-  <span class="Constant">&quot;wait-for-routine r</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
-  <span class="Constant">&quot;sandbox-state:number &lt;- routine-state r/routine_id</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
+  <span class="Constant">&quot;routine-id:number &lt;- start-running interactive, screen</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
+  <span class="Constant">&quot;limit-time routine-id, 100000/instructions</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
+  <span class="Constant">&quot;wait-for-routine routine-id</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
+  <span class="Constant">&quot;instructions-run:number &lt;- number-of-instructions routine-id</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
+  <span class="Constant">&quot;stash instructions-run [instructions run]</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
+  <span class="Constant">&quot;sandbox-state:number &lt;- routine-state routine-id</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
   <span class="Constant">&quot;completed?:boolean &lt;- equal sandbox-state, 1/completed</span><span class="cSpecial">\n</span><span class="Constant">&quot;</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> +
diff --git a/html/edit/010-sandbox-trace.mu.html b/html/edit/010-sandbox-trace.mu.html
index b791d18b..608bd63c 100644
--- a/html/edit/010-sandbox-trace.mu.html
+++ b/html/edit/010-sandbox-trace.mu.html
@@ -76,6 +76,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
    <span class="Constant"> .  stash [abc]                                     ┊0   edit          copy            delete         .</span>
    <span class="Constant"> .]                                                 ┊foo                                              .</span>
    <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊abc                                              .</span>
+   <span class="Constant"> .                                                  ┊8 instructions run                               .</span>
    <span class="Constant"> .                                                  ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
    <span class="Constant"> .                                                  ┊                                                 .</span>
   ]
@@ -86,6 +87,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
    <span class="Constant"> .                                                  ┊                                                 .</span>
    <span class="Constant"> .                                                  ┊                                                 .</span>
    <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊abc                                              .</span>
+   <span class="Constant"> .                                                  ┊8 instructions run                               .</span>
    <span class="Constant"> .                                                  ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
    <span class="Constant"> .                                                  ┊                                                 .</span>
   ]
@@ -150,7 +152,8 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
    <span class="Constant"> .  stash [abc]                                     ┊0   edit          copy            delete         .</span>
    <span class="Constant"> .  reply 4                                         ┊foo                                              .</span>
    <span class="Constant"> .]                                                 ┊abc                                              .</span>
-   <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4                                                .</span>
+   <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊8 instructions run                               .</span>
+   <span class="Constant"> .                                                  ┊4                                                .</span>
    <span class="Constant"> .                                                  ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
    <span class="Constant"> .                                                  ┊                                                 .</span>
   ]
@@ -175,6 +178,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
    <span class="Constant"> .                                                  ┊0   edit          copy            delete         .</span>
    <span class="Constant"> .                                                  ┊stash 123456789                                  .</span>
    <span class="Constant"> .                                                  ┊123456789                                        .</span>
+   <span class="Constant"> .                                                  ┊6 instructions run                               .</span>
    <span class="Constant"> .                                                  ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
    <span class="Constant"> .                                                  ┊                                                 .</span>
   ]
@@ -193,6 +197,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
    <span class="Constant"> .                                                  ┊0   edit          copy            delete         .</span>
    <span class="Constant"> .                                                  ┊stash 123456789                                  .</span>
    <span class="Constant"> .                                                  ┊123456789                                        .</span>
+   <span class="Constant"> .                                                  ┊6 instructions run                               .</span>
    <span class="Constant"> .                                                  ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
    <span class="Constant"> .                                                  ┊                                                 .</span>
   ]
diff --git a/html/edit/011-errors.mu.html b/html/edit/011-errors.mu.html
index 6bf5c452..521006e4 100644
--- a/html/edit/011-errors.mu.html
+++ b/html/edit/011-errors.mu.html
@@ -719,9 +719,10 @@ _, c:number<span class="Special"> &lt;- </span>divide-with-remainder a, b
    <span class="Constant"> .a:number &lt;- next-ingredient                       ┊0   edit          copy            delete         .</span>
    <span class="Constant"> .b:number &lt;- next-ingredient                       ┊foo 4, 0                                         .</span>
    <span class="Constant"> .stash [dividing by], b                            ┊dividing by 0                                    .</span>
-   <span class="Constant"> ._, c:number &lt;- divide-with-remainder a, b         ┊foo: divide by zero in '_, c:number &lt;- divide-wi↩.</span>
-   <span class="Constant"> .reply b                                           ┊th-remainder a, b'                               .</span>
-   <span class="Constant"> .]                                                 ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
+   <span class="Constant"> ._, c:number &lt;- divide-with-remainder a, b         ┊14 instructions run                              .</span>
+   <span class="Constant"> .reply b                                           ┊foo: divide by zero in '_, c:number &lt;- divide-wi↩.</span>
+   <span class="Constant"> .]                                                 ┊th-remainder a, b'                               .</span>
+<span class="Constant">    .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
   ]
 ]
 </pre>