mirror of
https://github.com/ganelson/inform.git
synced 2024-07-01 06:24:58 +03:00
Completed Inform 6 generator
This commit is contained in:
parent
f779c3b0d9
commit
5452ca63e8
|
@ -296,7 +296,7 @@ everything else.
|
|||
<span class="definition-keyword">define</span> <span class="constant-syntax">PRINTING_LTM</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
|
||||
</pre>
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CodeGen::lt_mode</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">CodeGen::lt_mode</span></span>:<br/>Inform 6 Code - <a href="4-i6c2.html#SP6_8">§6.8</a><br/>C Input-Output Model - <a href="5-cim.html#SP2">§2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m</span><span class="plain-syntax">) {</span>
|
||||
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">CodeGen::lt_mode</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">CodeGen::lt_mode</span></span>:<br/>Inform 6 Code - <a href="4-i6c2.html#SP6_9">§6.9</a><br/>C Input-Output Model - <a href="5-cim.html#SP2">§2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m</span><span class="plain-syntax">) {</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">gen</span><span class="plain-syntax">-></span><span class="element-syntax">literal_text_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">m</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax">}</span>
|
||||
</pre>
|
||||
|
|
|
@ -73,7 +73,7 @@ function togglePopup(material_id) {
|
|||
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inter Modules</a></li><li><a href="index.html">final</a></li><li><a href="index.html#4">Chapter 4: Inform 6</a></li><li><b>Inform 6 Code</b></li></ul></div>
|
||||
<p class="purpose">To generate I6 routines of imperative code.</p>
|
||||
|
||||
<ul class="toc"><li><a href="4-i6c2.html#SP2">§2. Functions</a></li><li><a href="4-i6c2.html#SP3">§3. Labels</a></li><li><a href="4-i6c2.html#SP4">§4. Function invocations</a></li><li><a href="4-i6c2.html#SP5">§5. Assembly language</a></li><li><a href="4-i6c2.html#SP6">§6. Primitives</a></li><li><a href="4-i6c2.html#SP9">§9. A few resources</a></li></ul><hr class="tocbar">
|
||||
<ul class="toc"><li><a href="4-i6c2.html#SP2">§2. Functions</a></li><li><a href="4-i6c2.html#SP3">§3. Labels</a></li><li><a href="4-i6c2.html#SP4">§4. Function invocations</a></li><li><a href="4-i6c2.html#SP5">§5. Assembly language</a></li><li><a href="4-i6c2.html#SP6">§6. Primitives</a></li><li><a href="4-i6c2.html#SP7">§7. Support code for property accesses</a></li><li><a href="4-i6c2.html#SP9">§9. The final functions</a></li></ul><hr class="tocbar">
|
||||
|
||||
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§1. </b></p>
|
||||
|
||||
|
@ -354,10 +354,11 @@ As a dodge, we use the Inform 6 statement <span class="extract"><span class="ext
|
|||
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-i6c2.html#SP6_2" class="named-paragraph-link"><span class="named-paragraph">Storing or otherwise changing values</span><span class="named-paragraph-number">6.2</span></a></span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-i6c2.html#SP6_5" class="named-paragraph-link"><span class="named-paragraph">VM stack access</span><span class="named-paragraph-number">6.5</span></a></span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-i6c2.html#SP6_6" class="named-paragraph-link"><span class="named-paragraph">Control structures</span><span class="named-paragraph-number">6.6</span></a></span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-i6c2.html#SP6_7" class="named-paragraph-link"><span class="named-paragraph">Indirect function or method calls</span><span class="named-paragraph-number">6.7</span></a></span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-i6c2.html#SP6_7" class="named-paragraph-link"><span class="named-paragraph">Indirect function calls</span><span class="named-paragraph-number">6.7</span></a></span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-i6c2.html#SP6_8" class="named-paragraph-link"><span class="named-paragraph">Method calls</span><span class="named-paragraph-number">6.8</span></a></span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-i6c2.html#SP6_3" class="named-paragraph-link"><span class="named-paragraph">Property value access</span><span class="named-paragraph-number">6.3</span></a></span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-i6c2.html#SP6_8" class="named-paragraph-link"><span class="named-paragraph">Textual output</span><span class="named-paragraph-number">6.8</span></a></span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-i6c2.html#SP6_9" class="named-paragraph-link"><span class="named-paragraph">The VM object tree</span><span class="named-paragraph-number">6.9</span></a></span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-i6c2.html#SP6_9" class="named-paragraph-link"><span class="named-paragraph">Textual output</span><span class="named-paragraph-number">6.9</span></a></span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-i6c2.html#SP6_10" class="named-paragraph-link"><span class="named-paragraph">The VM object tree</span><span class="named-paragraph-number">6.10</span></a></span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">STDERR</span><span class="plain-syntax">, </span><span class="string-syntax">"Unimplemented primitive is '%S'\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">prim_name</span><span class="plain-syntax">-></span><span class="identifier-syntax">symbol_name</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"unimplemented prim"</span><span class="plain-syntax">);</span>
|
||||
|
@ -474,9 +475,12 @@ for example, be a global variable, or a memory location.
|
|||
</p>
|
||||
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ref</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InterTree::first_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Inter::Reference::node_is_ref_to</span><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">-></span><span class="element-syntax">from</span><span class="plain-syntax">, </span><span class="identifier-syntax">ref</span><span class="plain-syntax">, </span><span class="identifier-syntax">PROPERTYVALUE_BIP</span><span class="plain-syntax">)) &&</span>
|
||||
<span class="plain-syntax"> (</span><a href="4-i6c2.html#SP8" class="function-link"><span class="function-syntax">I6TargetCode::pval_case</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ref</span><span class="plain-syntax">) != </span><span class="constant-syntax">I6G_CAN_PROVE_IS_OBJ_PROPERTY</span><span class="plain-syntax">)) {</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">storage_ref</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InterTree::first_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">storage_ref</span><span class="plain-syntax">-></span><span class="identifier-syntax">W</span><span class="plain-syntax">.</span><span class="identifier-syntax">data</span><span class="plain-syntax">[0] == </span><span class="identifier-syntax">REFERENCE_IST</span><span class="plain-syntax">)</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">storage_ref</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InterTree::first_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">storage_ref</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Inter::Reference::node_is_ref_to</span><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">-></span><span class="element-syntax">from</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterTree::first_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">),</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">PROPERTYVALUE_BIP</span><span class="plain-syntax">)) &&</span>
|
||||
<span class="plain-syntax"> (</span><a href="4-i6c2.html#SP8" class="function-link"><span class="function-syntax">I6TargetCode::pval_case</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">storage_ref</span><span class="plain-syntax">) != </span><span class="constant-syntax">I6G_CAN_PROVE_IS_OBJ_PROPERTY</span><span class="plain-syntax">)) {</span>
|
||||
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-i6c2.html#SP6_2_1_2" class="named-paragraph-link"><span class="named-paragraph">Alter a property value</span><span class="named-paragraph-number">6.2.1.2</span></a></span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
||||
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-i6c2.html#SP6_2_1_1" class="named-paragraph-link"><span class="named-paragraph">Alter some other storage</span><span class="named-paragraph-number">6.2.1.1</span></a></span><span class="plain-syntax">;</span>
|
||||
|
@ -489,6 +493,12 @@ its variable name). For example, the memory location <span class="extract"><span
|
|||
or can have <span class="extract"><span class="extract-syntax">++</span></span> or <span class="extract"><span class="extract-syntax">--</span></span> applied to it in I6.
|
||||
</p>
|
||||
|
||||
<p class="commentary">Note that this case even includes some property values: if we can see that <span class="extract"><span class="extract-syntax">P</span></span>
|
||||
is the explicit name of a property we are storing in a VM-property, then we can
|
||||
use <span class="extract"><span class="extract-syntax">O.P</span></span> as an Inform 6 lvalue, and all is well, and we then end up with code
|
||||
such as <span class="extract"><span class="extract-syntax">++(O.P)</span></span>.
|
||||
</p>
|
||||
|
||||
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Alter some other storage</span><span class="named-paragraph-number">6.2.1.1</span></span><span class="comment-syntax"> =</span>
|
||||
</p>
|
||||
|
||||
|
@ -504,16 +514,18 @@ or can have <span class="extract"><span class="extract-syntax">++</span></span>
|
|||
<span class="plain-syntax"> }</span>
|
||||
</pre>
|
||||
<ul class="endnotetexts"><li>This code is used in <a href="4-i6c2.html#SP6_2_1">§6.2.1</a>.</li></ul>
|
||||
<p class="commentary firstcommentary"><a id="SP6_2_1_2" class="paragraph-anchor"></a><b>§6.2.1.2. </b>Property values are trickier: they aren't lvalues in Inform 6. (Remember,
|
||||
an I7-level property is a pointer to a small metadata array: it's not the same
|
||||
thing as a VM-property. We cannot compile an I6 assignment to <span class="extract"><span class="extract-syntax">O.P</span></span> given that
|
||||
<span class="extract"><span class="extract-syntax">P</span></span> is actually an array, and anyway, what if <span class="extract"><span class="extract-syntax">P</span></span> is stored as a VM-attribute?)
|
||||
<p class="commentary firstcommentary"><a id="SP6_2_1_2" class="paragraph-anchor"></a><b>§6.2.1.2. </b>But not all property values can be written as Inform 6 lvalues. If the I7
|
||||
property P is being stored as a VM-attribute A, then there is no lvalue which
|
||||
expresses the value of A for an object O: instead one must use <span class="extract"><span class="extract-syntax">give O A</span></span> to
|
||||
set it, <span class="extract"><span class="extract-syntax">give O ~A</span></span> to unset it, and <span class="extract"><span class="extract-syntax">(O has A)</span></span> to test it. And there will
|
||||
also be cases where P cannot be identified at compile-time, so that we have no
|
||||
way to know whether it will be stored as a VM-attribute or not.
|
||||
</p>
|
||||
|
||||
<p class="commentary">In fact, then, we will compile an attempt to store or modify a property value
|
||||
either as a <span class="extract"><span class="extract-syntax">give</span></span> statement — if we can prove at compile time that the property
|
||||
is stored in a VM-attribute — or else as a function call to a general-purpose
|
||||
function called <span class="extract"><span class="extract-syntax">_final_write_pval</span></span>.
|
||||
<p class="commentary">To handle these two cases, then, we will compile an attempt to store or modify
|
||||
a property value either as a <span class="extract"><span class="extract-syntax">give</span></span> statement — if we can prove P is being
|
||||
stored in a VM-attribute — or else as a function call to a general-purpose
|
||||
function called <span class="extract"><span class="extract-syntax">_final_change_property</span></span>.
|
||||
</p>
|
||||
|
||||
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Alter a property value</span><span class="named-paragraph-number">6.2.1.2</span></span><span class="comment-syntax"> =</span>
|
||||
|
@ -529,32 +541,34 @@ function called <span class="extract"><span class="extract-syntax">_final_write_
|
|||
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">val1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">val2</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="identifier-syntax">set</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> }</span>
|
||||
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">storage_ref</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InterTree::first_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">storage_ref</span><span class="plain-syntax">-></span><span class="identifier-syntax">W</span><span class="plain-syntax">.</span><span class="identifier-syntax">data</span><span class="plain-syntax">[0] == </span><span class="identifier-syntax">REFERENCE_IST</span><span class="plain-syntax">) </span><span class="identifier-syntax">storage_ref</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InterTree::first_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">storage_ref</span><span class="plain-syntax">);</span>
|
||||
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><a href="4-i6c2.html#SP8" class="function-link"><span class="function-syntax">I6TargetCode::pval_case</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ref</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">I6G_CAN_PROVE_IS_OBJ_ATTRIBUTE</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">set</span><span class="plain-syntax"> == </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">)) {</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><a href="4-i6c2.html#SP8" class="function-link"><span class="function-syntax">I6TargetCode::pval_case</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">storage_ref</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">I6G_CAN_PROVE_IS_OBJ_ATTRIBUTE</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">bip</span><span class="plain-syntax"> == </span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">set</span><span class="plain-syntax"> == </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">)) {</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"give "</span><span class="plain-syntax">); </span><a href="2-vnl.html#SP3" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterTree::second_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">storage_ref</span><span class="plain-syntax">));</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" %S"</span><span class="plain-syntax">, </span><a href="4-i6c2.html#SP7" class="function-link"><span class="function-syntax">I6TargetCode::inner_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">storage_ref</span><span class="plain-syntax">));</span>
|
||||
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">I6G_CAN_PROVE_IS_OBJ_ATTRIBUTE</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">set</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" %S"</span><span class="plain-syntax">, </span><a href="4-i6c2.html#SP7" class="function-link"><span class="function-syntax">I6TargetCode::inner_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterTree::third_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">storage_ref</span><span class="plain-syntax">)));</span>
|
||||
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">I6G_CAN_PROVE_IS_OBJ_ATTRIBUTE</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">bip</span><span class="plain-syntax"> == </span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">set</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"give "</span><span class="plain-syntax">); </span><a href="2-vnl.html#SP3" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterTree::second_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">storage_ref</span><span class="plain-syntax">));</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" ~%S"</span><span class="plain-syntax">, </span><a href="4-i6c2.html#SP7" class="function-link"><span class="function-syntax">I6TargetCode::inner_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">storage_ref</span><span class="plain-syntax">));</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" ~%S"</span><span class="plain-syntax">, </span><a href="4-i6c2.html#SP7" class="function-link"><span class="function-syntax">I6TargetCode::inner_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterTree::third_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">storage_ref</span><span class="plain-syntax">)));</span>
|
||||
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"(_final_write_pval("</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bip</span><span class="plain-syntax">) {</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">STORE_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"_final_store_property"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PREINCREMENT_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"_final_preinc_property"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">POSTINCREMENT_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"_final_postinc_property"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PREDECREMENT_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"_final_predec_property"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">POSTDECREMENT_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"_final_postdec_property"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SETBIT_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"_final_setbit_property"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CLEARBIT_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"_final_clearbit_property"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> }</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><a href="2-vnl.html#SP3" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterTree::first_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">storage_ref</span><span class="plain-syntax">));</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><a href="2-vnl.html#SP3" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterTree::second_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">storage_ref</span><span class="plain-syntax">));</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><a href="2-vnl.html#SP3" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterTree::third_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">storage_ref</span><span class="plain-syntax">));</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bip</span><span class="plain-syntax">) {</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">STORE_BIP:</span><span class="plain-syntax"> </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", i7_lvalue_SET"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PREINCREMENT_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"0, i7_lvalue_PREINC"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">POSTINCREMENT_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"0, i7_lvalue_POSTINC"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PREDECREMENT_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"0, i7_lvalue_PREDEC"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">POSTDECREMENT_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"0, i7_lvalue_POSTDEC"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SETBIT_BIP:</span><span class="plain-syntax"> </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", i7_lvalue_SETBIT"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CLEARBIT_BIP:</span><span class="plain-syntax"> </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", i7_lvalue_CLEARBIT"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">STORE_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SETBIT_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CLEARBIT_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> }</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"))"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> }</span>
|
||||
|
@ -574,30 +588,33 @@ what is definitely a VM-object. This optimisation results in faster code.
|
|||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PROPERTYEXISTS_BIP:</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">I6_GEN_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">value_ranges_needed</span><span class="plain-syntax">) = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">I6_GEN_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">value_property_holders_needed</span><span class="plain-syntax">) = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"(_final_provides("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"(_final_propertyexists("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="constant-syntax">VNODE_3C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"))"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PROPERTYARRAY_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"(_final_read_paddr("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PROPERTYARRAY_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"(_final_propertyarray("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_3C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"))"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PROPERTYLENGTH_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"(_final_read_plen("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PROPERTYLENGTH_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"(_final_propertylength("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_3C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"))"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PROPERTYVALUE_BIP:</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PROPERTYVALUE_BIP:</span><span class="plain-syntax"> {</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">KP</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InterTree::first_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OP</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InterTree::second_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PP</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InterTree::third_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><a href="4-i6c2.html#SP8" class="function-link"><span class="function-syntax">I6TargetCode::pval_case</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">)) {</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">I6G_CAN_PROVE_IS_OBJ_ATTRIBUTE:</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" has %S"</span><span class="plain-syntax">, </span><a href="4-i6c2.html#SP7" class="function-link"><span class="function-syntax">I6TargetCode::inner_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">)); </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" has %S"</span><span class="plain-syntax">, </span><a href="4-i6c2.html#SP7" class="function-link"><span class="function-syntax">I6TargetCode::inner_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">PP</span><span class="plain-syntax">)); </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">I6G_CAN_PROVE_IS_OBJ_PROPERTY:</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">".%S"</span><span class="plain-syntax">, </span><a href="4-i6c2.html#SP7" class="function-link"><span class="function-syntax">I6TargetCode::inner_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">)); </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">".%S"</span><span class="plain-syntax">, </span><a href="4-i6c2.html#SP7" class="function-link"><span class="function-syntax">I6TargetCode::inner_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">PP</span><span class="plain-syntax">)); </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">I6G_CANNOT_PROVE:</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">I6_GEN_DATA</span><span class="plain-syntax">(</span><span class="identifier-syntax">value_property_holders_needed</span><span class="plain-syntax">) = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><a href="4-i6c2.html#SP6_4" class="function-link"><span class="function-syntax">I6TargetCode::eval_property_list</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">InterTree::first_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">),</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">InterTree::second_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">), </span><span class="identifier-syntax">InterTree::third_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">), </span><span class="constant-syntax">0</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><a href="4-i6c2.html#SP6_4" class="function-link"><span class="function-syntax">I6TargetCode::eval_property_list</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">KP</span><span class="plain-syntax">, </span><span class="identifier-syntax">OP</span><span class="plain-syntax">, </span><span class="identifier-syntax">PP</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> }</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> }</span>
|
||||
</pre>
|
||||
<ul class="endnotetexts"><li>This code is used in <a href="4-i6c2.html#SP6">§6</a>.</li></ul>
|
||||
<p class="commentary firstcommentary"><a id="SP6_4" class="paragraph-anchor"></a><b>§6.4. </b>In the most general case of <span class="extract"><span class="extract-syntax">!propertyvalue</span></span>, we will end up calling the function
|
||||
<span class="extract"><span class="extract-syntax">_final_read_pval</span></span>. But we don't do so right away because, annoyingly, <span class="extract"><span class="extract-syntax">!propertyvalue</span></span>
|
||||
<span class="extract"><span class="extract-syntax">_final_propertyvalue</span></span>. But we don't do so right away because, annoyingly, <span class="extract"><span class="extract-syntax">!propertyvalue</span></span>
|
||||
can have <span class="extract"><span class="extract-syntax">!alternative</span></span> children supplied. We might find this, for example:
|
||||
</p>
|
||||
|
||||
|
@ -643,12 +660,12 @@ is evaluated only once — in case there are side-effects of the evaluation.
|
|||
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><a href="4-i6c2.html#SP8" class="function-link"><span class="function-syntax">I6TargetCode::pval_case_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y</span><span class="plain-syntax">)) {</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">I6G_CAN_PROVE_IS_OBJ_ATTRIBUTE:</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">); </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">X</span><span class="plain-syntax">) </span><a href="2-vnl.html#SP3" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">X</span><span class="plain-syntax">); </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"or_tmp_var"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" has %S"</span><span class="plain-syntax">, </span><a href="4-i6c2.html#SP7" class="function-link"><span class="function-syntax">I6TargetCode::inner_name_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y</span><span class="plain-syntax">)); </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" has %S"</span><span class="plain-syntax">, </span><a href="4-i6c2.html#SP7" class="function-link"><span class="function-syntax">I6TargetCode::inner_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y</span><span class="plain-syntax">)); </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">I6G_CAN_PROVE_IS_OBJ_PROPERTY:</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">); </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">X</span><span class="plain-syntax">) </span><a href="2-vnl.html#SP3" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">X</span><span class="plain-syntax">); </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"or_tmp_var"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">".%S"</span><span class="plain-syntax">, </span><a href="4-i6c2.html#SP7" class="function-link"><span class="function-syntax">I6TargetCode::inner_name_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y</span><span class="plain-syntax">)); </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">".%S"</span><span class="plain-syntax">, </span><a href="4-i6c2.html#SP7" class="function-link"><span class="function-syntax">I6TargetCode::inner_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y</span><span class="plain-syntax">)); </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">I6G_CANNOT_PROVE:</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"_final_read_pval("</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"_final_propertyvalue("</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><a href="2-vnl.html#SP3" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">X</span><span class="plain-syntax">) </span><a href="2-vnl.html#SP3" class="function-link"><span class="function-syntax">Vanilla::node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">X</span><span class="plain-syntax">); </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"or_tmp_var"</span><span class="plain-syntax">);</span>
|
||||
|
@ -847,29 +864,43 @@ is evaluated only once — in case there are side-effects of the evaluation.
|
|||
<span class="plain-syntax"> </span><span class="identifier-syntax">suppress_terminal_semicolon</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
|
||||
</pre>
|
||||
<ul class="endnotetexts"><li>This code is used in <a href="4-i6c2.html#SP6_6">§6.6</a>.</li></ul>
|
||||
<p class="commentary firstcommentary"><a id="SP6_7" class="paragraph-anchor"></a><b>§6.7. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Indirect function or method calls</span><span class="named-paragraph-number">6.7</span></span><span class="comment-syntax"> =</span>
|
||||
<p class="commentary firstcommentary"><a id="SP6_7" class="paragraph-anchor"></a><b>§6.7. </b>In Inform 6, as in C, a function which returns a value can be called in a void
|
||||
context (in which case its return value is thrown away); the syntax for calling
|
||||
a void function is identical to that for calling a value-returning function, so
|
||||
we can treat <span class="extract"><span class="extract-syntax">INDIRECT0V_BIP</span></span> as the same as <span class="extract"><span class="extract-syntax">INDIRECT0_BIP</span></span>, and so on.
|
||||
</p>
|
||||
|
||||
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Indirect function calls</span><span class="named-paragraph-number">6.7</span></span><span class="comment-syntax"> =</span>
|
||||
</p>
|
||||
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT0_BIP:</span><span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT0V_BIP:</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")()"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT1_BIP:</span><span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT1V_BIP:</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT2_BIP:</span><span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT2V_BIP:</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_3C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT3_BIP:</span><span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT3V_BIP:</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_3C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="constant-syntax">VNODE_4C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT4_BIP:</span><span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT4V_BIP:</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_3C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="constant-syntax">VNODE_4C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_5C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT5_BIP:</span><span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT5V_BIP:</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_3C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="constant-syntax">VNODE_4C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_5C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_6C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EXTERNALCALL_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"external calls impossible in Inform 6"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
</pre>
|
||||
<ul class="endnotetexts"><li>This code is used in <a href="4-i6c2.html#SP6">§6</a>.</li></ul>
|
||||
<p class="commentary firstcommentary"><a id="SP6_8" class="paragraph-anchor"></a><b>§6.8. </b>Message calls are handled with functions (see below) in case the user is trying
|
||||
to send a message to a property stored in an attribute, or something like that.
|
||||
</p>
|
||||
|
||||
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Method calls</span><span class="named-paragraph-number">6.8</span></span><span class="comment-syntax"> =</span>
|
||||
</p>
|
||||
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT0_BIP:</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT0V_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")()"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT1_BIP:</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT1V_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")("</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT2_BIP:</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT2V_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")("</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_3C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT3_BIP:</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT3V_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")("</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_3C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_4C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT4_BIP:</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT4V_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")("</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_3C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_4C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="constant-syntax">VNODE_5C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT5_BIP:</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INDIRECT5V_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")("</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_3C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_4C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="constant-syntax">VNODE_5C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_6C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">MESSAGE0_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"_final_message0("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">MESSAGE1_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"_final_message1("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="constant-syntax">VNODE_3C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
|
@ -877,11 +908,14 @@ is evaluated only once — in case there are side-effects of the evaluation.
|
|||
<span class="plain-syntax"> </span><span class="constant-syntax">VNODE_3C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_4C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">MESSAGE3_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"_final_message3("</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_2C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="constant-syntax">VNODE_3C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_4C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">","</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_5C</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EXTERNALCALL_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"external calls impossible in Inform 6"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
</pre>
|
||||
<ul class="endnotetexts"><li>This code is used in <a href="4-i6c2.html#SP6">§6</a>.</li></ul>
|
||||
<p class="commentary firstcommentary"><a id="SP6_8" class="paragraph-anchor"></a><b>§6.8. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Textual output</span><span class="named-paragraph-number">6.8</span></span><span class="comment-syntax"> =</span>
|
||||
<p class="commentary firstcommentary"><a id="SP6_9" class="paragraph-anchor"></a><b>§6.9. </b>Note that the only styles permitted are those from the original Z-machine, which
|
||||
is about the level of technology of a 1970s teletype. The <span class="extract"><span class="extract-syntax">!style</span></span> number must be
|
||||
a constant 1, 2 or 3, or else plain roman is all you get.
|
||||
</p>
|
||||
|
||||
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Textual output</span><span class="named-paragraph-number">6.9</span></span><span class="comment-syntax"> =</span>
|
||||
</p>
|
||||
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
|
@ -918,7 +952,7 @@ is evaluated only once — in case there are side-effects of the evaluation.
|
|||
<span class="plain-syntax"> }</span>
|
||||
</pre>
|
||||
<ul class="endnotetexts"><li>This code is used in <a href="4-i6c2.html#SP6">§6</a>.</li></ul>
|
||||
<p class="commentary firstcommentary"><a id="SP6_9" class="paragraph-anchor"></a><b>§6.9. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">The VM object tree</span><span class="named-paragraph-number">6.9</span></span><span class="comment-syntax"> =</span>
|
||||
<p class="commentary firstcommentary"><a id="SP6_10" class="paragraph-anchor"></a><b>§6.10. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">The VM object tree</span><span class="named-paragraph-number">6.10</span></span><span class="comment-syntax"> =</span>
|
||||
</p>
|
||||
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
|
@ -926,16 +960,14 @@ is evaluated only once — in case there are side-effects of the evaluation.
|
|||
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">REMOVE_BIP:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"remove "</span><span class="plain-syntax">); </span><span class="constant-syntax">VNODE_1C</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
||||
</pre>
|
||||
<ul class="endnotetexts"><li>This code is used in <a href="4-i6c2.html#SP6">§6</a>.</li></ul>
|
||||
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>§7. </b></p>
|
||||
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>§7. Support code for property accesses. </b>In the following, <span class="extract"><span class="extract-syntax">prop_node</span></span> is a <span class="extract"><span class="extract-syntax">VAL_IST</span></span> identifying the property being
|
||||
accessed: we return the "inner name" as text, if we can find one. This will only
|
||||
happen if the node evaluates to a named symbol which is the name of a property.
|
||||
See <a href="2-vo.html" class="internal">Vanilla Objects</a> for more on inner names.
|
||||
</p>
|
||||
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
<span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">I6TargetCode::inner_name</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">I6TargetCode::inner_name</span></span>:<br/><a href="4-i6c2.html#SP6_2_1_2">§6.2.1.2</a>, <a href="4-i6c2.html#SP6_3">§6.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="identifier-syntax">W</span><span class="plain-syntax">.</span><span class="identifier-syntax">data</span><span class="plain-syntax">[</span><span class="identifier-syntax">ID_IFLD</span><span class="plain-syntax">] == </span><span class="identifier-syntax">REFERENCE_IST</span><span class="plain-syntax">) </span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InterTree::first_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prop_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InterTree::third_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-i6c2.html#SP7" class="function-link"><span class="function-syntax">I6TargetCode::inner_name_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">prop_node</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax">}</span>
|
||||
|
||||
<span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">I6TargetCode::inner_name_inner</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">I6TargetCode::inner_name_inner</span></span>:<br/><a href="4-i6c2.html#SP6_4">§6.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prop_node</span><span class="plain-syntax">) {</span>
|
||||
<span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">I6TargetCode::inner_name</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">I6TargetCode::inner_name</span></span>:<br/><a href="4-i6c2.html#SP6_2_1_2">§6.2.1.2</a>, <a href="4-i6c2.html#SP6_3">§6.3</a>, <a href="4-i6c2.html#SP6_4">§6.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prop_node</span><span class="plain-syntax">) {</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prop_symbol</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">prop_node</span><span class="plain-syntax">-></span><span class="identifier-syntax">W</span><span class="plain-syntax">.</span><span class="identifier-syntax">data</span><span class="plain-syntax">[</span><span class="identifier-syntax">ID_IFLD</span><span class="plain-syntax">] == </span><span class="identifier-syntax">VAL_IST</span><span class="plain-syntax">) {</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax"> </span><span class="identifier-syntax">val1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">prop_node</span><span class="plain-syntax">-></span><span class="identifier-syntax">W</span><span class="plain-syntax">.</span><span class="identifier-syntax">data</span><span class="plain-syntax">[</span><span class="identifier-syntax">VAL1_VAL_IFLD</span><span class="plain-syntax">];</span>
|
||||
|
@ -953,20 +985,30 @@ is evaluated only once — in case there are side-effects of the evaluation.
|
|||
<span class="plain-syntax"> }</span>
|
||||
<span class="plain-syntax">}</span>
|
||||
</pre>
|
||||
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>§8. </b></p>
|
||||
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>§8. </b><span class="extract"><span class="extract-syntax">I6TargetCode::pval_case</span></span> applies to a <span class="extract"><span class="extract-syntax">!propertyvalue</span></span> invocation node. That
|
||||
has three children: the kind, the object/owner, and the property itself. We
|
||||
look at the node and try to see if it's one of the two easy cases which enable
|
||||
more efficient code to be compiled (see above): in fact, it almost always is.
|
||||
</p>
|
||||
|
||||
<ul class="items"><li>● We return <span class="extract"><span class="extract-syntax">I6G_CAN_PROVE_IS_OBJ_ATTRIBUTE</span></span> if the kind is definitely <span class="extract"><span class="extract-syntax">OBJECT_TY</span></span>
|
||||
and the property is stored in a VM-attribute;
|
||||
</li><li>● Or <span class="extract"><span class="extract-syntax">I6G_CAN_PROVE_IS_OBJ_PROPERTY</span></span> if the kind is definitely <span class="extract"><span class="extract-syntax">OBJECT_TY</span></span>
|
||||
and the property is stored in a VM-property;
|
||||
</li><li>● Or <span class="extract"><span class="extract-syntax">I6G_CANNOT_PROVE</span></span> if we don't know.
|
||||
</li></ul>
|
||||
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">I6G_CAN_PROVE_IS_OBJ_ATTRIBUTE</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
|
||||
<span class="definition-keyword">define</span> <span class="constant-syntax">I6G_CAN_PROVE_IS_OBJ_PROPERTY</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
|
||||
<span class="definition-keyword">define</span> <span class="constant-syntax">I6G_CANNOT_PROVE</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span>
|
||||
</pre>
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">I6TargetCode::pval_case</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">I6TargetCode::pval_case</span></span>:<br/><a href="4-i6c2.html#SP6_2_1">§6.2.1</a>, <a href="4-i6c2.html#SP6_2_1_2">§6.2.1.2</a>, <a href="4-i6c2.html#SP6_3">§6.3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
|
||||
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">I6TargetCode::pval_case</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">I6TargetCode::pval_case</span></span>:<br/><a href="4-i6c2.html#SP6_2_1">§6.2.1</a>, <a href="4-i6c2.html#SP6_2_1_2">§6.2.1.2</a>, <a href="4-i6c2.html#SP6_3">§6.3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">P</span><span class="plain-syntax">-></span><span class="identifier-syntax">W</span><span class="plain-syntax">.</span><span class="identifier-syntax">data</span><span class="plain-syntax">[</span><span class="identifier-syntax">ID_IFLD</span><span class="plain-syntax">] == </span><span class="identifier-syntax">REFERENCE_IST</span><span class="plain-syntax">) </span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InterTree::first_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prop_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InterTree::third_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-i6c2.html#SP8" class="function-link"><span class="function-syntax">I6TargetCode::pval_case_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">InterTree::first_child</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">), </span><span class="identifier-syntax">prop_node</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax">}</span>
|
||||
|
||||
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">I6TargetCode::pval_case_inner</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">I6TargetCode::pval_case_inner</span></span>:<br/><a href="4-i6c2.html#SP6_4">§6.4</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prop_node</span><span class="plain-syntax">) {</span>
|
||||
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">I6TargetCode::pval_case_inner</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">I6TargetCode::pval_case_inner</span></span>:<br/><a href="4-i6c2.html#SP6_4">§6.4</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prop_node</span><span class="plain-syntax">) {</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_symbol</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kind_node</span><span class="plain-syntax">-></span><span class="identifier-syntax">W</span><span class="plain-syntax">.</span><span class="identifier-syntax">data</span><span class="plain-syntax">[</span><span class="identifier-syntax">ID_IFLD</span><span class="plain-syntax">] == </span><span class="identifier-syntax">VAL_IST</span><span class="plain-syntax">) {</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax"> </span><span class="identifier-syntax">val1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">kind_node</span><span class="plain-syntax">-></span><span class="identifier-syntax">W</span><span class="plain-syntax">.</span><span class="identifier-syntax">data</span><span class="plain-syntax">[</span><span class="identifier-syntax">VAL1_VAL_IFLD</span><span class="plain-syntax">];</span>
|
||||
|
@ -995,13 +1037,43 @@ is evaluated only once — in case there are side-effects of the evaluation.
|
|||
<span class="plain-syntax"> }</span>
|
||||
<span class="plain-syntax">}</span>
|
||||
</pre>
|
||||
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>§9. A few resources. </b></p>
|
||||
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>§9. The final functions. </b>The generator above compiled calls to a handful of functions with names in the
|
||||
form <span class="extract"><span class="extract-syntax">_final_*</span></span>; so these functions must clearly be supplied. It might seem that
|
||||
they ought to be included in, say, BasicInformKit and not here. But:
|
||||
</p>
|
||||
|
||||
<ul class="items"><li>(1) They are needed only for Inform 6 usage, whereas BasicInformKit contains
|
||||
material used whatever the final code-generator;
|
||||
</li><li>(2) They are written in genuine Inform 6 code, not kit code, which looks like
|
||||
I6 and is very similar to it but is not quite the same. In kit code, <span class="extract"><span class="extract-syntax">O.P</span></span> means
|
||||
"the value of the property P for the object O", but where <span class="extract"><span class="extract-syntax">P</span></span> is the metadata
|
||||
array for the property. In genuine Inform 6, <span class="extract"><span class="extract-syntax">O.P</span></span> expects <span class="extract"><span class="extract-syntax">P</span></span> to be the actual
|
||||
VM-property. The following functions need the latter interpretation in order to work.
|
||||
</li></ul>
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">I6TargetCode::end_generation</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">I6TargetCode::end_generation</span></span>:<br/>Generating Inform 6 - <a href="4-fi6.html#SP7">§7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generator</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">, </span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">) {</span>
|
||||
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">I6TargetCode::end_generation</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">I6TargetCode::end_generation</span></span>:<br/>Generating Inform 6 - <a href="4-fi6.html#SP7">§7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">code_generator</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cgt</span><span class="plain-syntax">, </span><span class="reserved-syntax">code_generation</span><span class="plain-syntax"> *</span><span class="identifier-syntax">gen</span><span class="plain-syntax">) {</span>
|
||||
<span class="plain-syntax"> </span><span class="reserved-syntax">segmentation_pos</span><span class="plain-syntax"> </span><span class="identifier-syntax">saved</span><span class="plain-syntax"> = </span><a href="2-cg.html#SP10" class="function-link"><span class="function-syntax">CodeGen::select</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="constant-syntax">functions_I7CGS</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OUT</span><span class="plain-syntax"> = </span><a href="2-cg.html#SP12" class="function-link"><span class="function-syntax">CodeGen::current</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_read_pval K o p t;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-i6c2.html#SP9_1" class="named-paragraph-link"><span class="named-paragraph">Most general implementation of !propertyvalue</span><span class="named-paragraph-number">9.1</span></a></span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-i6c2.html#SP9_2" class="named-paragraph-link"><span class="named-paragraph">Most general implementation of !propertyexists</span><span class="named-paragraph-number">9.2</span></a></span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-i6c2.html#SP9_3" class="named-paragraph-link"><span class="named-paragraph">Most general implementation of !propertyarray</span><span class="named-paragraph-number">9.3</span></a></span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-i6c2.html#SP9_4" class="named-paragraph-link"><span class="named-paragraph">Most general implementation of !propertylength</span><span class="named-paragraph-number">9.4</span></a></span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-i6c2.html#SP9_5" class="named-paragraph-link"><span class="named-paragraph">Most general implementation of writing to a property</span><span class="named-paragraph-number">9.5</span></a></span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-i6c2.html#SP9_6" class="named-paragraph-link"><span class="named-paragraph">Implementation of !messageX</span><span class="named-paragraph-number">9.6</span></a></span><span class="plain-syntax">;</span>
|
||||
<span class="plain-syntax"> </span><a href="2-cg.html#SP10" class="function-link"><span class="function-syntax">CodeGen::deselect</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">saved</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax">}</span>
|
||||
</pre>
|
||||
<p class="commentary firstcommentary"><a id="SP9_1" class="paragraph-anchor"></a><b>§9.1. </b>See <a href="4-i6o.html" class="internal">Inform 6 Objects</a> for the runtime contents of the array of property
|
||||
metadata <span class="extract"><span class="extract-syntax">p</span></span>. The following is more or less a safe general-purpose wrapper for
|
||||
the Inform 6 operator <span class="extract"><span class="extract-syntax">.</span></span>, used as an rvalue, in cases where we cannot prove
|
||||
it would be safe to use <span class="extract"><span class="extract-syntax">.</span></span> directly:
|
||||
</p>
|
||||
|
||||
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Most general implementation of !propertyvalue</span><span class="named-paragraph-number">9.1</span></span><span class="comment-syntax"> =</span>
|
||||
</p>
|
||||
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_propertyvalue K o p t;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (K == OBJECT_TY) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (metaclass(o) == Object) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" t = p-->0; p = p-->1;\n"</span><span class="plain-syntax">);</span>
|
||||
|
@ -1014,46 +1086,16 @@ is evaluated only once — in case there are side-effects of the evaluation.
|
|||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" return (t.(p-->1))-->(o+COL_HSIZE);\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_write_pval K o p v t;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (K == OBJECT_TY) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (metaclass(o) == Object) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" t = p-->0; p = p-->1; ! print \"give \", o, \" \", p, \"^\";\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (t == 2) { if (v) give o p; else give o ~p; }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" else { if (o provides p) o.p = v; }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" } else {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" ((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE) = v;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_read_paddr K o p v t;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (K ~= OBJECT_TY) return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" t = p-->0; p = p-->1; ! print \"give \", o, \" \", p, \"^\";\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (t == 2) return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" return o.&p;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_read_plen K o p v t;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (K ~= OBJECT_TY) return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" t = p-->0; p = p-->1; ! print \"give \", o, \" \", p, \"^\";\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (t == 2) return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" return o.#p;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_message0 o p q x a rv;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (p-->0 == 2) return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" q = p-->1; return o.q();\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_message1 o p v1 q x a rv;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (p-->0 == 2) return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" q = p-->1; return o.q(v1);\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_message2 o p v1 v2 q x a rv;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (p-->0 == 2) return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" q = p-->1; return o.q(v1, v2);\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_message3 o p v1 v2 v3 q x a rv;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (p-->0 == 2) return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" q = p-->1; return o.q(v1, v2, v3);\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_provides K o p holder;\n"</span><span class="plain-syntax">);</span>
|
||||
</pre>
|
||||
<ul class="endnotetexts"><li>This code is used in <a href="4-i6c2.html#SP9">§9</a>.</li></ul>
|
||||
<p class="commentary firstcommentary"><a id="SP9_2" class="paragraph-anchor"></a><b>§9.2. </b>Similarly, this is a safe wrapper for <span class="extract"><span class="extract-syntax">provides</span></span>:
|
||||
</p>
|
||||
|
||||
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Most general implementation of !propertyexists</span><span class="named-paragraph-number">9.2</span></span><span class="comment-syntax"> =</span>
|
||||
</p>
|
||||
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_propertyexists K o p holder;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"if (K == OBJECT_TY) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if ((o) && (metaclass(o) == Object)) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if ((p-->0 == 2) || (o provides p-->1)) {\n"</span><span class="plain-syntax">);</span>
|
||||
|
@ -1077,28 +1119,179 @@ is evaluated only once — in case there are side-effects of the evaluation.
|
|||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"}\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"rfalse; ];\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_xwrite_pval K o p v t;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"if (K == OBJECT_TY) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (p-->0 == 2) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (v) give o p-->1; else give o ~(p-->1);\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" } else {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" o.(p-->1) = v;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"} else {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" ((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE) = v;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"}\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"Constant i7_lvalue_SET = 1;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"Constant i7_lvalue_PREDEC = 2;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"Constant i7_lvalue_POSTDEC = 3;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"Constant i7_lvalue_PREINC = 4;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"Constant i7_lvalue_POSTINC = 5;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"Constant i7_lvalue_SETBIT = 6;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"Constant i7_lvalue_CLEARBIT = 7;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><a href="2-cg.html#SP10" class="function-link"><span class="function-syntax">CodeGen::deselect</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">gen</span><span class="plain-syntax">, </span><span class="identifier-syntax">saved</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax">}</span>
|
||||
</pre>
|
||||
<ul class="endnotetexts"><li>This code is used in <a href="4-i6c2.html#SP9">§9</a>.</li></ul>
|
||||
<p class="commentary firstcommentary"><a id="SP9_3" class="paragraph-anchor"></a><b>§9.3. </b>And this for <span class="extract"><span class="extract-syntax">.&</span></span>. Note that we always return 0 if the owner is not an object.
|
||||
</p>
|
||||
|
||||
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Most general implementation of !propertyarray</span><span class="named-paragraph-number">9.3</span></span><span class="comment-syntax"> =</span>
|
||||
</p>
|
||||
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_propertyarray K o p v t;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (K ~= OBJECT_TY) return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" t = p-->0; p = p-->1;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (t == 2) return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" return o.&p;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
</pre>
|
||||
<ul class="endnotetexts"><li>This code is used in <a href="4-i6c2.html#SP9">§9</a>.</li></ul>
|
||||
<p class="commentary firstcommentary"><a id="SP9_4" class="paragraph-anchor"></a><b>§9.4. </b>And this for <span class="extract"><span class="extract-syntax">.#</span></span>. Again, we always return 0 if the owner is not an object.
|
||||
</p>
|
||||
|
||||
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Most general implementation of !propertylength</span><span class="named-paragraph-number">9.4</span></span><span class="comment-syntax"> =</span>
|
||||
</p>
|
||||
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_propertylength K o p v t;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (K ~= OBJECT_TY) return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" t = p-->0; p = p-->1;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (t == 2) return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" return o.#p;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
</pre>
|
||||
<ul class="endnotetexts"><li>This code is used in <a href="4-i6c2.html#SP9">§9</a>.</li></ul>
|
||||
<p class="commentary firstcommentary"><a id="SP9_5" class="paragraph-anchor"></a><b>§9.5. </b>And this is a safe way to write to or otherwise alter <span class="extract"><span class="extract-syntax">O.P</span></span>, laboriously
|
||||
written out as seven functions. (Speed is more important than conciseness here.)
|
||||
</p>
|
||||
|
||||
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Most general implementation of writing to a property</span><span class="named-paragraph-number">9.5</span></span><span class="comment-syntax"> =</span>
|
||||
</p>
|
||||
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_store_property K o p v t;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (K == OBJECT_TY) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (metaclass(o) == Object) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" t = p-->0; p = p-->1;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (t == 2) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (v) give o p; else give o ~p;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" } else if (o provides p) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" o.p = v;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" } else {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" ((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE) = v;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_preinc_property K o p t;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (K == OBJECT_TY) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (metaclass(o) == Object) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" t = p-->0; p = p-->1;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (t == 2) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (o has p) { give o ~p; rfalse; } give o p; rtrue;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" } else if (o provides p) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" return ++(o.p);\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" } else {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" return ++(((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE));\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_predec_property K o p t;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (K == OBJECT_TY) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (metaclass(o) == Object) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" t = p-->0; p = p-->1;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (t == 2) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (o has p) { give o ~p; rfalse; } give o p; rtrue;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" } else if (o provides p) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" return --(o.p);\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" } else {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" return --(((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE));\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_postinc_property K o p t;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (K == OBJECT_TY) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (metaclass(o) == Object) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" t = p-->0; p = p-->1;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (t == 2) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (o has p) { give o ~p; rtrue; } give o p; rfalse;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" } else if (o provides p) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" return (o.p)++;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" } else {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" return (((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE))++;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_postdec_property K o p t;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (K == OBJECT_TY) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (metaclass(o) == Object) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" t = p-->0; p = p-->1;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (t == 2) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (o has p) { give o ~p; rtrue; } give o p; rfalse;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" } else if (o provides p) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" return (o.p)--;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" } else {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" return (((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE))--;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_setbit_property K o p v t;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (K == OBJECT_TY) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (metaclass(o) == Object) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" t = p-->0; p = p-->1;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (t == 2) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (v & 1) give o p;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" } else if (o provides p) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" o.p = o.p | v;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" } else {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" ((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE) =\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" ((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE) | v;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_clearbit_property K o p v t;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (K == OBJECT_TY) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (metaclass(o) == Object) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" t = p-->0; p = p-->1;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (t == 2) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (v & 1) give o ~p;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" } else if (o provides p) {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" o.p = o.p & ~v;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" } else {\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" ((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE) =\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" ((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE) & ~v;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" }\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
</pre>
|
||||
<ul class="endnotetexts"><li>This code is used in <a href="4-i6c2.html#SP9">§9</a>.</li></ul>
|
||||
<p class="commentary firstcommentary"><a id="SP9_6" class="paragraph-anchor"></a><b>§9.6. </b>It's not entirely clear what the result of trying to send a message to an
|
||||
either/or property ought to be: nobody should ever do that. We're going to say
|
||||
that it's 0 here.
|
||||
</p>
|
||||
|
||||
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Implementation of !messageX</span><span class="named-paragraph-number">9.6</span></span><span class="comment-syntax"> =</span>
|
||||
</p>
|
||||
|
||||
<pre class="displayed-code all-displayed-code code-font">
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_message0 o p q x a rv;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (p-->0 == 2) return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" q = p-->1; return o.q();\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_message1 o p v1 q x a rv;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (p-->0 == 2) return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" q = p-->1; return o.q(v1);\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_message2 o p v1 v2 q x a rv;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (p-->0 == 2) return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" q = p-->1; return o.q(v1, v2);\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"[ _final_message3 o p v1 v2 v3 q x a rv;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" if (p-->0 == 2) return 0;\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" q = p-->1; return o.q(v1, v2, v3);\n"</span><span class="plain-syntax">);</span>
|
||||
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"];\n"</span><span class="plain-syntax">);</span>
|
||||
</pre>
|
||||
<ul class="endnotetexts"><li>This code is used in <a href="4-i6c2.html#SP9">§9</a>.</li></ul>
|
||||
<nav role="progress"><div class="progresscontainer">
|
||||
<ul class="progressbar"><li class="progressprev"><a href="4-i6o.html">❮</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-cg.html">2</a></li><li class="progresschapter"><a href="3-fti.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-fi6.html">fi6</a></li><li class="progresssection"><a href="4-i6c.html">i6c</a></li><li class="progresssection"><a href="4-i6gv.html">i6gv</a></li><li class="progresssection"><a href="4-i6o.html">i6o</a></li><li class="progresscurrent">i6c2</li><li class="progresschapter"><a href="5-fnc.html">5</a></li><li class="progressnext"><a href="5-fnc.html">❯</a></li></ul></div>
|
||||
</nav><!--End of weave-->
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
100.0% in inform7 run
|
||||
55.2% in compilation to Inter
|
||||
39.8% in //Sequence::undertake_queued_tasks//
|
||||
3.5% in //MajorNodes::pre_pass//
|
||||
3.4% in //MajorNodes::pre_pass//
|
||||
2.6% in //MajorNodes::pass_1//
|
||||
2.0% in //RTPhrasebook::compile_entries//
|
||||
1.3% in //ImperativeDefinitions::assess_all//
|
||||
1.0% in //RTKindConstructors::compile//
|
||||
1.2% in //RTKindConstructors::compile//
|
||||
0.4% in //ImperativeDefinitions::compile_first_block//
|
||||
0.4% in //MajorNodes::pass_2//
|
||||
0.4% in //Sequence::undertake_queued_tasks//
|
||||
|
@ -17,11 +17,11 @@
|
|||
0.1% in //Task::make_built_in_kind_constructors//
|
||||
0.1% in //World::stages_II_and_III//
|
||||
1.8% not specifically accounted for
|
||||
42.8% in running Inter pipeline
|
||||
12.2% in step preparation
|
||||
42.7% in running Inter pipeline
|
||||
12.1% in step preparation
|
||||
9.7% in inter step 7/16: consolidate-text
|
||||
8.1% in inter step 2/16: link
|
||||
6.4% in inter step 16/16: generate inform6 -> auto.inf
|
||||
7.9% in inter step 2/16: link
|
||||
6.3% in inter step 16/16: generate inform6 -> auto.inf
|
||||
1.5% in inter step 11/16: make-identifiers-unique
|
||||
0.4% in inter step 12/16: reconcile-verbs
|
||||
0.2% in inter step 10/16: detect-indirect-calls
|
||||
|
@ -33,6 +33,6 @@
|
|||
0.1% in inter step 3/16: merge-template <- none
|
||||
0.1% in inter step 4/16: parse-linked-matter
|
||||
0.1% in inter step 5/16: resolve-conditional-compilation
|
||||
2.5% not specifically accounted for
|
||||
2.7% not specifically accounted for
|
||||
1.6% in supervisor
|
||||
0.3% not specifically accounted for
|
||||
0.5% not specifically accounted for
|
||||
|
|
|
@ -149,10 +149,6 @@ primitive !message0 val val -> val
|
|||
primitive !message1 val val val -> val
|
||||
primitive !message2 val val val val -> val
|
||||
primitive !message3 val val val val val -> val
|
||||
primitive !callmessage0 val -> val
|
||||
primitive !callmessage1 val val -> val
|
||||
primitive !callmessage2 val val val -> val
|
||||
primitive !callmessage3 val val val val -> val
|
||||
primitive !externalcall val val -> val
|
||||
primitive !propertyarray val val val -> val
|
||||
primitive !propertylength val val val -> val
|
||||
|
@ -34817,7 +34813,7 @@ package main _plain
|
|||
constant KIT_CONFIGURATION_BITMAP K_typeless_int = 0
|
||||
constant KIT_CONFIGURATION_LOOKMODE K_typeless_int = 2
|
||||
constant I7_VERSION_NUMBER K_typeless_string = "10.1.0"
|
||||
constant I7_FULL_VERSION_NUMBER K_typeless_string = "10.1.0-alpha.1+6T56"
|
||||
constant I7_FULL_VERSION_NUMBER K_typeless_string = "10.1.0-alpha.1+6T57"
|
||||
constant ^virtual_machine K_typeless_string = "C/32d/v1/no-main"
|
||||
constant ^virtual_machine_icon K_typeless_string = "vm_glulx.png"
|
||||
constant ^language_elements_used K_typeless_string = "core, naming, instance counting, glulx external files"
|
||||
|
|
|
@ -242,7 +242,8 @@ void I6TargetCode::invoke_primitive(code_generator *cgt, code_generation *gen,
|
|||
@<Storing or otherwise changing values@>;
|
||||
@<VM stack access@>;
|
||||
@<Control structures@>;
|
||||
@<Indirect function or method calls@>;
|
||||
@<Indirect function calls@>;
|
||||
@<Method calls@>;
|
||||
@<Property value access@>;
|
||||
@<Textual output@>;
|
||||
@<The VM object tree@>;
|
||||
|
@ -339,9 +340,12 @@ for example, be a global variable, or a memory location.
|
|||
case CLEARBIT_BIP: @<Perform a store@>; break;
|
||||
|
||||
@<Perform a store@> =
|
||||
inter_tree_node *ref = InterTree::first_child(P);
|
||||
if ((Inter::Reference::node_is_ref_to(gen->from, ref, PROPERTYVALUE_BIP)) &&
|
||||
(I6TargetCode::pval_case(ref) != I6G_CAN_PROVE_IS_OBJ_PROPERTY)) {
|
||||
inter_tree_node *storage_ref = InterTree::first_child(P);
|
||||
if (storage_ref->W.data[0] == REFERENCE_IST)
|
||||
storage_ref = InterTree::first_child(storage_ref);
|
||||
if ((Inter::Reference::node_is_ref_to(gen->from, InterTree::first_child(P),
|
||||
PROPERTYVALUE_BIP)) &&
|
||||
(I6TargetCode::pval_case(storage_ref) != I6G_CAN_PROVE_IS_OBJ_PROPERTY)) {
|
||||
@<Alter a property value@>;
|
||||
} else {
|
||||
@<Alter some other storage@>;
|
||||
|
@ -352,6 +356,11 @@ it's one that we can simply treat as an lvalue in Inform 6 (for example, by givi
|
|||
its variable name). For example, the memory location |A-->3| can be assigned to,
|
||||
or can have |++| or |--| applied to it in I6.
|
||||
|
||||
Note that this case even includes some property values: if we can see that |P|
|
||||
is the explicit name of a property we are storing in a VM-property, then we can
|
||||
use |O.P| as an Inform 6 lvalue, and all is well, and we then end up with code
|
||||
such as |++(O.P)|.
|
||||
|
||||
@<Alter some other storage@> =
|
||||
switch (bip) {
|
||||
case PREINCREMENT_BIP: WRITE("++("); VNODE_1C; WRITE(")"); break;
|
||||
|
@ -363,15 +372,17 @@ or can have |++| or |--| applied to it in I6.
|
|||
case CLEARBIT_BIP: VNODE_1C; WRITE(" = "); VNODE_1C; WRITE(" &~ ("); VNODE_2C; WRITE(")"); break;
|
||||
}
|
||||
|
||||
@ Property values are trickier: they aren't lvalues in Inform 6. (Remember,
|
||||
an I7-level property is a pointer to a small metadata array: it's not the same
|
||||
thing as a VM-property. We cannot compile an I6 assignment to |O.P| given that
|
||||
|P| is actually an array, and anyway, what if |P| is stored as a VM-attribute?)
|
||||
@ But not all property values can be written as Inform 6 lvalues. If the I7
|
||||
property P is being stored as a VM-attribute A, then there is no lvalue which
|
||||
expresses the value of A for an object O: instead one must use |give O A| to
|
||||
set it, |give O ~A| to unset it, and |(O has A)| to test it. And there will
|
||||
also be cases where P cannot be identified at compile-time, so that we have no
|
||||
way to know whether it will be stored as a VM-attribute or not.
|
||||
|
||||
In fact, then, we will compile an attempt to store or modify a property value
|
||||
either as a |give| statement -- if we can prove at compile time that the property
|
||||
is stored in a VM-attribute -- or else as a function call to a general-purpose
|
||||
function called |_final_write_pval|.
|
||||
To handle these two cases, then, we will compile an attempt to store or modify
|
||||
a property value either as a |give| statement -- if we can prove P is being
|
||||
stored in a VM-attribute -- or else as a function call to a general-purpose
|
||||
function called |_final_change_property|.
|
||||
|
||||
@<Alter a property value@> =
|
||||
inter_tree_node *VP = InterTree::second_child(P);
|
||||
|
@ -383,32 +394,34 @@ function called |_final_write_pval|.
|
|||
if ((val1 == LITERAL_IVAL) && (val2 == 0)) set = FALSE;
|
||||
}
|
||||
|
||||
inter_tree_node *storage_ref = InterTree::first_child(P);
|
||||
if (storage_ref->W.data[0] == REFERENCE_IST) storage_ref = InterTree::first_child(storage_ref);
|
||||
|
||||
int c = I6TargetCode::pval_case(ref);
|
||||
if ((c == I6G_CAN_PROVE_IS_OBJ_ATTRIBUTE) && (set == TRUE)) {
|
||||
int c = I6TargetCode::pval_case(storage_ref);
|
||||
if ((c == I6G_CAN_PROVE_IS_OBJ_ATTRIBUTE) && (bip == STORE_BIP) && (set == TRUE)) {
|
||||
WRITE("give "); Vanilla::node(gen, InterTree::second_child(storage_ref));
|
||||
WRITE(" %S", I6TargetCode::inner_name(gen, storage_ref));
|
||||
} else if ((c == I6G_CAN_PROVE_IS_OBJ_ATTRIBUTE) && (set == FALSE)) {
|
||||
WRITE(" %S", I6TargetCode::inner_name(gen, InterTree::third_child(storage_ref)));
|
||||
} else if ((c == I6G_CAN_PROVE_IS_OBJ_ATTRIBUTE) && (bip == STORE_BIP) && (set == FALSE)) {
|
||||
WRITE("give "); Vanilla::node(gen, InterTree::second_child(storage_ref));
|
||||
WRITE(" ~%S", I6TargetCode::inner_name(gen, storage_ref));
|
||||
WRITE(" ~%S", I6TargetCode::inner_name(gen, InterTree::third_child(storage_ref)));
|
||||
} else {
|
||||
WRITE("(_final_write_pval(");
|
||||
WRITE("(");
|
||||
switch (bip) {
|
||||
case STORE_BIP: WRITE("_final_store_property"); break;
|
||||
case PREINCREMENT_BIP: WRITE("_final_preinc_property"); break;
|
||||
case POSTINCREMENT_BIP: WRITE("_final_postinc_property"); break;
|
||||
case PREDECREMENT_BIP: WRITE("_final_predec_property"); break;
|
||||
case POSTDECREMENT_BIP: WRITE("_final_postdec_property"); break;
|
||||
case SETBIT_BIP: WRITE("_final_setbit_property"); break;
|
||||
case CLEARBIT_BIP: WRITE("_final_clearbit_property"); break;
|
||||
}
|
||||
WRITE("(");
|
||||
Vanilla::node(gen, InterTree::first_child(storage_ref));
|
||||
WRITE(",");
|
||||
Vanilla::node(gen, InterTree::second_child(storage_ref));
|
||||
WRITE(",");
|
||||
Vanilla::node(gen, InterTree::third_child(storage_ref));
|
||||
WRITE(", ");
|
||||
switch (bip) {
|
||||
case STORE_BIP: VNODE_2C; WRITE(", i7_lvalue_SET"); break;
|
||||
case PREINCREMENT_BIP: WRITE("0, i7_lvalue_PREINC"); break;
|
||||
case POSTINCREMENT_BIP: WRITE("0, i7_lvalue_POSTINC"); break;
|
||||
case PREDECREMENT_BIP: WRITE("0, i7_lvalue_PREDEC"); break;
|
||||
case POSTDECREMENT_BIP: WRITE("0, i7_lvalue_POSTDEC"); break;
|
||||
case SETBIT_BIP: VNODE_2C; WRITE(", i7_lvalue_SETBIT"); break;
|
||||
case CLEARBIT_BIP: VNODE_2C; WRITE(", i7_lvalue_CLEARBIT"); break;
|
||||
case STORE_BIP: WRITE(", "); VNODE_2C; break;
|
||||
case SETBIT_BIP: WRITE(", "); VNODE_2C; break;
|
||||
case CLEARBIT_BIP: WRITE(", "); VNODE_2C; break;
|
||||
}
|
||||
WRITE("))");
|
||||
}
|
||||
|
@ -423,29 +436,32 @@ what is definitely a VM-object. This optimisation results in faster code.
|
|||
case PROPERTYEXISTS_BIP:
|
||||
I6_GEN_DATA(value_ranges_needed) = TRUE;
|
||||
I6_GEN_DATA(value_property_holders_needed) = TRUE;
|
||||
WRITE("(_final_provides("); VNODE_1C; WRITE(", "); VNODE_2C; WRITE(", ");
|
||||
WRITE("(_final_propertyexists("); VNODE_1C; WRITE(", "); VNODE_2C; WRITE(", ");
|
||||
VNODE_3C; WRITE("))"); break;
|
||||
case PROPERTYARRAY_BIP: WRITE("(_final_read_paddr("); VNODE_1C; WRITE(", ");
|
||||
case PROPERTYARRAY_BIP: WRITE("(_final_propertyarray("); VNODE_1C; WRITE(", ");
|
||||
VNODE_2C; WRITE(", "); VNODE_3C; WRITE("))"); break;
|
||||
case PROPERTYLENGTH_BIP: WRITE("(_final_read_plen("); VNODE_1C; WRITE(", ");
|
||||
case PROPERTYLENGTH_BIP: WRITE("(_final_propertylength("); VNODE_1C; WRITE(", ");
|
||||
VNODE_2C; WRITE(", "); VNODE_3C; WRITE("))"); break;
|
||||
case PROPERTYVALUE_BIP:
|
||||
case PROPERTYVALUE_BIP: {
|
||||
inter_tree_node *KP = InterTree::first_child(P);
|
||||
inter_tree_node *OP = InterTree::second_child(P);
|
||||
inter_tree_node *PP = InterTree::third_child(P);
|
||||
switch (I6TargetCode::pval_case(P)) {
|
||||
case I6G_CAN_PROVE_IS_OBJ_ATTRIBUTE:
|
||||
WRITE("("); VNODE_2C;
|
||||
WRITE(" has %S", I6TargetCode::inner_name(gen, P)); WRITE(")"); break;
|
||||
WRITE(" has %S", I6TargetCode::inner_name(gen, PP)); WRITE(")"); break;
|
||||
case I6G_CAN_PROVE_IS_OBJ_PROPERTY:
|
||||
WRITE("("); VNODE_2C;
|
||||
WRITE(".%S", I6TargetCode::inner_name(gen, P)); WRITE(")"); break;
|
||||
WRITE(".%S", I6TargetCode::inner_name(gen, PP)); WRITE(")"); break;
|
||||
case I6G_CANNOT_PROVE:
|
||||
I6_GEN_DATA(value_property_holders_needed) = TRUE;
|
||||
I6TargetCode::eval_property_list(gen, InterTree::first_child(P),
|
||||
InterTree::second_child(P), InterTree::third_child(P), 0); break;
|
||||
I6TargetCode::eval_property_list(gen, KP, OP, PP, 0); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ In the most general case of |!propertyvalue|, we will end up calling the function
|
||||
|_final_read_pval|. But we don't do so right away because, annoyingly, |!propertyvalue|
|
||||
|_final_propertyvalue|. But we don't do so right away because, annoyingly, |!propertyvalue|
|
||||
can have |!alternative| children supplied. We might find this, for example:
|
||||
= (text as Inter)
|
||||
inv !if
|
||||
|
@ -486,12 +502,12 @@ void I6TargetCode::eval_property_list(code_generation *gen, inter_tree_node *K,
|
|||
switch (I6TargetCode::pval_case_inner(K, Y)) {
|
||||
case I6G_CAN_PROVE_IS_OBJ_ATTRIBUTE:
|
||||
WRITE("("); if (X) Vanilla::node(gen, X); else WRITE("or_tmp_var");
|
||||
WRITE(" has %S", I6TargetCode::inner_name_inner(gen, Y)); WRITE(")"); break;
|
||||
WRITE(" has %S", I6TargetCode::inner_name(gen, Y)); WRITE(")"); break;
|
||||
case I6G_CAN_PROVE_IS_OBJ_PROPERTY:
|
||||
WRITE("("); if (X) Vanilla::node(gen, X); else WRITE("or_tmp_var");
|
||||
WRITE(".%S", I6TargetCode::inner_name_inner(gen, Y)); WRITE(")"); break;
|
||||
WRITE(".%S", I6TargetCode::inner_name(gen, Y)); WRITE(")"); break;
|
||||
case I6G_CANNOT_PROVE:
|
||||
WRITE("_final_read_pval(");
|
||||
WRITE("_final_propertyvalue(");
|
||||
Vanilla::node(gen, K);
|
||||
WRITE(", ");
|
||||
if (X) Vanilla::node(gen, X); else WRITE("or_tmp_var");
|
||||
|
@ -626,26 +642,34 @@ void I6TargetCode::eval_property_list(code_generation *gen, inter_tree_node *K,
|
|||
WRITE("default:\n"); INDENT; VNODE_1C; WRITE(";\n"); OUTDENT;
|
||||
suppress_terminal_semicolon = TRUE;
|
||||
|
||||
@<Indirect function or method calls@> =
|
||||
case INDIRECT0_BIP:
|
||||
case INDIRECT0V_BIP: WRITE("("); VNODE_1C; WRITE(")()"); break;
|
||||
case INDIRECT1_BIP:
|
||||
case INDIRECT1V_BIP: WRITE("("); VNODE_1C; WRITE(")(");
|
||||
VNODE_2C; WRITE(")"); break;
|
||||
case INDIRECT2_BIP:
|
||||
case INDIRECT2V_BIP: WRITE("("); VNODE_1C; WRITE(")(");
|
||||
VNODE_2C; WRITE(","); VNODE_3C; WRITE(")"); break;
|
||||
case INDIRECT3_BIP:
|
||||
case INDIRECT3V_BIP: WRITE("("); VNODE_1C; WRITE(")(");
|
||||
VNODE_2C; WRITE(","); VNODE_3C; WRITE(","); VNODE_4C; WRITE(")"); break;
|
||||
case INDIRECT4_BIP:
|
||||
case INDIRECT4V_BIP: WRITE("("); VNODE_1C; WRITE(")(");
|
||||
VNODE_2C; WRITE(","); VNODE_3C; WRITE(","); VNODE_4C; WRITE(",");
|
||||
VNODE_5C; WRITE(")"); break;
|
||||
case INDIRECT5_BIP:
|
||||
case INDIRECT5V_BIP: WRITE("("); VNODE_1C; WRITE(")(");
|
||||
VNODE_2C; WRITE(","); VNODE_3C; WRITE(","); VNODE_4C; WRITE(",");
|
||||
VNODE_5C; WRITE(","); VNODE_6C; WRITE(")"); break;
|
||||
@ In Inform 6, as in C, a function which returns a value can be called in a void
|
||||
context (in which case its return value is thrown away); the syntax for calling
|
||||
a void function is identical to that for calling a value-returning function, so
|
||||
we can treat |INDIRECT0V_BIP| as the same as |INDIRECT0_BIP|, and so on.
|
||||
|
||||
@<Indirect function calls@> =
|
||||
case INDIRECT0_BIP: case INDIRECT0V_BIP:
|
||||
WRITE("("); VNODE_1C; WRITE(")()"); break;
|
||||
case INDIRECT1_BIP: case INDIRECT1V_BIP:
|
||||
WRITE("("); VNODE_1C; WRITE(")("); VNODE_2C; WRITE(")"); break;
|
||||
case INDIRECT2_BIP: case INDIRECT2V_BIP:
|
||||
WRITE("("); VNODE_1C; WRITE(")("); VNODE_2C; WRITE(","); VNODE_3C; WRITE(")");
|
||||
break;
|
||||
case INDIRECT3_BIP: case INDIRECT3V_BIP:
|
||||
WRITE("("); VNODE_1C; WRITE(")("); VNODE_2C; WRITE(","); VNODE_3C; WRITE(",");
|
||||
VNODE_4C; WRITE(")"); break;
|
||||
case INDIRECT4_BIP: case INDIRECT4V_BIP:
|
||||
WRITE("("); VNODE_1C; WRITE(")("); VNODE_2C; WRITE(","); VNODE_3C; WRITE(",");
|
||||
VNODE_4C; WRITE(","); VNODE_5C; WRITE(")"); break;
|
||||
case INDIRECT5_BIP: case INDIRECT5V_BIP:
|
||||
WRITE("("); VNODE_1C; WRITE(")("); VNODE_2C; WRITE(","); VNODE_3C; WRITE(",");
|
||||
VNODE_4C; WRITE(","); VNODE_5C; WRITE(","); VNODE_6C; WRITE(")"); break;
|
||||
case EXTERNALCALL_BIP: internal_error("external calls impossible in Inform 6"); break;
|
||||
|
||||
@ Message calls are handled with functions (see below) in case the user is trying
|
||||
to send a message to a property stored in an attribute, or something like that.
|
||||
|
||||
@<Method calls@> =
|
||||
case MESSAGE0_BIP: WRITE("_final_message0("); VNODE_1C; WRITE(", "); VNODE_2C; WRITE(")"); break;
|
||||
case MESSAGE1_BIP: WRITE("_final_message1("); VNODE_1C; WRITE(", "); VNODE_2C; WRITE(", ");
|
||||
VNODE_3C; WRITE(")"); break;
|
||||
|
@ -654,7 +678,9 @@ void I6TargetCode::eval_property_list(code_generation *gen, inter_tree_node *K,
|
|||
case MESSAGE3_BIP: WRITE("_final_message3("); VNODE_1C; WRITE(", "); VNODE_2C; WRITE(", ");
|
||||
VNODE_3C; WRITE(","); VNODE_4C; WRITE(","); VNODE_5C; WRITE(")"); break;
|
||||
|
||||
case EXTERNALCALL_BIP: internal_error("external calls impossible in Inform 6"); break;
|
||||
@ Note that the only styles permitted are those from the original Z-machine, which
|
||||
is about the level of technology of a 1970s teletype. The |!style| number must be
|
||||
a constant 1, 2 or 3, or else plain roman is all you get.
|
||||
|
||||
@<Textual output@> =
|
||||
case PRINT_BIP: WRITE("print "); CodeGen::lt_mode(gen, PRINTING_LTM);
|
||||
|
@ -693,16 +719,14 @@ void I6TargetCode::eval_property_list(code_generation *gen, inter_tree_node *K,
|
|||
case MOVE_BIP: WRITE("move "); VNODE_1C; WRITE(" to "); VNODE_2C; break;
|
||||
case REMOVE_BIP: WRITE("remove "); VNODE_1C; break;
|
||||
|
||||
@
|
||||
@h Support code for property accesses.
|
||||
In the following, |prop_node| is a |VAL_IST| identifying the property being
|
||||
accessed: we return the "inner name" as text, if we can find one. This will only
|
||||
happen if the node evaluates to a named symbol which is the name of a property.
|
||||
See //Vanilla Objects// for more on inner names.
|
||||
|
||||
=
|
||||
text_stream *I6TargetCode::inner_name(code_generation *gen, inter_tree_node *P) {
|
||||
while (P->W.data[ID_IFLD] == REFERENCE_IST) P = InterTree::first_child(P);
|
||||
inter_tree_node *prop_node = InterTree::third_child(P);
|
||||
return I6TargetCode::inner_name_inner(gen, prop_node);
|
||||
}
|
||||
|
||||
text_stream *I6TargetCode::inner_name_inner(code_generation *gen, inter_tree_node *prop_node) {
|
||||
text_stream *I6TargetCode::inner_name(code_generation *gen, inter_tree_node *prop_node) {
|
||||
inter_symbol *prop_symbol = NULL;
|
||||
if (prop_node->W.data[ID_IFLD] == VAL_IST) {
|
||||
inter_ti val1 = prop_node->W.data[VAL1_VAL_IFLD];
|
||||
|
@ -720,7 +744,16 @@ text_stream *I6TargetCode::inner_name_inner(code_generation *gen, inter_tree_nod
|
|||
}
|
||||
}
|
||||
|
||||
@
|
||||
@ |I6TargetCode::pval_case| applies to a |!propertyvalue| invocation node. That
|
||||
has three children: the kind, the object/owner, and the property itself. We
|
||||
look at the node and try to see if it's one of the two easy cases which enable
|
||||
more efficient code to be compiled (see above): in fact, it almost always is.
|
||||
|
||||
(*) We return |I6G_CAN_PROVE_IS_OBJ_ATTRIBUTE| if the kind is definitely |OBJECT_TY|
|
||||
and the property is stored in a VM-attribute;
|
||||
(*) Or |I6G_CAN_PROVE_IS_OBJ_PROPERTY| if the kind is definitely |OBJECT_TY|
|
||||
and the property is stored in a VM-property;
|
||||
(*) Or |I6G_CANNOT_PROVE| if we don't know.
|
||||
|
||||
@d I6G_CAN_PROVE_IS_OBJ_ATTRIBUTE 1
|
||||
@d I6G_CAN_PROVE_IS_OBJ_PROPERTY 2
|
||||
|
@ -762,14 +795,39 @@ int I6TargetCode::pval_case_inner(inter_tree_node *kind_node, inter_tree_node *p
|
|||
}
|
||||
}
|
||||
|
||||
@h The final functions.
|
||||
The generator above compiled calls to a handful of functions with names in the
|
||||
form |_final_*|; so these functions must clearly be supplied. It might seem that
|
||||
they ought to be included in, say, BasicInformKit and not here. But:
|
||||
|
||||
@h A few resources.
|
||||
(1) They are needed only for Inform 6 usage, whereas BasicInformKit contains
|
||||
material used whatever the final code-generator;
|
||||
(2) They are written in genuine Inform 6 code, not kit code, which looks like
|
||||
I6 and is very similar to it but is not quite the same. In kit code, |O.P| means
|
||||
"the value of the property P for the object O", but where |P| is the metadata
|
||||
array for the property. In genuine Inform 6, |O.P| expects |P| to be the actual
|
||||
VM-property. The following functions need the latter interpretation in order to work.
|
||||
|
||||
=
|
||||
void I6TargetCode::end_generation(code_generator *cgt, code_generation *gen) {
|
||||
segmentation_pos saved = CodeGen::select(gen, functions_I7CGS);
|
||||
text_stream *OUT = CodeGen::current(gen);
|
||||
WRITE("[ _final_read_pval K o p t;\n");
|
||||
@<Most general implementation of !propertyvalue@>;
|
||||
@<Most general implementation of !propertyexists@>;
|
||||
@<Most general implementation of !propertyarray@>;
|
||||
@<Most general implementation of !propertylength@>;
|
||||
@<Most general implementation of writing to a property@>;
|
||||
@<Implementation of !messageX@>;
|
||||
CodeGen::deselect(gen, saved);
|
||||
}
|
||||
|
||||
@ See //Inform 6 Objects// for the runtime contents of the array of property
|
||||
metadata |p|. The following is more or less a safe general-purpose wrapper for
|
||||
the Inform 6 operator |.|, used as an rvalue, in cases where we cannot prove
|
||||
it would be safe to use |.| directly:
|
||||
|
||||
@<Most general implementation of !propertyvalue@> =
|
||||
WRITE("[ _final_propertyvalue K o p t;\n");
|
||||
WRITE(" if (K == OBJECT_TY) {\n");
|
||||
WRITE(" if (metaclass(o) == Object) {\n");
|
||||
WRITE(" t = p-->0; p = p-->1;\n");
|
||||
|
@ -782,46 +840,11 @@ void I6TargetCode::end_generation(code_generator *cgt, code_generation *gen) {
|
|||
WRITE(" return (t.(p-->1))-->(o+COL_HSIZE);\n");
|
||||
WRITE(" }\n");
|
||||
WRITE("];\n");
|
||||
WRITE("[ _final_write_pval K o p v t;\n");
|
||||
WRITE(" if (K == OBJECT_TY) {\n");
|
||||
WRITE(" if (metaclass(o) == Object) {\n");
|
||||
WRITE(" t = p-->0; p = p-->1; ! print \"give \", o, \" \", p, \"^\";\n");
|
||||
WRITE(" if (t == 2) { if (v) give o p; else give o ~p; }\n");
|
||||
WRITE(" else { if (o provides p) o.p = v; }\n");
|
||||
WRITE(" }\n");
|
||||
WRITE(" } else {\n");
|
||||
WRITE(" ((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE) = v;\n");
|
||||
WRITE(" }\n");
|
||||
WRITE("];\n");
|
||||
WRITE("[ _final_read_paddr K o p v t;\n");
|
||||
WRITE(" if (K ~= OBJECT_TY) return 0;\n");
|
||||
WRITE(" t = p-->0; p = p-->1; ! print \"give \", o, \" \", p, \"^\";\n");
|
||||
WRITE(" if (t == 2) return 0;\n");
|
||||
WRITE(" return o.&p;\n");
|
||||
WRITE("];\n");
|
||||
WRITE("[ _final_read_plen K o p v t;\n");
|
||||
WRITE(" if (K ~= OBJECT_TY) return 0;\n");
|
||||
WRITE(" t = p-->0; p = p-->1; ! print \"give \", o, \" \", p, \"^\";\n");
|
||||
WRITE(" if (t == 2) return 0;\n");
|
||||
WRITE(" return o.#p;\n");
|
||||
WRITE("];\n");
|
||||
WRITE("[ _final_message0 o p q x a rv;\n");
|
||||
WRITE(" if (p-->0 == 2) return 0;\n");
|
||||
WRITE(" q = p-->1; return o.q();\n");
|
||||
WRITE("];\n");
|
||||
WRITE("[ _final_message1 o p v1 q x a rv;\n");
|
||||
WRITE(" if (p-->0 == 2) return 0;\n");
|
||||
WRITE(" q = p-->1; return o.q(v1);\n");
|
||||
WRITE("];\n");
|
||||
WRITE("[ _final_message2 o p v1 v2 q x a rv;\n");
|
||||
WRITE(" if (p-->0 == 2) return 0;\n");
|
||||
WRITE(" q = p-->1; return o.q(v1, v2);\n");
|
||||
WRITE("];\n");
|
||||
WRITE("[ _final_message3 o p v1 v2 v3 q x a rv;\n");
|
||||
WRITE(" if (p-->0 == 2) return 0;\n");
|
||||
WRITE(" q = p-->1; return o.q(v1, v2, v3);\n");
|
||||
WRITE("];\n");
|
||||
WRITE("[ _final_provides K o p holder;\n");
|
||||
|
||||
@ Similarly, this is a safe wrapper for |provides|:
|
||||
|
||||
@<Most general implementation of !propertyexists@> =
|
||||
WRITE("[ _final_propertyexists K o p holder;\n");
|
||||
WRITE("if (K == OBJECT_TY) {\n");
|
||||
WRITE(" if ((o) && (metaclass(o) == Object)) {\n");
|
||||
WRITE(" if ((p-->0 == 2) || (o provides p-->1)) {\n");
|
||||
|
@ -845,24 +868,154 @@ void I6TargetCode::end_generation(code_generator *cgt, code_generation *gen) {
|
|||
WRITE(" }\n");
|
||||
WRITE("}\n");
|
||||
WRITE("rfalse; ];\n");
|
||||
WRITE("[ _final_xwrite_pval K o p v t;\n");
|
||||
WRITE("if (K == OBJECT_TY) {\n");
|
||||
WRITE(" if (p-->0 == 2) {\n");
|
||||
WRITE(" if (v) give o p-->1; else give o ~(p-->1);\n");
|
||||
WRITE(" } else {\n");
|
||||
WRITE(" o.(p-->1) = v;\n");
|
||||
WRITE(" }\n");
|
||||
WRITE("} else {\n");
|
||||
WRITE(" ((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE) = v;\n");
|
||||
WRITE("}\n");
|
||||
|
||||
@ And this for |.&|. Note that we always return 0 if the owner is not an object.
|
||||
|
||||
@<Most general implementation of !propertyarray@> =
|
||||
WRITE("[ _final_propertyarray K o p v t;\n");
|
||||
WRITE(" if (K ~= OBJECT_TY) return 0;\n");
|
||||
WRITE(" t = p-->0; p = p-->1;\n");
|
||||
WRITE(" if (t == 2) return 0;\n");
|
||||
WRITE(" return o.&p;\n");
|
||||
WRITE("];\n");
|
||||
|
||||
WRITE("Constant i7_lvalue_SET = 1;\n");
|
||||
WRITE("Constant i7_lvalue_PREDEC = 2;\n");
|
||||
WRITE("Constant i7_lvalue_POSTDEC = 3;\n");
|
||||
WRITE("Constant i7_lvalue_PREINC = 4;\n");
|
||||
WRITE("Constant i7_lvalue_POSTINC = 5;\n");
|
||||
WRITE("Constant i7_lvalue_SETBIT = 6;\n");
|
||||
WRITE("Constant i7_lvalue_CLEARBIT = 7;\n");
|
||||
CodeGen::deselect(gen, saved);
|
||||
}
|
||||
@ And this for |.#|. Again, we always return 0 if the owner is not an object.
|
||||
|
||||
@<Most general implementation of !propertylength@> =
|
||||
WRITE("[ _final_propertylength K o p v t;\n");
|
||||
WRITE(" if (K ~= OBJECT_TY) return 0;\n");
|
||||
WRITE(" t = p-->0; p = p-->1;\n");
|
||||
WRITE(" if (t == 2) return 0;\n");
|
||||
WRITE(" return o.#p;\n");
|
||||
WRITE("];\n");
|
||||
|
||||
@ And this is a safe way to write to or otherwise alter |O.P|, laboriously
|
||||
written out as seven functions. (Speed is more important than conciseness here.)
|
||||
|
||||
@<Most general implementation of writing to a property@> =
|
||||
WRITE("[ _final_store_property K o p v t;\n");
|
||||
WRITE(" if (K == OBJECT_TY) {\n");
|
||||
WRITE(" if (metaclass(o) == Object) {\n");
|
||||
WRITE(" t = p-->0; p = p-->1;\n");
|
||||
WRITE(" if (t == 2) {\n");
|
||||
WRITE(" if (v) give o p; else give o ~p;\n");
|
||||
WRITE(" } else if (o provides p) {\n");
|
||||
WRITE(" o.p = v;\n");
|
||||
WRITE(" }\n");
|
||||
WRITE(" }\n");
|
||||
WRITE(" } else {\n");
|
||||
WRITE(" ((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE) = v;\n");
|
||||
WRITE(" }\n");
|
||||
WRITE("];\n");
|
||||
WRITE("[ _final_preinc_property K o p t;\n");
|
||||
WRITE(" if (K == OBJECT_TY) {\n");
|
||||
WRITE(" if (metaclass(o) == Object) {\n");
|
||||
WRITE(" t = p-->0; p = p-->1;\n");
|
||||
WRITE(" if (t == 2) {\n");
|
||||
WRITE(" if (o has p) { give o ~p; rfalse; } give o p; rtrue;\n");
|
||||
WRITE(" } else if (o provides p) {\n");
|
||||
WRITE(" return ++(o.p);\n");
|
||||
WRITE(" }\n");
|
||||
WRITE(" }\n");
|
||||
WRITE(" } else {\n");
|
||||
WRITE(" return ++(((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE));\n");
|
||||
WRITE(" }\n");
|
||||
WRITE(" return 0;\n");
|
||||
WRITE("];\n");
|
||||
WRITE("[ _final_predec_property K o p t;\n");
|
||||
WRITE(" if (K == OBJECT_TY) {\n");
|
||||
WRITE(" if (metaclass(o) == Object) {\n");
|
||||
WRITE(" t = p-->0; p = p-->1;\n");
|
||||
WRITE(" if (t == 2) {\n");
|
||||
WRITE(" if (o has p) { give o ~p; rfalse; } give o p; rtrue;\n");
|
||||
WRITE(" } else if (o provides p) {\n");
|
||||
WRITE(" return --(o.p);\n");
|
||||
WRITE(" }\n");
|
||||
WRITE(" }\n");
|
||||
WRITE(" } else {\n");
|
||||
WRITE(" return --(((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE));\n");
|
||||
WRITE(" }\n");
|
||||
WRITE(" return 0;\n");
|
||||
WRITE("];\n");
|
||||
WRITE("[ _final_postinc_property K o p t;\n");
|
||||
WRITE(" if (K == OBJECT_TY) {\n");
|
||||
WRITE(" if (metaclass(o) == Object) {\n");
|
||||
WRITE(" t = p-->0; p = p-->1;\n");
|
||||
WRITE(" if (t == 2) {\n");
|
||||
WRITE(" if (o has p) { give o ~p; rtrue; } give o p; rfalse;\n");
|
||||
WRITE(" } else if (o provides p) {\n");
|
||||
WRITE(" return (o.p)++;\n");
|
||||
WRITE(" }\n");
|
||||
WRITE(" }\n");
|
||||
WRITE(" } else {\n");
|
||||
WRITE(" return (((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE))++;\n");
|
||||
WRITE(" }\n");
|
||||
WRITE(" return 0;\n");
|
||||
WRITE("];\n");
|
||||
WRITE("[ _final_postdec_property K o p t;\n");
|
||||
WRITE(" if (K == OBJECT_TY) {\n");
|
||||
WRITE(" if (metaclass(o) == Object) {\n");
|
||||
WRITE(" t = p-->0; p = p-->1;\n");
|
||||
WRITE(" if (t == 2) {\n");
|
||||
WRITE(" if (o has p) { give o ~p; rtrue; } give o p; rfalse;\n");
|
||||
WRITE(" } else if (o provides p) {\n");
|
||||
WRITE(" return (o.p)--;\n");
|
||||
WRITE(" }\n");
|
||||
WRITE(" }\n");
|
||||
WRITE(" } else {\n");
|
||||
WRITE(" return (((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE))--;\n");
|
||||
WRITE(" }\n");
|
||||
WRITE(" return 0;\n");
|
||||
WRITE("];\n");
|
||||
WRITE("[ _final_setbit_property K o p v t;\n");
|
||||
WRITE(" if (K == OBJECT_TY) {\n");
|
||||
WRITE(" if (metaclass(o) == Object) {\n");
|
||||
WRITE(" t = p-->0; p = p-->1;\n");
|
||||
WRITE(" if (t == 2) {\n");
|
||||
WRITE(" if (v & 1) give o p;\n");
|
||||
WRITE(" } else if (o provides p) {\n");
|
||||
WRITE(" o.p = o.p | v;\n");
|
||||
WRITE(" }\n");
|
||||
WRITE(" }\n");
|
||||
WRITE(" } else {\n");
|
||||
WRITE(" ((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE) =\n");
|
||||
WRITE(" ((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE) | v;\n");
|
||||
WRITE(" }\n");
|
||||
WRITE("];\n");
|
||||
WRITE("[ _final_clearbit_property K o p v t;\n");
|
||||
WRITE(" if (K == OBJECT_TY) {\n");
|
||||
WRITE(" if (metaclass(o) == Object) {\n");
|
||||
WRITE(" t = p-->0; p = p-->1;\n");
|
||||
WRITE(" if (t == 2) {\n");
|
||||
WRITE(" if (v & 1) give o ~p;\n");
|
||||
WRITE(" } else if (o provides p) {\n");
|
||||
WRITE(" o.p = o.p & ~v;\n");
|
||||
WRITE(" }\n");
|
||||
WRITE(" }\n");
|
||||
WRITE(" } else {\n");
|
||||
WRITE(" ((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE) =\n");
|
||||
WRITE(" ((value_property_holders-->K).(p-->1))-->(o+COL_HSIZE) & ~v;\n");
|
||||
WRITE(" }\n");
|
||||
WRITE("];\n");
|
||||
|
||||
@ It's not entirely clear what the result of trying to send a message to an
|
||||
either/or property ought to be: nobody should ever do that. We're going to say
|
||||
that it's 0 here.
|
||||
|
||||
@<Implementation of !messageX@> =
|
||||
WRITE("[ _final_message0 o p q x a rv;\n");
|
||||
WRITE(" if (p-->0 == 2) return 0;\n");
|
||||
WRITE(" q = p-->1; return o.q();\n");
|
||||
WRITE("];\n");
|
||||
WRITE("[ _final_message1 o p v1 q x a rv;\n");
|
||||
WRITE(" if (p-->0 == 2) return 0;\n");
|
||||
WRITE(" q = p-->1; return o.q(v1);\n");
|
||||
WRITE("];\n");
|
||||
WRITE("[ _final_message2 o p v1 v2 q x a rv;\n");
|
||||
WRITE(" if (p-->0 == 2) return 0;\n");
|
||||
WRITE(" q = p-->1; return o.q(v1, v2);\n");
|
||||
WRITE("];\n");
|
||||
WRITE("[ _final_message3 o p v1 v2 v3 q x a rv;\n");
|
||||
WRITE(" if (p-->0 == 2) return 0;\n");
|
||||
WRITE(" q = p-->1; return o.q(v1, v2, v3);\n");
|
||||
WRITE("];\n");
|
||||
|
|
Loading…
Reference in a new issue