https://github.com/akkartik/mu/blob/master/032array.cc
  1 //: Arrays contain a variable number of elements of the same type. Their value
  2 //: starts with the length of the array.
  3 //:
  4 //: You can create arrays of containers, but containers can only contain
  5 //: elements of a fixed size, so you can't create containers containing arrays.
  6 //: Create containers containing addresses to arrays instead.
  7 
  8 //: You can create arrays using 'create-array'.
  9 :(scenario create_array)
 10 def main [
 11   # create an array occupying locations 1 (for the size) and 2-4 (for the elements)
 12   1:array:num:3 <- create-array
 13 ]
 14 +run: creating array from 4 locations
 15 
 16 :(before "End Primitive Recipe Declarations")
 17 CREATE_ARRAY,
 18 :(before "End Primitive Recipe Numbers")
 19 put(Recipe_ordinal, "create-array", CREATE_ARRAY);
 20 :(before "End Primitive Recipe Checks")
 21 case CREATE_ARRAY: {
 22   if (inst.products.empty()) {
 23     raise << maybe(get(Recipe, r).name) << "'create-array' needs one product and no ingredients but got '" << to_original_string(inst) << '\n' << end();
 24     break;
 25   }
 26   reagent/*copy*/ product = inst.products.at(0);
 27   // Update CREATE_ARRAY product in Check
 28   if (!is_mu_array(product)) {
 29     raise << maybe(get(Recipe, r).name) << "'create-array' cannot create non-array '" << product.original_string << "'\n" << end();
 30     break;
 31   }
 32   if (!product.type->right) {
 33     raise << maybe(get(Recipe, r).name) << "create array of what? '" << to_original_string(inst) << "'\n" << end();
 34     break;
 35   }
 36   // 'create-array' will need to check properties rather than types
 37   type_tree* array_length_from_type = product.type->right->right;
 38   if (!array_length_from_type) {
 39     raise << maybe(get(Recipe, r).name) << "create array of what size? '" << to_original_string(inst) << "'\n" << end();
 40     break;
 41   }
 42   if (!product.type->right->right->atom)
 43     array_length_from_type = array_length_from_type->left;
 44   if (!is_integer(array_length_from_type->name)) {
 45     raise << maybe(get(Recipe, r).name) << "'create-array' product should specify size of array after its element type, but got '" << product.type->right->right->name << "'\n" << end();
 46     break;
 47   }
 48   break;
 49 }
 50 :(before "End Primitive Recipe Implementations")
 51 case CREATE_ARRAY: {
 52   reagent/*copy*/ product = current_instruction().products.at(0);
 53   // Update CREATE_ARRAY product in Run
 54   int base_address = product.value;
 55   type_tree* array_length_from_type = product.type->right->right;
 56   if (!product.type->right->right->atom)
 57     array_length_from_type = array_length_from_type->left;
 58   int array_length = to_integer(array_length_from_type->name);
 59   // initialize array length, so that size_of will work
 60   trace("mem") << "storing " << array_length << " in location " << base_address << end();
 61   put(Memory, base_address, array_length);  // in array elements
 62   int size = size_of(product);  // in locations
 63   trace(9998, "run") << "creating array from " << size << " locations" << end();
 64   // initialize array
 65   for (int i = 1;  i <= size_of(product);  ++i)
 66     put(Memory, base_address+i, 0);
 67   // no need to update product
 68   write_products = false;
 69   break;
 70 }
 71 
 72 :(scenario copy_array)
 73 # Arrays can be copied around with a single instruction just like numbers,
 74 # no matter how large they are.
 75 # You don't need to pass the size around, since each array variable stores its
 76 # size in memory at run-time. We'll call a variable with an explicit size a
 77 # 'static' array, and one without a 'dynamic' array since it can contain
 78 # arrays of many different sizes.
 79 def main [
 80   1:array:num:3 <- create-array
 81   2:num <- copy 14
 82   3:num <- copy 15
 83   4:num <- copy 16
 84   5:array:num <- copy 1:array:num:3
 85 ]
 86 +mem: storing 3 in location 5
 87 +mem: storing 14 in location 6
 88 +mem: storing 15 in location 7
 89 +mem: storing 16 in location 8
 90 
 91 :(scenario stash_array)
 92 def main [
 93   1:array:num:3 <- create-array
 94   2:num <- copy 14
 95   3:num <- copy 15
 96   4:num <- copy 16
 97   stash [foo:], 1:array:num:3
 98 ]
 99 +app: foo: 3 14 15 16
