about summary refs log blame commit diff stats
path: root/html/052tangle.cc.html
blob: 14832b2aad470b6e223828507e1de05751f40c36 (plain) (tree)
1
2
3
4
5
6
7
8
9
10



                                                                                          
                                

                                                
                                  

                                                                                         

                       
                                                                                                 
                                                                                            

                                      
                                
                             
                                  
                            



                                                                           

        





                               

       
                         




                                                                                                            
                                
                                                                                              

                                                        
          
                                                                                                                
                
                                                                                                                

 
                       
                                                                                                                










                                                                                                                                                                                                                                                          
                                                                                                                                                                 


                                                                                       
                                                                                     

                                                                         
                                                                                                                                                                                                                            
                                                                                             

                                                                                                                   
                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      

                                                                                                                                                                                                 
                                                            
                                
                                                                                                                                                                                                                           
                                                                                             

                                                                                                                   
                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      

                                                                                                                                                                                                
                                                           

                                
                                                                                                      
 
                                                                                                   
                                                                                                                                                                                   
 
                                                                                                     


                                                                                                           
                                                                                                                


                                                                                 
                                      

                                                                                                                                                                                                    
                                                                                                        
                                                                                                                                                  


                                                                                               
                                                                                                                                                                                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                                                                                                               





                                                                                                                                                                    
                                                          
                                                                                                                                                                                                                                                                                                                                

                                                                                                  
                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                           
                                                                                                                          
                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                          
                                    
                                                                                                                                                                                                                                
                                          


                                  
                                                                                                                                                                                                                                                                                                                                                                           






                                                                                                          
                                                                                                                                                                                                                                                                                                                            

                                                                                                                                                                                                                                                   

                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                            
                                                                                                                                

                                                                                                                                                                                                                                        



                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                          

                                                                                                                                                                                                                                                                                                                                                                                





                                                                                                                            
                                                                                                                                                         


                                                                                                                                                                                                                                                                                                                              
                                                                   






                                                                                                       
                                      
                                                                                                                         

                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                   
                                  

                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                  
                                  


                                                                  
          
                                                                                                                
                
                                                                                                                
 
                       
                                                                                                                
 
                      
                                                                                                                








                                                                
                                                                     
                                                  
          
                                                                                                                
         
                                                                                                                

                
                                                                                                                
 
                                                                            

                                                                       
          








                                                                                                                
                                                                                                                
 
                       
                                                                                                                
 
                      
                                                                                                                













                                                                                                                      
          
                                                                                                                
                
                                                                                                                
 
                       
                                                                                                                
 
                      
                                                                                                                
 
                       
                                                                                                                
 
                      
                                                                                                                













                                                                                               
          
                                                                                                                
                
                                                                                                                
 
                       

                                                                                                                
 
                      

                                                                                                                











                                                                                        
          
                                                                                                                 
                


                                                                                                                 
             
                                                                                                                 
                
                                                                                                                 
 
                       
                                                                                                                 
 
                      
                                                                                                                 
 

                                                                 
                                     




                                                                 
                                     





                                                                                          
          
                                                                                                                 

                

                                                                                                                 
                       

                                                                                                                 
                      













                                                                                                                 
          
                                                                                                                 

                

                                                                                                                 
                       

                                                                                                                 
                      

                                                                                                                 

                   





                                                                 
                                         

                                                                 

                                           

                                                                                     
          



















                                                                                                                 
          




















                                                                                                                 
          

















                                                                                                                 




























                                                                                                                                                                                                                                                                                                                                                             


       
                                     
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - 052tangle.cc</title>
<meta name="Generator" content="Vim/7.4">
<meta name="plugin-version" content="vim7.4_v2">
<meta name="syntax" content="cpp">
<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
<meta name="colorscheme" content="minimal">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 12pt; font-size: 1em; }
.Constant { color: #00a0a0; }
.traceAbsent { color: #c00000; }
.cSpecial { color: #008000; }
.traceContains { color: #008000; }
.Comment { color: #9090ff; }
.Delimiter { color: #800080; }
.Special { color: #c00000; }
.Identifier { color: #fcb165; }
.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; }
-->
</style>

<script type='text/javascript'>
<!--

-->
</script>
</head>
<body>
<pre id='vimCodeElement'>
<span class="Comment">//: Allow code for recipes to be pulled in from multiple places and inserted</span>
<span class="Comment">//: at special labels called 'waypoints'. Unlike jump targets, a recipe can</span>
<span class="Comment">//: have multiple ambiguous waypoints with the same name. Any 'before' and</span>
<span class="Comment">//: 'after' fragments will simply be inserted at all applicable waypoints.</span>
<span class="Comment">//: Waypoints are always surrounded by '&lt;&gt;', e.g. &lt;handle-request&gt;.</span>
<span class="Comment">//:</span>
<span class="Comment">//: todo: switch recipe.steps to a more efficient data structure.</span>

<span class="Delimiter">:(scenario tangle_before)</span>
def main [
  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
  &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>
]
<span class="traceContains">+mem: storing 0 in location 1</span>
<span class="traceContains">+mem: storing 0 in location 2</span>
<span class="traceContains">+mem: storing 0 in location 3</span>
<span class="Comment"># nothing else</span>
$mem: <span class="Constant">3</span>

<span class="Comment">//: while loading recipes, load before/after fragments</span>

<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
map&lt;string <span class="Comment">/*</span><span class="Comment">label</span><span class="Comment">*/</span><span class="Delimiter">,</span> recipe&gt; Before_fragments<span class="Delimiter">,</span> After_fragments<span class="Delimiter">;</span>
set&lt;string <span class="Comment">/*</span><span class="Comment">label</span><span class="Comment">*/</span>&gt; Fragments_used<span class="Delimiter">;</span>
<span class="Delimiter">:(before &quot;End Setup&quot;)</span>
Before_fragments<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
After_fragments<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
Fragments_used<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>

<span class="Delimiter">:(before &quot;End Command Handlers&quot;)</span>
<span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>command == <span class="Constant">&quot;before&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
  string label = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
  recipe tmp<span class="Delimiter">;</span>
  slurp_body<span class="Delimiter">(</span>in<span class="Delimiter">,</span> tmp<span class="Delimiter">);</span>
  <span class="Normal">if</span> <span class="Delimiter">(</span>is_waypoint<span class="Delimiter">(</span>label<span class="Delimiter">))</span>
    Before_fragments[label]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>Before_fragments[label]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> tmp<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> tmp<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>end<span class="Delimiter">());</span>
  <span class="Normal">else</span>
    raise &lt;&lt; <span class="Constant">&quot;can't tangle before label &quot;</span> &lt;&lt; label &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
  <span class="Comment">// End before Command Handler</span>
<span class="Delimiter">}</span>
<span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>command == <span class="Constant">&quot;after&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
  string label = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
  recipe tmp<span class="Delimiter">;</span>
  slurp_body<span class="Delimiter">(</span>in<span class="Delimiter">,</span> tmp<span class="Delimiter">);</span>
  <span class="Normal">if</span> <span class="Delimiter">(</span>is_waypoint<span class="Delimiter">(</span>label<span class="Delimiter">))</span>
    After_fragments[label]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>After_fragments[label]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> tmp<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> tmp<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>end<span class="Delimiter">());</span>
  <span class="Normal">else</span>
    raise &lt;&lt; <span class="Constant">&quot;can't tangle after label &quot;</span> &lt;&lt; label &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
  <span class="Comment">// End after Command Handler</span>
<span class="Delimiter">}</span>

<span class="Comment">//: after all recipes are loaded, insert fragments at appropriate labels.</span>

<span class="Delimiter">:(after &quot;Begin Instruction Inserting/Deleting Transforms&quot;)</span>
Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>insert_fragments<span class="Delimiter">);</span>  <span class="Comment">// NOT idempotent</span>

<span class="Comment">//: We might need to perform multiple passes, in case inserted fragments</span>
<span class="Comment">//: include more labels that need further insertions. Track which labels we've</span>
<span class="Comment">//: already processed using an extra field.</span>
<span class="Delimiter">:(before &quot;End instruction Fields&quot;)</span>
<span class="Normal">mutable</span> <span class="Normal">bool</span> tangle_done<span class="Delimiter">;</span>
<span class="Delimiter">:(before &quot;End instruction Constructor&quot;)</span>
tangle_done = <span class="Constant">false</span><span class="Delimiter">;</span>

<span class="Delimiter">:(code)</span>
<span class="Normal">void</span> insert_fragments<span class="Delimiter">(</span><span class="Normal">const</span> recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Normal">bool</span> made_progress = <span class="Constant">true</span><span class="Delimiter">;</span>
  <span class="Normal">int</span> pass = <span class="Constant">0</span><span class="Delimiter">;</span>
  <span class="Normal">while</span> <span class="Delimiter">(</span>made_progress<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    made_progress = <span class="Constant">false</span><span class="Delimiter">;</span>
    <span class="Comment">// create a new vector because insertions invalidate iterators</span>
    vector&lt;instruction&gt; result<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>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
      <span class="Normal">const</span> instruction&amp; inst = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
      <span class="Normal">if</span> <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>is_label || !is_waypoint<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label<span class="Delimiter">)</span> || inst<span class="Delimiter">.</span>tangle_done<span class="Delimiter">)</span> <span class="Delimiter">{</span>
        result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>inst<span class="Delimiter">);</span>
        <span class="Identifier">continue</span><span class="Delimiter">;</span>
      <span class="Delimiter">}</span>
      inst<span class="Delimiter">.</span>tangle_done = <span class="Constant">true</span><span class="Delimiter">;</span>
      made_progress = <span class="Constant">true</span><span class="Delimiter">;</span>
      Fragments_used<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label<span class="Delimiter">);</span>
      ostringstream prefix<span class="Delimiter">;</span>
      prefix &lt;&lt; <span class="Constant">'+'</span> &lt;&lt; get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">'_'</span> &lt;&lt; pass &lt;&lt; <span class="Constant">'_'</span> &lt;&lt; i<span class="Delimiter">;</span>
      <span class="Comment">// ok to use contains_key even though Before_fragments uses [],</span>
      <span class="Comment">// because appending an empty recipe is a noop</span>
      <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Before_fragments<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>label<span class="Delimiter">))</span>
        append_fragment<span class="Delimiter">(</span>result<span class="Delimiter">,</span> Before_fragments[inst<span class="Delimiter">.</span>label]<span class="Delimiter">.</span>steps<span class="Delimiter">,</span> prefix<span class="Delimiter">.</span>str<span class="Delimiter">());</span>
      result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>inst<span class="Delimiter">);</span>
      <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>After_fragments<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>label<span class="Delimiter">))</span>
        append_fragment<span class="Delimiter">(</span>result<span class="Delimiter">,</span> After_fragments[inst<span class="Delimiter">.</span>label]<span class="Delimiter">.</span>steps<span class="Delimiter">,</span> prefix<span class="Delimiter">.</span>str<span class="Delimiter">());</span>
    <span class="Delimiter">}</span>
    get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>swap<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
    ++pass<span class="Delimiter">;</span>
  <span class="Delimiter">}</span>
