summary refs log tree commit diff stats
path: root/compiler/pragmas.nim
Commit message (Expand)AuthorAgeFilesLines
* fixes testament compilationAraq2018-05-141-1/+1
|\
| * Support thread-local variables declared inside procs; fixes #7565Zahary Karadjov2018-05-071-1/+1
* | options.nim: no global variables anymoreAndreas Rumpf2018-05-131-15/+16
* | pragmas compiles againAndreas Rumpf2018-05-111-220/+224
|/
* .experimental can now be used to enable specific featuresAndreas Rumpf2018-04-241-5/+17
* remove dead code elimination option (#7669)Jacek Sieka2018-04-231-10/+4
* refactoring: make FileIndex a distinct type; make line information an uint16;...Andreas Rumpf2018-04-211-1/+1
* introduce nkTupleConstr AST node for unary tuple construction; breaking changeAndreas Rumpf2018-04-131-2/+2
* the 'deprecated' pragma for modules now supports an error messageAraq2018-04-061-2/+6
* C codegen: preparations for different seq and string implementationsAndreas Rumpf2018-04-031-1/+1
* further steps in implementing sink parameters; refs #7041Araq2018-03-301-3/+5
* User pragmas hide effect specs bug fix. Fixes #7216 (#7217)cooldome2018-02-271-15/+17
* custom pragmas: proper error handlingAndreas Rumpf2018-02-121-3/+4
* the .deprecated pragma for procs now supports a user-definable deprecation me...Andreas Rumpf2018-02-021-1/+4
* Fixes nimsuggest#78 (#7151)Yuriy Glukhov2018-01-291-9/+10
* Custom pragmas in procs bug fix (#7086)cooldome2018-01-181-1/+0
* Implement custom annotations (#6987)cooldome2018-01-091-40/+72
* Merge branch 'devel' of github.com:nim-lang/Nim into develAndreas Rumpf2017-12-271-0/+2
|\
| * Allow noreturn procs with void type (#6973)cooldome2017-12-271-1/+1
| * Implement language feature #6885 (#6954)cooldome2017-12-241-0/+2
* | introduce 'core' as an alias for 'compilerproc'Andreas Rumpf2017-12-271-5/+5
|/
* newruntime: removed old way of writing destructorsAraq2017-11-281-5/+1
* added a warning that the .deprecate statement is unreliable for routinesAndreas Rumpf2017-11-211-1/+2
* implemented undocumented '.liftLocals' featureAndreas Rumpf2017-11-021-1/+10
* deprecated unary '<'Andreas Rumpf2017-10-291-1/+1
* first implementation of package level types that allow forwarding across modu...Andreas Rumpf2017-10-281-2/+2
* backend preparations for incomplete/forwarded object typesAndreas Rumpf2017-10-281-1/+5
* distinguish between 'reorder' and 'noforward'Andreas Rumpf2017-07-261-4/+5
* fixes #5846Andreas Rumpf2017-06-291-2/+3
* proper error reporting for concepts and the introduction of the {.explain.} p...Zahary Karadjov2017-03-241-2/+4
* fixes #5529; don't merge type visibility flagsAraq2017-03-141-1/+1
* removed compiler internal list implementation (#5371)Arne Döring2017-02-221-19/+16
* Enabled explicitly unknown lock levels (#5409)Fabian Keller2017-02-201-1/+7
* new feature: .used pragma to suppress declared-but-not-used warningAraq2017-02-171-8/+12
* new name mangling rules for easier debuggingAndreas Rumpf2017-02-021-0/+1
* new name mangling scheme implementedAndreas Rumpf2017-02-021-2/+7
* fixes serious regression that was introduced in the handling of .compile pragmaAraq2017-01-281-2/+4
* .compile pragma supports patterns and actionsAraq2017-01-281-10/+22
* .compile pragma supports wildcardsAraq2017-01-271-4/+16
* implements {.gcsafe.} enforcement as a pragma blockAndreas Rumpf2017-01-181-4/+7
* fixes #3848Araq2016-12-301-1/+1
* Merge branch 'devel' into sighashesAraq2016-12-171-2/+16
|\
| * reworked emit pragma; fixes #4730Andreas Rumpf2016-12-171-2/+16
* | more tests workAraq2016-12-021-1/+4
|/
* fixes the regressions introduced by fix for #5076Araq2016-11-301-0/+1
* first version of the new memory tracking featureAndreas Rumpf2016-11-211-1/+2
* fixes #4088Andreas Rumpf2016-09-111-1/+3
* MergedAraq2016-08-271-30/+25
|\
| * fixes #4579Andreas Rumpf2016-08-231-30/+25
* | next steps in getting symbol files to work againAraq2016-08-161-0/+2
|/
">: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } .SalientComment { color: #00ffff; } .cSpecial { color: #008000; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } .Constant { color: #00a0a0; } .traceContains { color: #008000; } --> </style> <script type='text/javascript'> <!-- --> </script> </head> <body> <pre id='vimCodeElement'> <span class="Comment">//: Arrays contain a variable number of elements of the same type. Their value</span> <span class="Comment">//: starts with the length of the array.</span> <span class="Comment">//:</span> <span class="Comment">//: You can create arrays of containers, but containers can only contain</span> <span class="Comment">//: elements of a fixed size, so you can't create containers containing arrays.</span> <span class="Comment">//: Create containers containing addresses to arrays instead.</span> <span class="Comment">//: You can create arrays using 'create-array'.</span> <span class="Delimiter">:(scenario create_array)</span> recipe main [ <span class="Comment"># create an array occupying locations 1 (for the size) and 2-4 (for the elements)</span> <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> &lt;- </span>create-array ] <span class="traceContains">+run: creating array of size 4</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span> CREATE_ARRAY<span class="Delimiter">,</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span> Recipe_ordinal[<span class="Constant">&quot;create-array&quot;</span>] = CREATE_ARRAY<span class="Delimiter">;</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span> case CREATE_ARRAY: <span class="Delimiter">{</span> if <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> raise &lt;&lt; current_recipe_name <span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: 'create-array' needs one product and no ingredients but got '&quot;</span> &lt;&lt; current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> reagent product = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> if <span class="Delimiter">(</span>!is_mu_array<span class="Delimiter">(</span>product<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise &lt;&lt; current_recipe_name <span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: 'create-array' cannot create non-array &quot;</span> &lt;&lt; product<span class="Delimiter">.</span>original_string &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> long long int base_address = product<span class="Delimiter">.</span>value<span class="Delimiter">;</span> if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>product<span class="Delimiter">.</span>types<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise &lt;&lt; current_recipe_name <span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: create array of what? &quot;</span> &lt;&lt; current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">// 'create-array' will need to check properties rather than types</span> if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>product<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">)</span> &lt;= <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise &lt;&lt; current_recipe_name <span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: create array of what size? &quot;</span> &lt;&lt; current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> if <span class="Delimiter">(</span>!is_integer<span class="Delimiter">(</span>product<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> raise &lt;&lt; current_recipe_name <span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: 'create-array' product should specify size of array after its element type, but got &quot;</span> &lt;&lt; product<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">)</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> long long int array_size= to_integer<span class="Delimiter">(</span>product<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">));</span> <span class="Comment">// initialize array size, so that size_of will work</span> Memory[base_address] = array_size<span class="Delimiter">;</span> <span class="Comment">// in array elements</span> long long int size = size_of<span class="Delimiter">(</span>product<span class="Delimiter">);</span> <span class="Comment">// in locations</span> trace<span class="Delimiter">(</span><span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;creating array of size &quot;</span> &lt;&lt; size &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Comment">// initialize array</span> for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</span><span class="Delimiter">;</span> i &lt;= size_of<span class="Delimiter">(</span>product<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> Memory[base_address+i] = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">// dummy product; doesn't actually do anything</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>array_size<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(scenario copy_array)</span> <span class="Comment"># Arrays can be copied around with a single instruction just like numbers,</span> <span class="Comment"># no matter how large they are.</span> recipe main [ <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> &lt;- </span>create-array <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span> <span class="Constant">5</span>:array:number<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>:array:number:<span class="Constant">3</span> ] <span class="traceContains">+mem: storing 3 in location 5</span> <span class="traceContains">+mem: storing 14 in location 6</span> <span class="traceContains">+mem: storing 15 in location 7</span> <span class="traceContains">+mem: storing 16 in location 8</span> <span class="Delimiter">:(scenario copy_array_indirect)</span> recipe main [ <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> &lt;- </span>create-array <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span> <span class="Constant">5</span>:address:array:number<span class="Special"> &lt;- </span>copy <span class="Constant">1</span> <span class="Comment"># unsafe</span> <span class="Constant">6</span>:array:number<span class="Special"> &lt;- </span>copy *<span class="Constant">5</span>:address:array:number ] <span class="traceContains">+mem: storing 3 in location 6</span> <span class="traceContains">+mem: storing 14 in location 7</span> <span class="traceContains">+mem: storing 15 in location 8</span> <span class="traceContains">+mem: storing 16 in location 9</span> <span class="Delimiter">:(scenario stash_array)</span> recipe main [ <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> &lt;- </span>create-array <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span> stash [foo:]<span class="Delimiter">,</span> <span class="Constant">1</span>:array:number:<span class="Constant">3</span> ] <span class="traceContains">+app: foo: 3 14 15 16</span> <span class="Comment">//: disable the size mismatch check since the destination array need not be initialized</span> <span class="Delimiter">:(before &quot;End size_mismatch(x) Cases&quot;)</span> if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == Type_ordinal[<span class="Constant">&quot;array&quot;</span>]<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">:(before &quot;End size_of(reagent) Cases&quot;)</span> if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == Type_ordinal[<span class="Constant">&quot;array&quot;</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span> if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise &lt;&lt; current_recipe_name<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: '&quot;</span> &lt;&lt; r<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;' is an array of what?</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="Comment">// skip the 'array' type to get at the element type</span> <span class="Identifier">return</span> <span class="Constant">1</span> + Memory[r<span class="Delimiter">.</span>value]*size_of<span class="Delimiter">(</span>array_element<span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">));</span> <span class="Delimiter">}</span> <span class="SalientComment">//:: To access elements of an array, use 'index'</span> <span class="Delimiter">:(scenario index)</span> recipe main [ <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> &lt;- </span>create-array <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span> <span class="Constant">5</span>:number<span class="Special"> &lt;- </span>index <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">0</span> ] <span class="traceContains">+mem: storing 14 in location 5</span> <span class="Delimiter">:(scenario index_direct_offset)</span> recipe main [ <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> &lt;- </span>create-array <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span> <span class="Constant">5</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span> <span class="Constant">6</span>:number<span class="Special"> &lt;- </span>index <span class="Constant">1</span>:array:number<span class="Delimiter">,</span> <span class="Constant">5</span>:number ] <span class="traceContains">+mem: storing 14 in location 6</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span> INDEX<span class="Delimiter">,</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span> Recipe_ordinal[<span class="Constant">&quot;index&quot;</span>] = INDEX<span class="Delimiter">;</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span> case INDEX: <span class="Delimiter">{</span> if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<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; current_recipe_name<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: 'index' expects exactly 2 ingredients in '&quot;</span> &lt;&lt; current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> reagent base = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> if <span class="Delimiter">(</span>!is_mu_array<span class="Delimiter">(</span>base<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise &lt;&lt; current_recipe_name <span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: 'index' on a non-array &quot;</span> &lt;&lt; base<span class="Delimiter">.</span>original_string &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> long long int base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span> if <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise &lt;&lt; current_recipe_name<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: tried to access location 0 in '&quot;</span> &lt;&lt; current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> reagent offset = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">));</span> vector&lt;double&gt; offset_val<span class="Delimiter">(</span>read_memory<span class="Delimiter">(</span>offset<span class="Delimiter">));</span> vector&lt;type_ordinal&gt; element_type = array_element<span class="Delimiter">(</span>base<span class="Delimiter">.</span>types<span class="Delimiter">);</span> if <span class="Delimiter">(</span>offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> &lt; <span class="Constant">0</span> || offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> &gt;= Memory[base_address]<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise &lt;&lt; current_recipe_name<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: invalid index &quot;</span> &lt;&lt; offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> long long int src = base_address + <span class="Constant">1</span> + offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>*size_of<span class="Delimiter">(</span>element_type<span class="Delimiter">);</span> trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;address to copy is &quot;</span> &lt;&lt; src &lt;&lt; end<span class="Delimiter">();</span> trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;its type is &quot;</span> &lt;&lt; Type[element_type<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>]<span class="Delimiter">.</span>name &lt;&lt; end<span class="Delimiter">();</span> reagent tmp<span class="Delimiter">;</span> tmp<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>src<span class="Delimiter">);</span> copy<span class="Delimiter">(</span>element_type<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> element_type<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> inserter<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>types<span class="Delimiter">,</span> tmp<span class="Delimiter">.</span>types<span class="Delimiter">.</span>begin<span class="Delimiter">()));</span> products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>read_memory<span class="Delimiter">(</span>tmp<span class="Delimiter">));</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> vector&lt;type_ordinal&gt; array_element<span class="Delimiter">(</span>const vector&lt;type_ordinal&gt;&amp; types<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> vector&lt;type_ordinal&gt;<span class="Delimiter">(</span>++types<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> types<span class="Delimiter">.</span>end<span class="Delimiter">());</span> <span class="Delimiter">}</span> <span class="Delimiter">:(scenario index_indirect)</span> recipe main [ <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> &lt;- </span>create-array <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span> <span class="Constant">5</span>:address:array:number<span class="Special"> &lt;- </span>copy <span class="Constant">1</span> <span class="Constant">6</span>:number<span class="Special"> &lt;- </span>index *<span class="Constant">5</span>:address:array:number<span class="Delimiter">,</span> <span class="Constant">1</span> ] <span class="traceContains">+mem: storing 15 in location 6</span> <span class="Delimiter">:(scenario index_out_of_bounds)</span> <span class="Special">% Hide_warnings = true;</span> recipe main [ <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> &lt;- </span>create-array <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span> <span class="Constant">5</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span> <span class="Constant">6</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span> <span class="Constant">7</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span> <span class="Constant">8</span>:address:array:point<span class="Special"> &lt;- </span>copy <span class="Constant">1</span> index *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> <span class="Constant">4</span> <span class="Comment"># less than size of array in locations, but larger than its length in elements</span> ] <span class="traceContains">+warn: main: invalid index 4</span> <span class="Delimiter">:(scenario index_out_of_bounds_2)</span> <span class="Special">% Hide_warnings = true;</span> recipe main [ <span class="Constant">1</span>:array:point:<span class="Constant">3</span><span class="Special"> &lt;- </span>create-array <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span> <span class="Constant">5</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span> <span class="Constant">6</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span> <span class="Constant">7</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span> <span class="Constant">8</span>:address:array:point<span class="Special"> &lt;- </span>copy <span class="Constant">1</span> index *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> -<span class="Constant">1</span> ] <span class="traceContains">+warn: main: invalid index -1</span> <span class="SalientComment">//:: To write to elements of containers, you need their address.</span> <span class="Delimiter">:(scenario index_address)</span> recipe main [ <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> &lt;- </span>create-array <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span> <span class="Constant">5</span>:number<span class="Special"> &lt;- </span>index-address <span class="Constant">1</span>:array:number<span class="Delimiter">,</span> <span class="Constant">0</span> ] <span class="traceContains">+mem: storing 2 in location 5</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span> INDEX_ADDRESS<span class="Delimiter">,</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span> Recipe_ordinal[<span class="Constant">&quot;index-address&quot;</span>] = INDEX_ADDRESS<span class="Delimiter">;</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span> case INDEX_ADDRESS: <span class="Delimiter">{</span> if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<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; current_recipe_name<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: 'index-address' expects exactly 2 ingredients in '&quot;</span> &lt;&lt; current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> reagent base = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> if <span class="Delimiter">(</span>!is_mu_array<span class="Delimiter">(</span>base<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise &lt;&lt; current_recipe_name <span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: 'index-address' on a non-array &quot;</span> &lt;&lt; base<span class="Delimiter">.</span>original_string &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> long long int base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span> if <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise &lt;&lt; current_recipe_name<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: tried to access location 0 in '&quot;</span> &lt;&lt; current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> reagent offset = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">));</span> vector&lt;double&gt; offset_val<span class="Delimiter">(</span>read_memory<span class="Delimiter">(</span>offset<span class="Delimiter">));</span> vector&lt;type_ordinal&gt; element_type = array_element<span class="Delimiter">(</span>base<span class="Delimiter">.</span>types<span class="Delimiter">);</span> if <span class="Delimiter">(</span>offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> &lt; <span class="Constant">0</span> || offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> &gt;= Memory[base_address]<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise &lt;&lt; current_recipe_name<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: invalid index &quot;</span> &lt;&lt; offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> long long int result = base_address + <span class="Constant">1</span> + offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>*size_of<span class="Delimiter">(</span>element_type<span class="Delimiter">);</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(scenario index_address_out_of_bounds)</span> <span class="Special">% Hide_warnings = true;</span> recipe main [ <span class="Constant">1</span>:array:point:<span class="Constant">3</span><span class="Special"> &lt;- </span>create-array <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span> <span class="Constant">5</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span> <span class="Constant">6</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span> <span class="Constant">7</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span> <span class="Constant">8</span>:address:array:point<span class="Special"> &lt;- </span>copy <span class="Constant">1</span> <span class="Comment"># unsafe</span> index-address *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> <span class="Constant">4</span> <span class="Comment"># less than size of array in locations, but larger than its length in elements</span> ] <span class="traceContains">+warn: main: invalid index 4</span> <span class="Delimiter">:(scenario index_address_out_of_bounds_2)</span> <span class="Special">% Hide_warnings = true;</span> recipe main [ <span class="Constant">1</span>:array:point:<span class="Constant">3</span><span class="Special"> &lt;- </span>create-array <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span> <span class="Constant">5</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span> <span class="Constant">6</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span> <span class="Constant">7</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span> <span class="Constant">8</span>:address:array:point<span class="Special"> &lt;- </span>copy <span class="Constant">1</span> <span class="Comment"># unsafe</span> index-address *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> -<span class="Constant">1</span> ] <span class="traceContains">+warn: main: invalid index -1</span> <span class="SalientComment">//:: compute the length of an array</span> <span class="Delimiter">:(scenario array_length)</span> recipe main [ <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> &lt;- </span>create-array <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span> <span class="Constant">5</span>:number<span class="Special"> &lt;- </span>length <span class="Constant">1</span>:array:number:<span class="Constant">3</span> ] <span class="traceContains">+mem: storing 3 in location 5</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span> LENGTH<span class="Delimiter">,</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span> Recipe_ordinal[<span class="Constant">&quot;length&quot;</span>] = LENGTH<span class="Delimiter">;</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span> case LENGTH: <span class="Delimiter">{</span> if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise &lt;&lt; current_recipe_name<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: 'length' expects exactly 2 ingredients in '&quot;</span> &lt;&lt; current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> reagent x = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> if <span class="Delimiter">(</span>!is_mu_array<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise &lt;&lt; <span class="Constant">&quot;tried to calculate length of non-array &quot;</span> &lt;&lt; x<span class="Delimiter">.</span>original_string &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise &lt;&lt; current_recipe_name<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: tried to access location 0 in '&quot;</span> &lt;&lt; current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>Memory[x<span class="Delimiter">.</span>value]<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">//: optimization: none of the instructions in this layer use 'ingredients' so</span> <span class="Comment">//: stop copying potentially huge arrays into it.</span> <span class="Delimiter">:(before &quot;End should_copy_ingredients Special-cases&quot;)</span> recipe_ordinal r = current_instruction<span class="Delimiter">().</span>operation<span class="Delimiter">;</span> if <span class="Delimiter">(</span>r == CREATE_ARRAY || r == INDEX || r == INDEX_ADDRESS || r == LENGTH<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> </pre> </body> </html> <!-- vim: set foldmethod=manual : -->