100 
101 :(before "End types_coercible Special-cases")
102 if (is_mu_array(from) && is_mu_array(to))
103   return types_strictly_match(array_element(from.type), array_element(to.type));
104 
105 :(before "End size_of(reagent r) Special-cases")
106 if (!r.type->atom && r.type->left->atom && r.type->left->value == Array_type_ordinal) {
107   if (!r.type->right) {
108     raise << maybe(current_recipe_name()) << "'" << r.original_string << "' is an array of what?\n" << end();
109     return 1;
110   }
111   return /*space for length*/1 + array_length(r)*size_of(array_element(r.type));
112 }
113 
114 :(before "End size_of(type) Non-atom Special-cases")
115 if (type->left->value == Array_type_ordinal) return static_array_length(type);
116 :(code)
117 int static_array_length(const type_tree* type) {
118   if (!type->atom && type->right && !type->right->atom && type->right->right && !type->right->right->atom && !type->right->right->right  // exactly 3 types
119       && type->right->right->left && type->right->right->left->atom && is_integer(type->right->right->left->name)) {  // third 'type' is a number
120     // get size from type
121     return to_integer(type->right->right->left->name);
122   }
123   cerr << to_string(type) << '\n';
124   assert(false);
125 }
126 
127 //: disable the size mismatch check for arrays since the destination array
128 //: need not be initialized
129 :(before "End size_mismatch(x) Special-cases")
130 if (x.type && !x.type->atom && x.type->left->value == Array_type_ordinal) return false;
131 
132 //:: arrays inside containers
133 //: arrays are disallowed inside containers unless their length is fixed in
134 //: advance
135 
136 :(scenario container_permits_static_array_element)
137 container foo [
138   x:array:num:3
139 ]
140 $error: 0
141 
142 :(before "End insert_container Special-cases")
143 else if (is_integer(type->name)) {  // sometimes types will contain non-type tags, like numbers for the size of an array
144   type->value = 0;
145 }
146 
147 :(scenario container_disallows_dynamic_array_element)
148 % Hide_errors = true;
149 container foo [
150   x:array:num
151 ]
152 +error: container 'foo' cannot determine size of element 'x'
153 
154 :(before "End Load Container Element Definition")
155 {
156   const type_tree* type = info.elements.back().type;
157   if (type && type->atom && type->name == "array") {
158     raise << "container '" << name << "' doesn't specify type of array elements for '" << info.elements.back().name << "'\n" << end();
159     continue;
160   }
161   if (type && !type->atom && type->left->atom && type->left->name == "array") {
162     if (!type->right) {
163       raise << "container '" << name << "' doesn't specify type of array elements for '" << info.elements.back().name << "'\n" << end();
164       continue;
165     }
166     if (!type->right->right || !is_integer(type->right->right->left->name)) {  // array has no length
167       raise << "container '" << name << "' cannot determine size of element '" << info.elements.back().name << "'\n" << end();
168       continue;
169     }
170   }
171 }
172 
173 //: disable the size mismatch check for 'merge' instructions since containers
174 //: can contain arrays, and since we already do plenty of checking for them
175 :(before "End size_mismatch(x) Special-cases")
176 if (current_call().running_step_index < SIZE(get(Recipe, current_call().running_recipe).steps)
177     && current_instruction().operation == MERGE) {
178   return false;
179 }
180 
181 :(scenario merge_static_array_into_container)
182 container foo [
183   x:num
184   y:array:num:3
185 ]
186 def main [
187   1:array:num:3 <- create-array
188   10:foo <- merge 34, 1:array:num:3
189 ]
190 # no errors
191 
192 :(scenario code_inside_container)
193 % Hide_errors = true;
194 container card [
195   rank:num <- next-ingredient
196 ]
197 def foo [
198   1:card <- merge 3
199   2:num <- get 1:card rank:offset
200 ]
201 # shouldn't die
202 
203 //:: To access elements of an array, use 'index'
204 
205 :(scenario index)
206 def main [
207   1:array:num:3 <- create-array
208   2:num <- copy 14
209   3:num <- copy 15
210   4:num <- copy 16
211   10:num <- index 1:array:num:3, 0/index  # the index must be a non-negative whole number
212 ]
213 +mem: storing 14 in location 10
214 
215 :(scenario index_compound_element)
216 def main [
217   {1: (array (address number) 3)} <- create-array
218   # skip alloc id
219   3:num <- copy 14
220   # skip alloc id
221   5:num <- copy 15
222   # skip alloc id
223   7:num <- copy 16
224   10:address:num <- index {1: (array (address number) 3)}, 0
225 ]
226 # skip alloc id
227 +mem: storing 14 in location 11
228 
229 :(scenario index_direct_offset)
230 def main [
231   1:array:num:3 <- create-array
232   2:num <- copy 14
233   3:num <- copy 15
234   4:num <- copy 16
235   10:num <- copy 0
236   20:num <- index 1:array:num, 10:num
237 ]
238 +mem: storing 14 in location 20
239 
240 :(before "End Primitive Recipe Declarations")
241 INDEX,
242 :(before "End Primitive Recipe Numbers")
243 put(Recipe_ordinal, "index", INDEX);
244 :(before "End Primitive Recipe Checks")
245 case INDEX: {
246   if (SIZE(inst.ingredients) != 2) {
247     raise << maybe(get(Recipe, r).name) << "'index' expects exactly 2 ingredients in '" << to_original_string(inst) << "'\n" << end();
248     break;
249   }
250   reagent/*copy*/ base = inst.ingredients.at(0);
251   // Update INDEX base in Check
252   if (!is_mu_array(base)) {
253     raise << maybe(get(Recipe, r).name) << "'index' on a non-array '" << base.original_string << "'\n" << end();
254     break;
255   }
256   reagent/*copy*/ index = inst.ingredients.at(1);
257   // Update INDEX index in Check
258   if (!is_mu_number(index)) {
259     raise << maybe(get(Recipe, r).name) << "second ingredient of 'index' should be a number, but got '" << index.original_string << "'\n" << end();
260     break;
261   }
262   if (instpre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
<!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 - 035labels.cc</title>
<meta name="Generator" content="Vim/8.1">
<meta name="plugin-version" content="vim8.1_v1">
<meta name="syntax" content="cpp">
<meta name="settings" content="number_lines,use_css,pre_wrap,no_foldcolumn,expand_tabs,line_ids,prevent_copy=">
<meta name="colorscheme" content="minimal-light">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #000000; background-color: #c6c6c6; }
body { font-size:12pt; font-family: monospace; color: #000000; background-color: #c6c6c6; }
a { color:inherit; }
* { font-size:12pt; font-size: 1em; }
.LineNr { }
.Constant { color: #008787; }
.Comment { color: #005faf; }
.Normal { color: #000000; background-color: #c6c6c6; padding-bottom: 1px; }
.Special { color: #d70000; }
.Identifier { color: #af5f00; }
.Delimiter { color: #c000c0; }
.cSpecial { color: #008000; }
-->
</style>

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

/* function to open any folds containing a jumped-to line before jumping to it */
function JumpToLine()
{
  var lineNum;
  lineNum = window.location.hash;
  lineNum = lineNum.substr(1); /* strip off '#' */

  if (lineNum.indexOf('L') == -1) {
    lineNum = 'L'+lineNum;
  }
  var lineElem = document.getElementById(lineNum);
  /* Always jump to new location even if the line was hidden inside a fold, or
   * we corrected the raw number to a line ID.
   */
  if (lineElem) {
    lineElem.scrollIntoView(true);
  }
  return true;
}
if ('onhashchange' in window) {
  window.onhashchange = JumpToLine;
}

-->
</script>
</head>
<body onload='JumpToLine();'>
<a href='https://github.com/akkartik/mu/blob/master/035labels.cc'>https://github.com/akkartik/mu/blob/master/035labels.cc</a>
<pre id='vimCodeElement'>
<span id="L1" class="LineNr">  1 </span><span class="Comment">//: Labels are defined by ending names with a ':'. This layer will compute</span>
<span id="L2" class="LineNr">  2 </span><span class="Comment">//: displacements for labels, and compute the offset for instructions using them.</span>
<span id="L3" class="LineNr">  3 </span><span class="Comment">//:</span>
<span id="L4" class="LineNr">  4 </span><span class="Comment">//: We won't check this, but our convention will be that jump targets will</span>
<span id="L5" class="LineNr">  5 </span><span class="Comment">//: start with a '$', while functions will not. Function names will never be</span>
<span id="L6" class="LineNr">  6 </span><span class="Comment">//: jumped to, and jump targets will never be called.</span>
<span id="L7" class="LineNr">  7 </span>
<span id="L8" class="LineNr">  8 </span><span class="Comment">//: We're introducing non-number names for the first time, so it's worth</span>
<span id="L9" class="LineNr">  9 </span><span class="Comment">//: laying down some ground rules all transforms will follow, so things don't</span>
<span id="L10" class="LineNr"> 10 </span><span class="Comment">//: get too confusing:</span>
<span id="L11" class="LineNr"> 11 </span><span class="Comment">//:   - if it starts with a digit, it's treated as a number. If it can't be</span>
<span id="L12" class="LineNr"> 12 </span><span class="Comment">//:     parsed as hex it will raise an error.</span>
<span id="L13" class="LineNr"> 13 </span><span class="Comment">//:   - if it starts with '-' it's treated as a number.</span>
<span id="L14" class="LineNr"> 14 </span><span class="Comment">//:   - if it starts with '0x' it's treated as a number.</span>
<span id="L15" class="LineNr"> 15 </span><span class="Comment">//:   - if it's two characters long, it can't be a name. Either it's a hex</span>
<span id="L16" class="LineNr"> 16 </span><span class="Comment">//:     byte, or it raises an error.</span>
<span id="L17" class="LineNr"> 17 </span><span class="Comment">//: That's it. Names can start with any non-digit that isn't a dash. They can</span>
<span id="L18" class="LineNr"> 18 </span><span class="Comment">//: be a single character long. 'a' is not a hex number, it's a variable.</span>
<span id="L19" class="LineNr"> 19 </span><span class="Comment">//: Later layers may add more conventions partitioning the space of names. But</span>
<span id="L20" class="LineNr"> 20 </span><span class="Comment">//: the above rules will remain inviolate.</span>
<span id="L21" class="LineNr"> 21 </span>
<span id="L22" class="LineNr"> 22 </span><span class="Comment">//: One special label is 'Entry', the address to start running the program at.</span>
<span id="L23" class="LineNr"> 23 </span><span class="Comment">//: It can be non-unique; the last declaration overrides earlier ones.</span>
<span id="L24" class="LineNr"> 24 </span><span class="Comment">//: It must exist in a program. Otherwise we don't know where to start running</span>
<span id="L25" class="LineNr"> 25 </span><span class="Comment">//: programs.</span>
<span id="L26" class="LineNr"> 26 </span>
<span id="L27" class="LineNr"> 27 </span><span class="Normal">void</span> <a href='035labels.cc.html#L27'>test_Entry_label</a><span class="Delimiter">()</span> <span class="Delimiter">{</span>
<span id="L28" class="LineNr"> 28 </span>  <a href='011run.cc.html#L83'>run</a><span class="Delimiter">(</span>
<span id="L29" class="LineNr"> 29 </span>      <span class="Constant">&quot;== code 0x1\n&quot;</span>
<span id="L30" class="LineNr"> 30 </span>      <span class="Constant">&quot;05 0x0d0c0b0a/imm32\n&quot;</span>
<span id="L31" class="LineNr"> 31 </span>      <span class="Constant">&quot;Entry:\n&quot;</span>
<span id="L32" class="LineNr"> 32 </span>      <span class="Constant">&quot;05 0x0d0c0b0a/imm32\n&quot;</span>
<span id="L33" class="LineNr"> 33 </span>  <span class="Delimiter">);</span>
<span id="L34" class="LineNr"> 34 </span>  <a href='003trace.cc.html#L290'>CHECK_TRACE_CONTENTS</a><span class="Delimiter">(</span>
<span id="L35" class="LineNr"> 35 </span>      <span class="Constant">&quot;run: 0x00000006 opcode: 05\n&quot;</span>
<span id="L36" class="LineNr"> 36 </span>  <span class="Delimiter">);</span>
<span id="L37" class="LineNr"> 37 </span>  <a href='003trace.cc.html#L292'>CHECK_TRACE_DOESNT_CONTAIN</a><span class="Delimiter">(</span><span class="Constant">&quot;run: 0x00000001 opcode: 05&quot;</span><span class="Delimiter">);</span>
<span id="L38" class="LineNr"> 38 </span><span class="Delimiter">}</span>
<span id="L39" class="LineNr"> 39 </span>
<span id="L40" class="LineNr"> 40 </span><span class="Delimiter">:(before &quot;End looks_like_hex_int(s) Detectors&quot;)</span>
<span id="L41" class="LineNr"> 41 </span><span class="Normal">if</span> <span class="Delimiter">(</span><a href='001help.cc.html#L164'>SIZE</a><span class="Delimiter">(</span>s<span class="Delimiter">)</span> == <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
<span id="L42" class="LineNr"> 42 </span>
<span id="L43" class="LineNr"> 43 </span><span class="Delimiter">:(code)</span>
<span id="L44" class="LineNr"> 44 </span><span class="Normal">void</span> <a href='035labels.cc.html#L44'>test_pack_immediate_ignores_single_byte_nondigit_operand</a><span class="Delimiter">()</span> <span class="Delimiter">{</span>
<span id="L45" class="LineNr"> 45 </span>  <span class="Special">Hide_errors</span> = <span class="Constant">true</span><span class="Delimiter">;</span>
<span id="L46" class="LineNr"> 46 </span>  transform<span class="Delimiter">(</span>
<span id="L47" class="LineNr"> 47 </span>      <span class="Constant">&quot;== code 0x1\n&quot;</span>
<span id="L48" class="LineNr"> 48 </span>      <span class="Constant">&quot;b9/copy  a/imm32\n&quot;</span>
<span id="L49" class="LineNr"> 49 </span>  <span class="Delimiter">);</span>
<span id="L50" class="LineNr"> 50 </span>  <a href='003trace.cc.html#L290'>CHECK_TRACE_CONTENTS</a><span class="Delimiter">(</span>
<span id="L51" class="LineNr"> 51 </span>      <span class="Constant">&quot;transform: packing instruction 'b9/copy a/imm32'\n&quot;</span>
<span id="L52" class="LineNr"> 52 </span>      <span class="Comment">// no change (we're just not printing metadata to the trace)</span>
<span id="L53" class="LineNr"> 53 </span>      <span class="Constant">&quot;transform: instruction after packing: 'b9 a'\n&quot;</span>
<