<span class="Delimiter">}</span>

<span class="Normal">void</span> append_fragment<span class="Delimiter">(</span>vector&lt;instruction&gt;&amp; base<span class="Delimiter">,</span> <span class="Normal">const</span> vector&lt;instruction&gt;&amp; patch<span class="Delimiter">,</span> <span class="Normal">const</span> string prefix<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Comment">// append 'patch' to 'base' while keeping 'base' oblivious to any new jump</span>
  <span class="Comment">// targets in 'patch' oblivious to 'base' by prepending 'prefix' to them.</span>
  <span class="Comment">// we might tangle the same fragment at multiple points in a single recipe,</span>
  <span class="Comment">// and we need to avoid duplicate jump targets.</span>
  <span class="Comment">// so we'll keep jump targets local to the specific before/after fragment</span>
  <span class="Comment">// that introduces them.</span>
  set&lt;string&gt; jump_targets<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>patch<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    <span class="Normal">const</span> instruction&amp; inst = patch<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>is_label &amp;&amp; is_jump_target<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label<span class="Delimiter">))</span>
      jump_targets<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label<span class="Delimiter">);</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>patch<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    instruction inst = patch<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>is_label<span class="Delimiter">)</span> <span class="Delimiter">{</span>
      <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>jump_targets<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>label<span class="Delimiter">))</span>
        inst<span class="Delimiter">.</span>label = prefix+inst<span class="Delimiter">.</span>label<span class="Delimiter">;</span>
      base<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>inst<span class="Delimiter">);</span>
      <span class="Identifier">continue</span><span class="Delimiter">;</span>
    <span class="Delimiter">}</span>
    <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> j = <span class="Constant">0</span><span class="Delimiter">;</span> j &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span>
      reagent&amp; x = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">);</span>
      <span class="Normal">if</span> <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
      <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>name == <span class="Constant">&quot;label&quot;</span> &amp;&amp; contains_key<span class="Delimiter">(</span>jump_targets<span class="Delimiter">,</span> x<span class="Delimiter">.</span>name<span class="Delimiter">))</span>
        x<span class="Delimiter">.</span>name = prefix+x<span class="Delimiter">.</span>name<span class="Delimiter">;</span>
    <span class="Delimiter">}</span>
    base<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>inst<span class="Delimiter">);</span>
  <span class="Delimiter">}</span>
