about summary refs log tree commit diff stats
path: root/html/018type_abbreviations.cc.html
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-09-15 01:01:58 -0700
committerKartik K. Agaram <vc@akkartik.com>2016-09-15 01:01:58 -0700
commit0ca56ed853c3d9bc8c26d1b014d8b665363fc2d0 (patch)
treeabd2d2e4b65c34797a635aeb2f7d06c9d65c7bf9 /html/018type_abbreviations.cc.html
parent36b927a63cb25e9fc64cf4ae079b32d23d528b1b (diff)
downloadmu-0ca56ed853c3d9bc8c26d1b014d8b665363fc2d0.tar.gz
3355
Diffstat (limited to 'html/018type_abbreviations.cc.html')
-rw-r--r--html/018type_abbreviations.cc.html259
1 files changed, 181 insertions, 78 deletions
diff --git a/html/018type_abbreviations.cc.html b/html/018type_abbreviations.cc.html
index 5f2ff869..a025de1d 100644
--- a/html/018type_abbreviations.cc.html
+++ b/html/018type_abbreviations.cc.html
@@ -14,12 +14,12 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-
 body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color: #080808; }
 * { font-size: 12pt; font-size: 1em; }
 .Constant { color: #00a0a0; }
-.Special { color: #c00000; }
-.traceContains { color: #008000; }
 .cSpecial { color: #008000; }
+.traceContains { color: #008000; }
+.SalientComment { color: #00ffff; }
 .Comment { color: #9090ff; }
 .Delimiter { color: #800080; }
-.SalientComment { color: #00ffff; }
+.Special { color: #c00000; }
 .Identifier { color: #fcb165; }
 .Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; }
 -->
@@ -33,96 +33,199 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
 </head>
 <body>
 <pre id='vimCodeElement'>
-<span class="Comment">//: For convenience, make some common types shorter.</span>
-<span class="Comment">//:</span>
-<span class="Comment">//:   a) Rewrite '&amp;t' to 'address:t' and '@t' to 'array:type' (with the</span>
-<span class="Comment">//:   ability to chain any combination of the two). This is not extensible.</span>
-<span class="Comment">//:</span>
-<span class="Comment">//:   b) Provide a facility to create new type names out of old ones.</span>
-
-<span class="SalientComment">//:: a) expanding '&amp;' and '@'</span>
+<span class="Comment">//: For convenience, allow Mu types to be abbreviated.</span>
 
-<span class="Delimiter">:(scenarios load)</span>
-<span class="Delimiter">:(scenario abbreviations_for_address_and_array)</span>
+<span class="Delimiter">:(scenarios transform)</span>
+<span class="Delimiter">:(scenario type_abbreviations)</span>
+type foo = number
 def main [
-  f <span class="Constant">1</span>:&amp;number  <span class="Comment"># abbreviation for 'address:number'</span>
-  f <span class="Constant">2</span>:@number  <span class="Comment"># abbreviation for 'array:number'</span>
-  f <span class="Constant">3</span>:&amp;@number  <span class="Comment"># combining '&amp;' and '@'</span>
-  f <span class="Constant">4</span>:&amp;&amp;@&amp;@number  <span class="Comment"># ..any number of times</span>
-  f <span class="Constant">5</span>:array:&amp;number:<span class="Constant">3</span>  <span class="Comment"># abbreviations take precedence over ':'</span>
-  f <span class="Delimiter">{</span><span class="Constant">6</span>: <span class="Delimiter">(</span>array &amp;number <span class="Constant">3</span><span class="Delimiter">)}</span>  <span class="Comment"># support for dilated reagents and more complex parse trees</span>
-  f <span class="Constant">7</span>:@number:<span class="Constant">3</span>  <span class="Comment"># *not* the same as array:number:3</span>
+  <span class="Normal">a</span>:foo<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
 ]
-<span class="traceContains">+parse:   ingredient: {1: (&quot;address&quot; &quot;number&quot;)}</span>
-<span class="traceContains">+parse:   ingredient: {2: (&quot;array&quot; &quot;number&quot;)}</span>
-<span class="traceContains">+parse:   ingredient: {3: (&quot;address&quot; &quot;array&quot; &quot;number&quot;)}</span>
-<span class="traceContains">+parse:   ingredient: {4: (&quot;address&quot; &quot;address&quot; &quot;array&quot; &quot;address&quot; &quot;array&quot; &quot;number&quot;)}</span>
-<span class="traceContains">+parse:   ingredient: {5: (&quot;array&quot; (&quot;address&quot; &quot;number&quot;) &quot;3&quot;)}</span>
-<span class="traceContains">+parse:   ingredient: {6: (&quot;array&quot; (&quot;address&quot; &quot;number&quot;) &quot;3&quot;)}</span>
-<span class="Comment"># not what you want</span>
-<span class="traceContains">+parse:   ingredient: {7: ((&quot;array&quot; &quot;number&quot;) &quot;3&quot;)}</span>
-
-<span class="Delimiter">:(scenario abbreviation_error)</span>
+<span class="traceContains">+transform: product type after expanding abbreviations: &quot;number&quot;</span>
+
+<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
+map&lt;string<span class="Delimiter">,</span> type_tree*&gt; Type_abbreviations<span class="Delimiter">,</span> Type_abbreviations_snapshot<span class="Delimiter">;</span>
+
+<span class="SalientComment">//:: Defining type abbreviations.</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;type&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  load_type_abbreviations<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(code)</span>
+<span class="Normal">void</span> load_type_abbreviations<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  string new_type_name = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+  assert<span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">)</span> || !new_type_name<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">)</span> || new_type_name<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+    raise &lt;&lt; <span class="Constant">&quot;incomplete 'type' statement; must be of the form 'type &lt;new type name&gt; = &lt;type expression&gt;'</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>
+  string arrow = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+  assert<span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">)</span> || !arrow<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>arrow<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+    raise &lt;&lt; <span class="Constant">&quot;incomplete 'type' statement 'type &quot;</span> &lt;&lt; new_type_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="Normal">if</span> <span class="Delimiter">(</span>arrow != <span class="Constant">&quot;=&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    raise &lt;&lt; <span class="Constant">&quot;'type' statements must be of the form 'type &lt;new type name&gt; = &lt;type expression&gt;' but got 'type &quot;</span> &lt;&lt; new_type_name &lt;&lt; <span class="Constant">' '</span> &lt;&lt; arrow &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="Normal">if</span> <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+    raise &lt;&lt; <span class="Constant">&quot;incomplete 'type' statement 'type &quot;</span> &lt;&lt; new_type_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>
+  string old = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>old<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+    raise &lt;&lt; <span class="Constant">&quot;incomplete 'type' statement 'type &quot;</span> &lt;&lt; new_type_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>
+    raise &lt;&lt; <span class="Constant">&quot;'type' statements must be of the form 'type &lt;new type name&gt; = &lt;type expression&gt;' but got 'type &quot;</span> &lt;&lt; new_type_name &lt;&lt; <span class="Constant">' '</span> &lt;&lt; arrow &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="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type_abbreviations<span class="Delimiter">,</span> new_type_name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+    raise &lt;&lt; <span class="Constant">&quot;'type' conflict: '&quot;</span> &lt;&lt; new_type_name &lt;&lt; <span class="Constant">&quot;' defined as both '&quot;</span> &lt;&lt; names_to_string_without_quotes<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_abbreviations<span class="Delimiter">,</span> new_type_name<span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;' and '&quot;</span> &lt;&lt; old &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>
+  trace<span class="Delimiter">(</span><span class="Constant">9990</span><span class="Delimiter">,</span> <span class="Constant">&quot;type&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;alias &quot;</span> &lt;&lt; new_type_name &lt;&lt; <span class="Constant">&quot; = &quot;</span> &lt;&lt; old &lt;&lt; end<span class="Delimiter">();</span>
+  type_tree* old_type = new_type_tree<span class="Delimiter">(</span>old<span class="Delimiter">);</span>
+  put<span class="Delimiter">(</span>Type_abbreviations<span class="Delimiter">,</span> new_type_name<span class="Delimiter">,</span> old_type<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+type_tree* new_type_tree<span class="Delimiter">(</span><span class="Normal">const</span> string&amp; x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  string_tree* type_names = starts_with<span class="Delimiter">(</span>x<span class="Delimiter">,</span> <span class="Constant">&quot;(&quot;</span><span class="Delimiter">)</span> ? parse_string_tree<span class="Delimiter">(</span>x<span class="Delimiter">)</span> : parse_string_list<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
+  type_tree* result = new_type_tree<span class="Delimiter">(</span>type_names<span class="Delimiter">);</span>
+  <span class="Normal">delete</span> type_names<span class="Delimiter">;</span>
+  expand_type_abbreviations<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
+  <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+string_tree* parse_string_list<span class="Delimiter">(</span><span class="Normal">const</span> string&amp; s<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  istringstream in<span class="Delimiter">(</span>s<span class="Delimiter">);</span>
+  in &gt;&gt; std::noskipws<span class="Delimiter">;</span>
+  <span class="Identifier">return</span> parse_property_list<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario type_error1)</span>
 <span class="Special">% Hide_errors = true;</span>
+type foo
+<span class="traceContains">+error: incomplete 'type' statement 'type foo'</span>
+
+<span class="Delimiter">:(scenario type_error2)</span>
+<span class="Special">% Hide_errors = true;</span>
+type foo =
+<span class="traceContains">+error: incomplete 'type' statement 'type foo ='</span>
+
+<span class="Delimiter">:(scenario type_error3)</span>
+<span class="Special">% Hide_errors = true;</span>
+type foo bar baz
+<span class="traceContains">+error: 'type' statements must be of the form 'type &lt;new type name&gt; = &lt;type expression&gt;' but got 'type foo bar'</span>
+
+<span class="Delimiter">:(scenario type_conflict_error)</span>
+<span class="Special">% Hide_errors = true;</span>
+type foo = bar
+type foo = baz
+<span class="traceContains">+error: 'type' conflict: 'foo' defined as both 'bar' and 'baz'</span>
+
+<span class="Delimiter">:(scenario type_abbreviation_for_compound)</span>
+type foo = address:number
 def main [
-  f <span class="Constant">1</span>:&amp;&amp;@&amp;  <span class="Comment"># abbreviations without payload</span>
+  <span class="Normal">a</span>:foo<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
 ]
-<span class="traceContains">+error: invalid type abbreviation &amp;&amp;@&amp;</span>
+<span class="traceContains">+transform: product type after expanding abbreviations: (&quot;address&quot; &quot;number&quot;)</span>
 
-<span class="Delimiter">:(before &quot;End Parsing Reagent Type Property(type_names)&quot;)</span>
-string_tree* new_type_names = replace_address_and_array_symbols<span class="Delimiter">(</span>type_names<span class="Delimiter">);</span>
-<span class="Normal">delete</span> type_names<span class="Delimiter">;</span>
-type_names = new_type_names<span class="Delimiter">;</span>
-<span class="Delimiter">:(before &quot;End Parsing Dilated Reagent Type Property(type_names)&quot;)</span>
-string_tree* new_type_names = replace_address_and_array_symbols<span class="Delimiter">(</span>type_names<span class="Delimiter">);</span>
-<span class="Normal">delete</span> type_names<span class="Delimiter">;</span>
-type_names = new_type_names<span class="Delimiter">;</span>
+<span class="Comment">//: cleaning up type abbreviations between tests and before exiting</span>
 
+<span class="Delimiter">:(before &quot;End save_snapshots&quot;)</span>
+Type_abbreviations_snapshot = Type_abbreviations<span class="Delimiter">;</span>
+<span class="Delimiter">:(before &quot;End restore_snapshots&quot;)</span>
+restore_type_abbreviations<span class="Delimiter">();</span>
+<span class="Delimiter">:(before &quot;End One-time Setup&quot;)</span>
+atexit<span class="Delimiter">(</span>clear_type_abbreviations<span class="Delimiter">);</span>
 <span class="Delimiter">:(code)</span>
-<span class="Comment">// simple version; lots of unnecessary allocations; always creates a new pointer</span>
-string_tree* replace_address_and_array_symbols<span class="Delimiter">(</span>string_tree* orig<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  <span class="Normal">if</span> <span class="Delimiter">(</span>orig == <span class="Constant">NULL</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span>
-  <span class="Normal">if</span> <span class="Delimiter">(</span>orig<span class="Delimiter">-&gt;</span>atom<span class="Delimiter">)</span>
-    <span class="Identifier">return</span> replace_address_and_array_symbols<span class="Delimiter">(</span>orig<span class="Delimiter">-&gt;</span>value<span class="Delimiter">);</span>
-  <span class="Identifier">return</span> <span class="Normal">new</span> string_tree<span class="Delimiter">(</span>replace_address_and_array_symbols<span class="Delimiter">(</span>orig<span class="Delimiter">-&gt;</span>left<span class="Delimiter">),</span>
-                         replace_address_and_array_symbols<span class="Delimiter">(</span>orig<span class="Delimiter">-&gt;</span>right<span class="Delimiter">));</span>
+<span class="Normal">void</span> restore_type_abbreviations<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+  <span class="Normal">for</span> <span class="Delimiter">(</span>map&lt;string<span class="Delimiter">,</span> type_tree*&gt;::iterator p = Type_abbreviations<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Type_abbreviations<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>Type_abbreviations_snapshot<span class="Delimiter">,</span> p<span class="Delimiter">-&gt;</span>first<span class="Delimiter">))</span>
+      <span class="Normal">delete</span> p<span class="Delimiter">-&gt;</span>second<span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
+  Type_abbreviations<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+  Type_abbreviations = Type_abbreviations_snapshot<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Normal">void</span> clear_type_abbreviations<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+  <span class="Normal">for</span> <span class="Delimiter">(</span>map&lt;string<span class="Delimiter">,</span> type_tree*&gt;::iterator p = Type_abbreviations<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Type_abbreviations<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span>
+    <span class="Normal">delete</span> p<span class="Delimiter">-&gt;</span>second<span class="Delimiter">;</span>
+  Type_abbreviations<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
 <span class="Delimiter">}</span>
 
-<span class="Comment">// todo: unicode</span>
-string_tree* replace_address_and_array_symbols<span class="Delimiter">(</span><span class="Normal">const</span> string&amp; type_name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  <span class="Normal">if</span> <span class="Delimiter">(</span>type_name<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span>
-  <span class="Normal">if</span> <span class="Delimiter">(</span>type_name<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> != <span class="Constant">'&amp;'</span> &amp;&amp; type_name<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> != <span class="Constant">'@'</span><span class="Delimiter">)</span>
-    <span class="Identifier">return</span> <span class="Normal">new</span> string_tree<span class="Delimiter">(</span>type_name<span class="Delimiter">);</span>
-  string_tree* result = <span class="Constant">NULL</span><span class="Delimiter">;</span>
-  string_tree* curr = <span class="Constant">NULL</span><span class="Delimiter">;</span>
-  <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>
-  <span class="Normal">while</span> <span class="Delimiter">(</span>i &lt; SIZE<span class="Delimiter">(</span>type_name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
-    string_tree* new_node = <span class="Constant">NULL</span><span class="Delimiter">;</span>
-    <span class="Normal">if</span> <span class="Delimiter">(</span>type_name<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == <span class="Constant">'&amp;'</span><span class="Delimiter">)</span>
-      new_node = <span class="Normal">new</span> string_tree<span class="Delimiter">(</span><span class="Constant">&quot;address&quot;</span><span class="Delimiter">);</span>
-    <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>type_name<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == <span class="Constant">'@'</span><span class="Delimiter">)</span>
-      new_node = <span class="Normal">new</span> string_tree<span class="Delimiter">(</span><span class="Constant">&quot;array&quot;</span><span class="Delimiter">);</span>
-    <span class="Normal">else</span>
-      <span class="Identifier">break</span><span class="Delimiter">;</span>
-    <span class="Normal">if</span> <span class="Delimiter">(</span>result == <span class="Constant">NULL</span><span class="Delimiter">)</span>
-      result = curr = <span class="Normal">new</span> string_tree<span class="Delimiter">(</span>new_node<span class="Delimiter">,</span> <span class="Constant">NULL</span><span class="Delimiter">);</span>
-    <span class="Normal">else</span> <span class="Delimiter">{</span>
-      curr<span class="Delimiter">-&gt;</span>right = <span class="Normal">new</span> string_tree<span class="Delimiter">(</span>new_node<span class="Delimiter">,</span> <span class="Constant">NULL</span><span class="Delimiter">);</span>
-      curr = curr<span class="Delimiter">-&gt;</span>right<span class="Delimiter">;</span>
+<span class="SalientComment">//:: A few default abbreviations.</span>
+
+<span class="Delimiter">:(before &quot;End Mu Types Initialization&quot;)</span>
+put<span class="Delimiter">(</span>Type_abbreviations<span class="Delimiter">,</span> <span class="Constant">&quot;&amp;&quot;</span><span class="Delimiter">,</span> new_type_tree<span class="Delimiter">(</span><span class="Constant">&quot;address&quot;</span><span class="Delimiter">));</span>
+put<span class="Delimiter">(</span>Type_abbreviations<span class="Delimiter">,</span> <span class="Constant">&quot;@&quot;</span><span class="Delimiter">,</span> new_type_tree<span class="Delimiter">(</span><span class="Constant">&quot;array&quot;</span><span class="Delimiter">));</span>
+put<span class="Delimiter">(</span>Type_abbreviations<span class="Delimiter">,</span> <span class="Constant">&quot;num&quot;</span><span class="Delimiter">,</span> new_type_tree<span class="Delimiter">(</span><span class="Constant">&quot;number&quot;</span><span class="Delimiter">));</span>
+put<span class="Delimiter">(</span>Type_abbreviations<span class="Delimiter">,</span> <span class="Constant">&quot;bool&quot;</span><span class="Delimiter">,</span> new_type_tree<span class="Delimiter">(</span><span class="Constant">&quot;boolean&quot;</span><span class="Delimiter">));</span>
+put<span class="Delimiter">(</span>Type_abbreviations<span class="Delimiter">,</span> <span class="Constant">&quot;char&quot;</span><span class="Delimiter">,</span> new_type_tree<span class="Delimiter">(</span><span class="Constant">&quot;character&quot;</span><span class="Delimiter">));</span>
+
+<span class="Delimiter">:(scenario use_type_abbreviations_when_declaring_type_abbreviations)</span>
+type foo = &amp;:num
+def main [
+  <span class="Normal">a</span>:foo<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
+]
+<span class="traceContains">+transform: product type after expanding abbreviations: (&quot;address&quot; &quot;number&quot;)</span>
+
+<span class="SalientComment">//:: Expand type aliases before running.</span>
+<span class="Comment">//: We'll do this in a transform so that we don't need to define abbreviations</span>
+<span class="Comment">//: before we use them.</span>
+
+<span class="Delimiter">:(scenario abbreviations_for_address_and_array)</span>
+def main [
+  f <span class="Constant">1</span>:&amp;:number  <span class="Comment"># abbreviation for 'address:number'</span>
+  f <span class="Constant">2</span>:@:number  <span class="Comment"># abbreviation for 'array:number'</span>
+  f <span class="Constant">3</span>:&amp;:@:number  <span class="Comment"># combining '&amp;' and '@'</span>
+  f <span class="Constant">4</span>:&amp;:&amp;:@:&amp;:@:number  <span class="Comment"># ..any number of times</span>
+  f <span class="Delimiter">{</span><span class="Constant">5</span>: <span class="Delimiter">(</span>array <span class="Delimiter">(</span>&amp; number<span class="Delimiter">)</span> <span class="Constant">3</span><span class="Delimiter">)}</span>  <span class="Comment"># support for dilated reagents and more complex parse trees</span>
+]
+def f [
+]
+<span class="traceContains">+transform: --- expand type abbreviations in recipe 'main'</span>
+<span class="traceContains">+transform: ingredient type after expanding abbreviations: (&quot;address&quot; &quot;number&quot;)</span>
+<span class="traceContains">+transform: ingredient type after expanding abbreviations: (&quot;array&quot; &quot;number&quot;)</span>
+<span class="traceContains">+transform: ingredient type after expanding abbreviations: (&quot;address&quot; &quot;array&quot; &quot;number&quot;)</span>
+<span class="traceContains">+transform: ingredient type after expanding abbreviations: (&quot;address&quot; &quot;address&quot; &quot;array&quot; &quot;address&quot; &quot;array&quot; &quot;number&quot;)</span>
+<span class="traceContains">+transform: ingredient type after expanding abbreviations: (&quot;array&quot; (&quot;address&quot; &quot;number&quot;) &quot;3&quot;)</span>
+
+<span class="Delimiter">:(before &quot;Transform.push_back(update_instruction_operations)&quot;)</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>expand_type_abbreviations<span class="Delimiter">);</span>  <span class="Comment">// idempotent</span>
+<span class="Comment">// Begin Type Modifying Transforms</span>
+<span class="Comment">// End Type Modifying Transforms</span>
+
+<span class="Delimiter">:(code)</span>
+<span class="Normal">void</span> expand_type_abbreviations<span class="Delimiter">(</span><span class="Normal">const</span> recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  <span class="Normal">const</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;--- expand type abbreviations in recipe '&quot;</span> &lt;&lt; caller<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot;'&quot;</span> &lt;&lt; end<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>caller<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 = caller<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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;instruction '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>original_string &lt;&lt; end<span class="Delimiter">();</span>
+    <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      expand_type_abbreviations<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">);</span>
+      trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;ingredient type after expanding abbreviations: &quot;</span> &lt;&lt; names_to_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span>
+    <span class="Delimiter">}</span>
+    <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      expand_type_abbreviations<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">);</span>
+      trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;product type after expanding abbreviations: &quot;</span> &lt;&lt; names_to_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Delimiter">}</span>
-    ++i<span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
-  <span class="Normal">if</span> <span class="Delimiter">(</span>i &lt; SIZE<span class="Delimiter">(</span>type_name<span class="Delimiter">))</span>
-    curr<span class="Delimiter">-&gt;</span>right = <span class="Normal">new</span> string_tree<span class="Delimiter">(</span>type_name<span class="Delimiter">.</span>substr<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
-  <span class="Normal">else</span>
-    raise &lt;&lt; <span class="Constant">&quot;invalid type abbreviation &quot;</span> &lt;&lt; type_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> result<span class="Delimiter">;</span>
+  <span class="Comment">// End Expand Type Abbreviations(caller)</span>
 <span class="Delimiter">}</span>
 
-<span class="SalientComment">//:: b) extensible type abbreviations</span>
-
-<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
-map&lt;string<span class="Delimiter">,</span> type_tree*&gt; Type_abbreviations<span class="Delimiter">;</span>
+<span class="Normal">void</span> expand_type_abbreviations<span class="Delimiter">(</span>type_tree* type<span class="Delimiter">)</span> <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="Delimiter">;</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-&gt;</span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    expand_type_abbreviations<span class="Delimiter">(</span>type<span class="Delimiter">-&gt;</span>left<span class="Delimiter">);</span>
+    expand_type_abbreviations<span class="Delimiter">(</span>type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">);</span>
+    <span class="Identifier">return</span><span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type_abbreviations<span class="Delimiter">,</span> type<span class="Delimiter">-&gt;</span>name<span class="Delimiter">))</span>
+    *type = type_tree<span class="Delimiter">(</span>*get<span class="Delimiter">(</span>Type_abbreviations<span class="Delimiter">,</span> type<span class="Delimiter">-&gt;</span>name<span class="Delimiter">));</span>
+<span class="Delimiter">}</span>
 </pre>
 </body>
 </html>