summary refs log tree commit diff stats
path: root/lib/pure/pegs.nim
Commit message (Expand)AuthorAgeFilesLines
* updated pegs moduleAraq2014-08-281-38/+38
* big renameAraq2014-08-271-140/+132
* distinguish between 'defined' and 'declared'Araq2014-08-111-1/+1
* Rewrote the changes to findAll using if/elseFabio Cevasco2014-02-221-3/+3
* pegs.findAll iterator fixFabio Cevasco2014-02-211-1/+3
* updated grammar.txtAraq2014-01-201-4/+4
* case consistency part 6Araq2013-12-281-64/+64
* made tests greenAraq2013-06-101-1/+1
* manyloc test should be green againAraq2013-06-041-1/+0
* pegs/re =~ warns about scope rule change; improved docsAraq2013-05-081-2/+2
* pegs compiles againAraq2013-05-021-1/+2
* bugfixes mostly JS relatedAraq2013-05-011-3/+5
* Removes executable bit for text files.Grzegorz Adam Hankiewicz2013-03-161-0/+0
* objects with no ancestor are not implicitely finalAraq2012-08-241-1/+1
* first steps to make templates hygienicAraq2012-08-201-1/+4
* openarray/varargs split; breaks bootstrappingAraq2012-08-161-4/+4
* Both the re and pegs module's `=~` templates can now be used simultaneously f...Dominik Picheta2012-07-211-1/+1
* fixes #113Araq2012-05-201-4/+4
* fixes #114Araq2012-05-201-2/+2
* Merge branch 'master' of github.com:Araq/NimrodAraq2012-04-151-1/+0
|\
| * minor changes to make the test suite green againZahary Karadjov2012-04-151-1/+0
* | @ is a sigil-like operatorAraq2012-04-151-7/+7
|/
* documentation improvements; higher level Mongodb wrapperAraq2012-04-091-2/+2
* year 2012 for most copyright headersAraq2012-01-021-1/+1
* tester checks exitcode; osproc additions; DLL fixes; taint mode fixesAraq2011-11-071-1/+1
* code generator supports constant sequences; more consistent compile time eval...Araq2011-10-071-5/+5
* pegs module: bugfixes for the anchor ^; pegs.replace now does what the docs sayAraq2011-06-161-24/+52
* readFile raises EIO instead of returning nil; added system.writeFileAraq2011-06-161-10/+2
* deprecated system.copy: use system.substr insteadAraq2011-05-141-8/+8
* p[] instead of p^Araq2011-04-111-7/+7
* some little bugfixesAraq2011-03-271-1/+1
* bugfixes; field discriminant checks; linearScanEnd, unroll, shallow pragmasAraq2011-03-231-5/+10
* distinction between re.replace and re.replacef; speed improvements for re moduleAraq2011-03-061-4/+20
* nimgrep: first working versionAraq2011-02-021-10/+45
* cleanup: E_Base should not be used for inheriting exceptions; documentation g...Araq2011-01-151-1/+2
* better tester; yet another iterator bugfixAraq2011-01-061-31/+46
* docgen understands and ignores *when false*Araq2010-11-181-31/+148
* pegs: captured search loopAraq2010-11-071-4/+49
* pegs: bugfixes and extensionsAraq2010-10-311-10/+39
* inlining of the write barrier for dllsAndreas Rumpf2010-08-081-34/+57
* version 0.8.8Andreas Rumpf2010-03-141-1/+1
* further enhancements for the GTK wrapperAndreas Rumpf2010-03-011-0/+20
* bugfixes: re; pegs moduleAndreas Rumpf2010-02-281-4/+12
* further cleanup for new GTK wrapperAndreas Rumpf2010-02-271-10/+5
* fixed pango/pangoutils new wrappersAndreas Rumpf2010-02-261-16/+93
* continued work on html/xmlparserrumpf_a@web.de2010-02-141-0/+0
* httpserver supports a fixed port numberAndreas Rumpf2010-02-061-1/+1
* bug concerning constant evaluation fixedAndreas Rumpf2009-11-261-2/+2
* bind tableAndreas Rumpf2009-11-121-121/+166
* version 0.8.2rumpf_a@web.de2009-10-211-0/+1320
ntent="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; } .muRecipe { color: #ff8700; } .SalientComment { color: #00ffff; } .Comment { color: #9090ff; } .Delimiter { color: #800080; } .Special { color: #c00000; } .traceContains { color: #008000; } .Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .Identifier { color: #c0a020; } --> </style> <script type='text/javascript'> <!-- --> </script> </head> <body> <pre id='vimCodeElement'> <span class="Comment">//: A big convenience high-level languages provide is the ability to name memory</span> <span class="Comment">//: locations. In Mu, a transform called 'transform_names' provides this</span> <span class="Comment">//: convenience.</span> <span class="Delimiter">:(scenario transform_names)</span> <span class="muRecipe">def</span> main [ <span class="Normal">x</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">0</span> ] <span class="traceContains">+name: assign x 1</span> <span class="traceContains">+mem: storing 0 in location 1</span> <span class="Delimiter">:(scenarios transform)</span> <span class="Delimiter">:(scenario transform_names_fails_on_use_before_define)</span> <span class="Special">% Hide_errors = true;</span> <span class="muRecipe">def</span> main [ <span class="Normal">x</span>:num<span class="Special"> &lt;- </span>copy y:num ] <span class="traceContains">+error: main: tried to read ingredient 'y' in 'x:num &lt;- copy y:num' but it hasn't been written to yet</span> <span class="Comment"># todo: detect conditional defines</span> <span class="Delimiter">:(after &quot;Transform.push_back(compute_container_sizes)&quot;)</span> Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>transform_names<span class="Delimiter">);</span> <span class="Comment">// idempotent</span> <span class="Delimiter">:(before &quot;End Globals&quot;)</span> map&lt;recipe_ordinal<span class="Delimiter">,</span> map&lt;string<span class="Delimiter">,</span> <span class="Normal">int</span>&gt; &gt; Name<span class="Delimiter">;</span> <span class="Comment">//: the Name map is a global, so save it before tests and reset it for every</span> <span class="Comment">//: test, just to be safe.</span> <span class="Delimiter">:(before &quot;End Globals&quot;)</span> map&lt;recipe_ordinal<span class="Delimiter">,</span> map&lt;string<span class="Delimiter">,</span> <span class="Normal">int</span>&gt; &gt; Name_snapshot<span class="Delimiter">;</span> <span class="Delimiter">:(before &quot;End save_snapshots&quot;)</span> Name_snapshot = Name<span class="Delimiter">;</span> <span class="Delimiter">:(before &quot;End restore_snapshots&quot;)</span> Name = Name_snapshot<span class="Delimiter">;</span> <span class="Delimiter">:(code)</span> <span class="Normal">void</span> transform_names<span class="Delimiter">(</span><span class="Normal">const</span> recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> recipe&amp; caller = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span> trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;--- transform names for recipe &quot;</span> &lt;&lt; caller<span class="Delimiter">.</span>name &lt;&lt; end<span class="Delimiter">();</span> <span class="Normal">bool</span> names_used = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Normal">bool</span> numeric_locations_used = <span class="Constant">false</span><span class="Delimiter">;</span> map&lt;string<span class="Delimiter">,</span> <span class="Normal">int</span>&gt;&amp; names = Name[r]<span class="Delimiter">;</span> <span class="Comment">// store the indices 'used' so far in the map</span> <span class="Normal">int</span>&amp; curr_idx = names[<span class="Constant">&quot;&quot;</span>]<span class="Delimiter">;</span> ++curr_idx<span class="Delimiter">;</span> <span class="Comment">// avoid using index 0, benign skip in some other cases</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>caller<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> instruction&amp; inst = caller<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> <span class="Comment">// End transform_names(inst) Special-cases</span> <span class="Comment">// map names to addresses</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> in = <span class="Constant">0</span><span class="Delimiter">;</span> in &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++in<span class="Delimiter">)</span> <span class="Delimiter">{</span> reagent&amp; ingredient = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Comment">// Begin transform_names Ingredient Special-cases(ingredient, inst, caller)</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_disqualified<span class="Delimiter">(</span>ingredient<span class="Delimiter">,</span> inst<span class="Delimiter">,</span> caller<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_numeric_location<span class="Delimiter">(</span>ingredient<span class="Delimiter">))</span> numeric_locations_used = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_named_location<span class="Delimiter">(</span>ingredient<span class="Delimiter">))</span> names_used = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>ingredient<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!already_transformed<span class="Delimiter">(</span>ingredient<span class="Delimiter">,</span> names<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise &lt;&lt; maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;tried to read ingredient '&quot;</span> &lt;&lt; ingredient<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot;' in '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;' but it hasn't been written to yet</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Comment">// use-before-set Error</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">int</span> v = lookup_name<span class="Delimiter">(</span>ingredient<span class="Delimiter">,</span> r<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>v &gt;= <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> ingredient<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>v<span class="Delimiter">);</span> <span class="Comment">// Done Placing Ingredient(ingredient, inst, caller)</span> <span class="Delimiter">}</span> <span class="Normal">else</span> <span class="Delimiter">{</span> raise &lt;&lt; maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;can't find a place to store '&quot;</span> &lt;&lt; ingredient<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> out = <span class="Constant">0</span><span class="Delimiter">;</span> out &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++out<span class="Delimiter">)</span> <span class="Delimiter">{</span> reagent&amp; product = inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">);</span> <span class="Comment">// Begin transform_names Product Special-cases(product, inst, caller)</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_disqualified<span class="Delimiter">(</span>product<span class="Delimiter">,</span> inst<span class="Delimiter">,</span> caller<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_numeric_location<span class="Delimiter">(</span>product<span class="Delimiter">))</span> numeric_locations_used = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_named_location<span class="Delimiter">(</span>product<span class="Delimiter">))</span> names_used = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>product<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>product<span class="Delimiter">.</span>name<span class="Delimiter">)</span> == names<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;name&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;assign &quot;</span> &lt;&lt; product<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot; &quot;</span> &lt;&lt; curr_idx &lt;&lt; end<span class="Delimiter">();</span> names[product<span class="Delimiter">.</span>name] = curr_idx<span class="Delimiter">;</span> curr_idx += size_of<span class="Delimiter">(</span>product<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">int</span> v = lookup_name<span class="Delimiter">(</span>product<span class="Delimiter">,</span> r<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>v &gt;= <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> product<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>v<span class="Delimiter">);</span> <span class="Comment">// Done Placing Product(product, inst, caller)</span> <span class="Delimiter">}</span> <span class="Normal">else</span> <span class="Delimiter">{</span> raise &lt;&lt; maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;can't find a place to store '&quot;</span> &lt;&lt; product<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>names_used &amp;&amp; numeric_locations_used<span class="Delimiter">)</span> raise &lt;&lt; maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;mixing variable names and numeric addresses</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">bool</span> is_disqualified<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">mutable</span><span class="Comment">*/</span> reagent&amp; x<span class="Delimiter">,</span> <span class="Normal">const</span> instruction&amp; inst<span class="Delimiter">,</span> <span class="Normal">const</span> string&amp; recipe_name<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise &lt;&lt; maybe<span class="Delimiter">(</span>recipe_name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;missing type for '&quot;</span> &lt;&lt; x<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;' in '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Comment">// missing-type Error 1</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><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">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Comment">// End is_disqualified Cases</span> <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>initialized<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</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">bool</span> already_transformed<span class="Delimiter">(</span><span class="Normal">const</span> reagent&amp; r<span class="Delimiter">,</span> <span class="Normal">const</span> map&lt;string<span class="Delimiter">,</span> <span class="Normal">int</span>&gt;&amp; names<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> contains_key<span class="Delimiter">(</span>names<span class="Delimiter">,</span> r<span class="Delimiter">.</span>name<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">int</span> lookup_name<span class="Delimiter">(</span><span class="Normal">const</span> reagent&amp; r<span class="Delimiter">,</span> <span class="Normal">const</span> recipe_ordinal default_recipe<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> Name[default_recipe][r<span class="Delimiter">.</span>name]<span class="Delimiter">;</span> <span class="Delimiter">}</span> type_ordinal skip_addresses<span class="Delimiter">(</span>type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">while</span> <span class="Delimiter">(</span>type &amp;&amp; is_compound_type_starting_with<span class="Delimiter">(</span>type<span class="Delimiter">,</span> <span class="Constant">&quot;address&quot;</span><span class="Delimiter">))</span> type = type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">)</span> <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Comment">// error handled elsewhere</span> <span class="Identifier">return</span> root_type<span class="Delimiter">(</span>type<span class="Delimiter">)-&gt;</span>value<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">int</span> find_element_name<span class="Delimiter">(</span><span class="Normal">const</span> type_ordinal t<span class="Delimiter">,</span> <span class="Normal">const</span> string&amp; name<span class="Delimiter">,</span> <span class="Normal">const</span> string&amp; recipe_name<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">const</span> type_info&amp; container = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> t<span class="Delimiter">);</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>container<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Normal">if</span> <span class="Delimiter">(</span>container<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name == name<span class="Delimiter">)</span> <span class="Identifier">return</span> i<span class="Delimiter">;</span> raise &lt;&lt; maybe<span class="Delimiter">(</span>recipe_name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;unknown element '&quot;</span> &lt;&lt; name &lt;&lt; <span class="Constant">&quot;' in container '&quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> t<span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">bool</span> is_numeric_location<span class="Delimiter">(</span><span class="Normal">const</span> reagent&amp; x<span class="Delimiter">)</span> <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">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">&quot;0&quot;</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Comment">// used for chaining lexical scopes</span> <span class="Identifier">return</span> is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">bool</span> is_named_location<span class="Delimiter">(</span><span class="Normal">const</span> reagent&amp; x<span class="Delimiter">)</span> <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">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_special_name<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Identifier">return</span> !is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Comment">// all names here should either be disqualified or also in bind_special_scenario_names</span> <span class="Normal">bool</span> is_special_name<span class="Delimiter">(</span><span class="Normal">const</span> string&amp; s<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>s == <span class="Constant">&quot;_&quot;</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>s == <span class="Constant">&quot;0&quot;</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Comment">// End is_special_name Cases</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(scenario transform_names_supports_containers)</span> <span class="muRecipe">def</span> main [ <span class="Normal">x</span>:point<span class="Special"> &lt;- </span>merge <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">35</span> <span class="Normal">y</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">3</span> ] <span class="traceContains">+name: assign x 1</span> <span class="Comment"># skip location 2 because x occupies two locations</span> <span class="traceContains">+name: assign y 3</span> <span class="Delimiter">:(scenario transform_names_supports_static_arrays)</span> <span class="muRecipe">def</span> main [ <span class="Normal">x</span>:@:num:<span class="Constant">3</span><span class="Special"> &lt;- </span>create-array <span class="Normal">y</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">3</span> ] <span class="traceContains">+name: assign x 1</span> <span class="Comment"># skip locations 2, 3, 4 because x occupies four locations</span> <span class="traceContains">+name: assign y 5</span> <span class="Delimiter">:(scenario transform_names_passes_dummy)</span> <span class="Comment"># _ is just a dummy result that never gets consumed</span> <span class="muRecipe">def</span> main [ _<span class="Delimiter">,</span> x:num<span class="Special"> &lt;- </span>copy <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">1</span> ] <span class="traceContains">+name: assign x 1</span> <span class="traceAbsent">-name: assign _ 1</span> <span class="Comment">//: an escape hatch to suppress name conversion that we'll use later</span> <span class="Delimiter">:(scenarios run)</span> <span class="Delimiter">:(scenario transform_names_passes_raw)</span> <span class="Special">% Hide_errors = true;</span> <span class="muRecipe">def</span> main [ <span class="Normal">x</span>:num/<span class="Special">raw &lt;- </span>copy <span class="Constant">0</span> ] <span class="traceAbsent">-name: assign x 1</span> <span class="traceContains">+error: can't write to location 0 in 'x:num/raw &lt;- copy 0'</span> <span class="Delimiter">:(scenarios transform)</span> <span class="Delimiter">:(scenario transform_names_fails_when_mixing_names_and_numeric_locations)</span> <span class="Special">% Hide_errors = true;</span> <span class="muRecipe">def</span> main [ <span class="Normal">x</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>:num ] <span class="traceContains">+error: main: mixing variable names and numeric addresses</span> <span class="Delimiter">:(scenario transform_names_fails_when_mixing_names_and_numeric_locations_2)</span> <span class="Special">% Hide_errors = true;</span> <span class="muRecipe">def</span> main [ <span class="Normal">x</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">1</span> <span class="Constant">1</span>:num<span class="Special"> &lt;- </span>copy x:num ] <span class="traceContains">+error: main: mixing variable names and numeric addresses</span> <span class="Delimiter">:(scenario transform_names_does_not_fail_when_mixing_names_and_raw_locations)</span> <span class="muRecipe">def</span> main [ <span class="Normal">x</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>:num/<span class="Special">raw</span> ] <span class="traceAbsent">-error: main: mixing variable names and numeric addresses</span> $error: <span class="Constant">0</span> <span class="Delimiter">:(scenario transform_names_does_not_fail_when_mixing_names_and_literals)</span> <span class="muRecipe">def</span> main [ <span class="Normal">x</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">1</span> ] <span class="traceAbsent">-error: main: mixing variable names and numeric addresses</span> $error: <span class="Constant">0</span> <span class="SalientComment">//:: Support element names for containers in 'get' and 'get-location' and 'put'.</span> <span class="Comment">//: (get-location is implemented later)</span> <span class="Delimiter">:(scenario transform_names_transforms_container_elements)</span> <span class="muRecipe">def</span> main [ <span class="Normal">p</span>:&amp;:point<span class="Special"> &lt;- </span>copy <span class="Constant">0</span> <span class="Normal">a</span>:num<span class="Special"> &lt;- </span>get *p:&amp;:point<span class="Delimiter">,</span> <span class="Constant">y:offset</span> <span class="Normal">b</span>:num<span class="Special"> &lt;- </span>get *p:&amp;:point<span class="Delimiter">,</span> <span class="Constant">x:offset</span> ] <span class="traceContains">+name: element y of type point is at offset 1</span> <span class="traceContains">+name: element x of type point is at offset 0</span> <span class="Delimiter">:(before &quot;End transform_names(inst) Special-cases&quot;)</span> <span class="Comment">// replace element names of containers with offsets</span> <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">&quot;get&quot;</span> || inst<span class="Delimiter">.</span>name == <span class="Constant">&quot;get-location&quot;</span> || inst<span class="Delimiter">.</span>name == <span class="Constant">&quot;put&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">//: avoid raising any errors here; later layers will support overloading new</span> <span class="Comment">//: instructions with the same names (static dispatch), which could lead to</span> <span class="Comment">//: spurious errors</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> &lt; <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Comment">// error raised elsewhere</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!is_literal<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="Identifier">break</span><span class="Delimiter">;</span> <span class="Comment">// error raised elsewhere</span> <span class="Normal">if</span> <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>name<span class="Delimiter">.</span>find_first_not_of<span class="Delimiter">(</span><span class="Constant">&quot;0123456789&quot;</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// since first non-address in base type must be a container, we don't have to canonize</span> type_ordinal base_type = skip_addresses<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>type<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>base_type == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Comment">// error raised elsewhere</span> <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Comment">// otherwise we'll raise an error elsewhere</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>set_value<span class="Delimiter">(</span>find_element_name<span class="Delimiter">(</span>base_type<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>name<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">));</span> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;name&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;element &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; of type &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; is at offset &quot;</span> &lt;&lt; no_scientific<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>value<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Comment">//: this test is actually illegal so can't call run</span> <span class="Delimiter">:(scenarios transform)</span> <span class="Delimiter">:(scenario transform_names_handles_containers)</span> <span class="muRecipe">def</span> main [ <span class="Normal">a</span>:point<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/unsafe <span class="Normal">b</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/unsafe ] <span class="traceContains">+name: assign a 1</span> <span class="traceContains">+name: assign b 3</span> <span class="SalientComment">//:: Support variant names for exclusive containers in 'maybe-convert'.</span> <span class="Delimiter">:(scenarios run)</span> <span class="Delimiter">:(scenario transform_names_handles_exclusive_containers)</span> <span class="muRecipe">def</span> main [ <span class="Constant">12</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">1</span> <span class="Constant">13</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">35</span> <span class="Constant">14</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">36</span> <span class="Constant">20</span>:point<span class="Delimiter">,</span> <span class="Constant">22</span>:<span class="Normal">bool</span><span class="Special"> &lt;- </span>maybe-convert <span class="Constant">12</span>:number-<span class="Normal">or</span>-point/unsafe<span class="Delimiter">,</span> <span class="Constant">p:variant</span> ] <span class="traceContains">+name: variant p of type number-or-point has tag 1</span> <span class="traceContains">+mem: storing 1 in location 22</span> <span class="traceContains">+mem: storing 35 in location 20</span> <span class="traceContains">+mem: storing 36 in location 21</span> <span class="Delimiter">:(before &quot;End transform_names(inst) Special-cases&quot;)</span> <span class="Comment">// convert variant names of exclusive containers</span> <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">&quot;maybe-convert&quot;</span><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>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;exactly 2 ingredients expected in '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> assert<span class="Delimiter">(</span>is_literal<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="Normal">if</span> <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>name<span class="Delimiter">.</span>find_first_not_of<span class="Delimiter">(</span><span class="Constant">&quot;0123456789&quot;</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// since first non-address in base type must be an exclusive container, we don't have to canonize</span> type_ordinal base_type = skip_addresses<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>type<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>base_type == -<span class="Constant">1</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;expected an exclusive-container in '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Comment">// otherwise we'll raise an error elsewhere</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>set_value<span class="Delimiter">(</span>find_element_name<span class="Delimiter">(</span>base_type<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>name<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">));</span> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;name&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;variant &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; of type &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; has tag &quot;</span> &lt;&lt; no_scientific<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>value<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> </pre> </body> </html> <!-- vim: set foldmethod=manual : -->