<span class="Delimiter">}</span>

<span class="Normal">bool</span> is_waypoint<span class="Delimiter">(</span>string label<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Identifier">return</span> *label<span class="Delimiter">.</span>begin<span class="Delimiter">()</span> == <span class="Constant">'&lt;'</span> &amp;&amp; *label<span class="Delimiter">.</span>rbegin<span class="Delimiter">()</span> == <span class="Constant">'&gt;'</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>

<span class="Comment">//: complain about unapplied fragments</span>
<span class="Comment">//: This can't run during transform because later (shape-shifting recipes)</span>
<span class="Comment">//: we'll encounter situations where fragments might get used long after</span>
<span class="Comment">//: they're loaded, and we might run transform_all in between. To avoid</span>
<span class="Comment">//: spurious errors, run this check right at the end, after all code is</span>
<span class="Comment">//: loaded, right before we run main.</span>
<span class="Delimiter">:(before &quot;End Commandline Parsing&quot;)</span>
check_insert_fragments<span class="Delimiter">();</span>
<span class="Delimiter">:(code)</span>
<span class="Normal">void</span> check_insert_fragments<span class="Delimiter">()</span> <span class="Delimiter">{</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span>map&lt;string<span class="Delimiter">,</span> recipe&gt;::iterator p = Before_fragments<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Before_fragments<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Fragments_used<span class="Delimiter">,</span> p<span class="Delimiter">-&gt;</span>first<span class="Delimiter">))</span>
      raise &lt;&lt; <span class="Constant">&quot;could not locate insert before label &quot;</span> &lt;&lt; p<span class="Delimiter">-&gt;</span>first &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
  <span class="Delimiter">}</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span>map&lt;string<span class="Delimiter">,</span> recipe&gt;::iterator p = After_fragments<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != After_fragments<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Fragments_used<span class="Delimiter">,</span> p<span class="Delimiter">-&gt;</span>first<span class="Delimiter">))</span>
      raise &lt;&lt; <span class="Constant">&quot;could not locate insert after label &quot;</span> &lt;&lt; p<span class="Delimiter">-&gt;</span>first &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
  <span class="Delimiter">}</span>
<span class="Delimiter">}</span>

<span class="Delimiter">:(scenario tangle_before_and_after)</span>
def main [
  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
  &lt;label1&gt;
  <span class="Constant">4</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>
]
after &lt;label1&gt; [
  <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
]
<span class="traceContains">+mem: storing 0 in location 1</span>
<span class="traceContains">+mem: storing 0 in location 2</span>
<span class="Comment"># label1</span>
<span class="traceContains">+mem: storing 0 in location 3</span>
<span class="traceContains">+mem: storing 0 in location 4</span>
<span class="Comment"># nothing else</span>
$mem: <span class="Constant">4</span>

<span class="Delimiter">:(scenario tangle_ignores_jump_target)</span>
<span class="Special">% Hide_errors = true;</span>
def main [
  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
  +label1
  <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
]
before +label1 [
  <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
]
<span class="traceContains">+error: can't tangle before label +label1</span>

<span class="Delimiter">:(scenario tangle_keeps_labels_separate)</span>
def main [
  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
  &lt;label1&gt;
  &lt;label2&gt;
  <span class="Constant">6</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>
]
after &lt;label1&gt; [
  <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
]
before &lt;label2&gt; [
  <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
]
after &lt;label2&gt; [
  <span class="Constant">5</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
]
<span class="traceContains">+mem: storing 0 in location 1</span>
<span class="traceContains">+mem: storing 0 in location 2</span>
<span class="Comment"># label1</span>
<span class="traceContains">+mem: storing 0 in location 3</span>
<span class="Comment"># 'after' fragments for earlier label always go before 'before' fragments for later label</span>
<span class="traceContains">+mem: storing 0 in location 4</span>
<span class="Comment"># label2</span>
<span class="traceContains">+mem: storing 0 in location 5</span>
<span class="traceContains">+mem: storing 0 in location 6</span>
<span class="Comment"># nothing else</span>
$mem: <span class="Constant">6</span>

<span class="Delimiter">:(scenario tangle_stacks_multiple_fragments)</span>
def main [
  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
  &lt;label1&gt;
  <span class="Constant">6</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>
]
after &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">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
]
after &lt;label1&gt; [
  <span class="Constant">5</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
]
<span class="traceContains">+mem: storing 0 in location 1</span>
<span class="Comment"># 'before' fragments stack in order</span>
<span class="traceContains">+mem: storing 0 in location 2</span>
<span class="traceContains">+mem: storing 0 in location 4</span>
<span class="Comment"># label1</span>
<span class="Comment"># 'after' fragments stack in reverse order</span>
<span class="traceContains">+mem: storing 0 in location 5</span>
<span class="traceContains">+mem: storing 0 in location 3</span>
<span class="traceContains">+mem: storing 0 in location 6</span>
<span class="Comment"># nothing else</span>
$mem: <span class="Constant">6</span>

<span class="Delimiter">:(scenario tangle_supports_fragments_with_multiple_instructions)</span>
def main [
  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
  &lt;label1&gt;
  <span class="Constant">6</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>
  <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
]
after &lt;label1&gt; [
  <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
  <span class="Constant">5</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
]
<span class="traceContains">+mem: storing 0 in location 1</span>
<span class="traceContains">+mem: storing 0 in location 2</span>
<span class="traceContains">+mem: storing 0 in location 3</span>
<span class="Comment"># label1</span>
<span class="traceContains">+mem: storing 0 in location 4</span>
<span class="traceContains">+mem: storing 0 in location 5</span>
<span class="traceContains">+mem: storing 0 in location 6</span>
<span class="Comment"># nothing else</span>
$mem: <span class="Constant">6</span>

<span class="Delimiter">:(scenario tangle_tangles_into_all_labels_with_same_name)</span>
def main [
  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>
  &lt;label1&gt;
  <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>
  recipe2
]
def recipe2 [
  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">11</span>
  &lt;label1&gt;
  <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">11</span>
]
before &lt;label1&gt; [
  <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">12</span>
]
after &lt;label1&gt; [
  <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">12</span>
]
<span class="traceContains">+mem: storing 10 in location 1</span>
<span class="traceContains">+mem: storing 12 in location 2</span>
<span class="Comment"># label1</span>
<span class="traceContains">+mem: storing 12 in location 3</span>
<span class="traceContains">+mem: storing 10 in location 4</span>
<span class="Comment"># recipe2</span>
<span class="traceContains">+mem: storing 11 in location 1</span>
<span class="traceContains">+mem: storing 12 in location 2</span>
<span class="Comment"># label1</span>
<span class="traceContains">+mem: storing 12 in location 3</span>
<span class="traceContains">+mem: storing 11 in location 4</span>
<span class="Comment"># nothing else</span>
$mem: <span class="Constant">8</span>

<span class="Delimiter">:(scenario tangle_tangles_into_all_labels_with_same_name_2)</span>
def main [
  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>
  &lt;label1&gt;
  &lt;label1&gt;
  <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>
]
before &lt;label1&gt; [
  <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">12</span>
]
after &lt;label1&gt; [
  <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">12</span>
]
<span class="traceContains">+mem: storing 10 in location 1</span>
<span class="traceContains">+mem: storing 12 in location 2</span>
<span class="Comment"># label1</span>
<span class="traceContains">+mem: storing 12 in location 3</span>
<span class="traceContains">+mem: storing 12 in location 2</span>
<span class="Comment"># label1</span>
<span class="traceContains">+mem: storing 12 in location 3</span>
<span class="traceContains">+mem: storing 10 in location 4</span>
<span class="Comment"># nothing else</span>
$mem: <span class="Constant">6</span>

<span class="Delimiter">:(scenario tangle_tangles_into_all_labels_with_same_name_3)</span>
def main [
  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>
  &lt;label1&gt;
  &lt;foo&gt;
  <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>
]
before &lt;label1&gt; [
  <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">12</span>
]
after &lt;label1&gt; [
  <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">12</span>
]
after &lt;foo&gt; [
  &lt;label1&gt;
]
<span class="traceContains">+mem: storing 10 in location 1</span>
<span class="traceContains">+mem: storing 12 in location 2</span>
<span class="Comment"># label1</span>
<span class="traceContains">+mem: storing 12 in location 3</span>
<span class="traceContains">+mem: storing 12 in location 2</span>
<span class="Comment"># foo/label1</span>
<span class="traceContains">+mem: storing 12 in location 3</span>
<span class="traceContains">+mem: storing 10 in location 4</span>
<span class="Comment"># nothing else</span>
$mem: <span class="Constant">6</span>

<span class="Delimiter">:(scenario tangle_handles_jump_target_inside_fragment)</span>
def main [
  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>
  &lt;label1&gt;
  <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>
]
before &lt;label1&gt; [
  jump +label2:label
  <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">12</span>
  +label2
  <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">12</span>
]
<span class="traceContains">+mem: storing 10 in location 1</span>
<span class="Comment"># label1</span>
<span class="traceContains">+mem: storing 12 in location 3</span>
<span class="traceContains">+mem: storing 10 in location 4</span>
<span class="Comment"># ignored by jump</span>
<span class="traceAbsent">-mem: storing 12 in label 2</span>
<span class="Comment"># nothing else</span>
$mem: <span class="Constant">3</span>

<span class="Delimiter">:(scenario tangle_renames_jump_target)</span>
def main [
  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>
  &lt;label1&gt;
  +label2
  <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>
]
before &lt;label1&gt; [
  jump +label2:label
  <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">12</span>
  +label2  <span class="Comment"># renamed</span>
  <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">12</span>
]
<span class="traceContains">+mem: storing 10 in location 1</span>
<span class="Comment"># label1</span>
<span class="traceContains">+mem: storing 12 in location 3</span>
<span class="traceContains">+mem: storing 10 in location 4</span>
<span class="Comment"># ignored by jump</span>
<span class="traceAbsent">-mem: storing 12 in label 2</span>
<span class="Comment"># nothing else</span>
$mem: <span class="Constant">3</span>

<span class="Delimiter">:(scenario tangle_jump_to_base_recipe)</span>
def main [
  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>
  &lt;label1&gt;
  +label2
  <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>
]
before &lt;label1&gt; [
  jump +label2:label
  <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">12</span>
  <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">12</span>
]
<span class="traceContains">+mem: storing 10 in location 1</span>
<span class="Comment"># label1</span>
<span class="traceContains">+mem: storing 10 in location 4</span>
<span class="Comment"># ignored by jump</span>
<span class="traceAbsent">-mem: storing 12 in label 2</span>
<span class="traceAbsent">-mem: storing 12 in location 3</span>
<span class="Comment"># nothing else</span>
$mem: <span class="Constant">2</span>

<span class="Comment">//: ensure that there are no new fragments created for a label after it's already been inserted to</span>

<span class="Delimiter">:(code)</span>
<span class="Normal">void</span> test_new_fragment_after_tangle<span class="Delimiter">()</span> <span class="Delimiter">{</span>
  <span class="Comment">// define a recipe</span>
  load<span class="Delimiter">(</span><span class="Constant">&quot;def foo [</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;  &lt;label&gt;</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       <span class="Constant">&quot;]</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       <span class="Constant">&quot;after &lt;label&gt; [</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       <span class="Constant">&quot;  1:number/raw &lt;- copy 34</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       <span class="Constant">&quot;]</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">);</span>
  transform_all<span class="Delimiter">();</span>
  CHECK_TRACE_DOESNT_CONTAIN_ERROR<span class="Delimiter">();</span>
  Hide_errors = <span class="Constant">true</span><span class="Delimiter">;</span>
  <span class="Comment">// try to tangle into recipe foo after transform</span>
  load<span class="Delimiter">(</span><span class="Constant">&quot;before &lt;label&gt; [</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       <span class="Constant">&quot;  2:number/raw &lt;- copy 35</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
       <span class="Constant">&quot;]</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">);</span>
  CHECK_TRACE_CONTAINS_ERROR<span class="Delimiter">();</span>
<span class="Delimiter">}</span>

<span class="Delimiter">:(before &quot;End before Command Handler&quot;)</span>
<span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Fragments_used<span class="Delimiter">,</span> label<span class="Delimiter">))</span>
  raise &lt;&lt; <span class="Constant">&quot;we've already tangled some code at label &quot;</span> &lt;&lt; label &lt;&lt; <span class="Constant">&quot; in a previous call to transform_all(). Those locations won't be updated.</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
<span class="Delimiter">:(before &quot;End after Command Handler&quot;)</span>
<span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Fragments_used<span class="Delimiter">,</span> label<span class="Delimiter">))</span>
  raise &lt;&lt; <span class="Constant">&quot;we've already tangled some code at label &quot;</span> &lt;&lt; label &lt;&lt; <span class="Constant">&quot; in a previous call to transform_all(). Those locations won't be updated.</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->