mirror of
https://github.com/ganelson/inform.git
synced 2024-07-05 16:44:21 +03:00
941 lines
116 KiB
HTML
941 lines
116 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>14/rv</title>
|
|
<meta name="viewport" content="width=device-width initial-scale=1">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
</head>
|
|
<body>
|
|
<nav role="navigation">
|
|
<h1><a href="../webs.html">Sources</a></h1>
|
|
<ul>
|
|
<li><a href="../compiler.html"><b>compiler tools</b></a></li>
|
|
<li><a href="../other.html">other tools</a></li>
|
|
<li><a href="../extensions.html">extensions and kits</a></li>
|
|
<li><a href="../units.html">unit test tools</a></li>
|
|
</ul>
|
|
<h2>Compiler Webs</h2>
|
|
<ul>
|
|
<li><a href="../inbuild/index.html">inbuild</a></li>
|
|
<li><a href="../inform7/index.html">inform7</a></li>
|
|
<li><a href="../inter/index.html">inter</a></li>
|
|
</ul>
|
|
<h2>Inbuild Modules</h2>
|
|
<ul>
|
|
<li><a href="../inbuild-module/index.html">inbuild</a></li>
|
|
<li><a href="../arch-module/index.html">arch</a></li>
|
|
<li><a href="../words-module/index.html">words</a></li>
|
|
<li><a href="../syntax-module/index.html">syntax</a></li>
|
|
<li><a href="../html-module/index.html">html</a></li>
|
|
</ul>
|
|
<h2>Inform7 Modules</h2>
|
|
<ul>
|
|
<li><a href="../core-module/index.html">core</a></li>
|
|
<li><a href="../problems-module/index.html">problems</a></li>
|
|
<li><a href="../inflections-module/index.html">inflections</a></li>
|
|
<li><a href="../linguistics-module/index.html">linguistics</a></li>
|
|
<li><a href="../kinds-module/index.html">kinds</a></li>
|
|
<li><a href="../if-module/index.html">if</a></li>
|
|
<li><a href="../multimedia-module/index.html">multimedia</a></li>
|
|
<li><a href="../index-module/index.html">index</a></li>
|
|
</ul>
|
|
<h2>Inter Modules</h2>
|
|
<ul>
|
|
<li><a href="../inter-module/index.html">inter</a></li>
|
|
<li><a href="../building-module/index.html">building</a></li>
|
|
<li><a href="../codegen-module/index.html">codegen</a></li>
|
|
</ul>
|
|
<h2>Foundation</h2>
|
|
<ul>
|
|
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
|
|
</ul>
|
|
|
|
|
|
</nav>
|
|
<main role="main">
|
|
|
|
<!--Weave of '14/lv' generated by 7-->
|
|
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Modules</a></li><li><a href="index.html">core</a></li><li><a href="index.html#14">Chapter 14: Specifications</a></li><li><b>Lvalues</b></li></ul><p class="purpose">Utility functions for specifications representing lvalues, that is, storage locations for values at run-time.</p>
|
|
|
|
<ul class="toc"><li><a href="#SP1">§1. Creation</a></li><li><a href="#SP7">§7. Testing</a></li><li><a href="#SP10">§10. Pretty-printing</a></li><li><a href="#SP12">§12. Compilation</a></li><li><a href="#SP14">§14. Rvalue compilation</a></li><li><a href="#SP15">§15. Lvalue compilation</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. Creation. </b>"Lvalues" can occur on the left of an assignment sign: they are values
|
|
which can be written to.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><code class="display"><span class="extract">LOCAL_VARIABLE_NT</span></code> refers to a specific local variable, so it has meaning
|
|
only within the routine currently being compiled. A <code class="display"><span class="extract">local_variable</span></code> pointer
|
|
is attached. There are no references or arguments.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><code class="display"><span class="extract">NONLOCAL_VARIABLE_NT</span></code> refers to a variable of any other scope: that is, a
|
|
global variable, or perhaps a rulebook, action or activity variable. The
|
|
important distinction between these other scopes and local scope is
|
|
essentially that local variables live on the I6 call-stack and have only a
|
|
local namespace, whereas others correspond to array entries or global I6
|
|
variables and share a global namespace. (It is basically a matter of
|
|
implementation convenience which makes us divide the stock of variables
|
|
into two different species this way.) A <code class="display"><span class="extract">instance *</span></code> pointer is attached,
|
|
identifying the name of the variable in question. There are no
|
|
arguments.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><code class="display"><span class="extract">PROPERTY_VALUE_NT</span></code> represents a given (value-)property of a given object,
|
|
not the name of a property in abstract. Thus "description of the Police
|
|
Commissioner" qualifies, but "description" does not. There are two arguments:
|
|
the property and the object which possesses it, respectively.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><code class="display"><span class="extract">TABLE_ENTRY_NT</span></code> represents a given entry to a table, which can be referred
|
|
to in several different ways. There are four different kinds of table reference,
|
|
distinguished by the number of arguments found:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<ul class="items"><li>(1) 1 argument. By column name only, the table and row to be understood from
|
|
context because we have selected a row in the surrounding source text.
|
|
</li><li>(2) 2 arguments. Used as a condition to see if a value is listed in a
|
|
given column of a given table. Argument 0 must be a constant of kind
|
|
"table column", argument 1 any value of kind "table". (Argument 0
|
|
has to be a constant because it is not type-safe to allow looping through
|
|
columns, say: different columns have different kinds, and the compiler
|
|
would be unable to tell the kind of the result of such a lookup. The
|
|
same doesn't apply to argument 1, perhaps oddly, because Inform requires
|
|
that every column name have the same kind in every table using it. So
|
|
the choice of table does not have to be a constant, and this allows
|
|
for some interesting data structures to be built.)
|
|
</li><li>(3) 3 arguments. An explicitly specified entry. The arguments are the
|
|
table column, row number, and table respectively.
|
|
</li><li>(4) 4 arguments. A reference to the X corresponding to a Y value of Z in table T.
|
|
The arguments are X, Y, Z, T respectively.
|
|
</li></ul>
|
|
<p class="inwebparagraph"><code class="display"><span class="extract">LIST_ENTRY_NT</span></code> represents a given entry in a list, which is much simpler:
|
|
there are two arguments, the list and the numerical index, which counts from 1.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Note that property names, table names, and lists themselves are not storage
|
|
items as such — they are places where storage items are found. They are
|
|
all in the <code class="display"><span class="extract">VALUE</span></code> family.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP2"></a><b>§2. </b>And here are some convenient creators. Variables:
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Lvalues::new_LOCAL_VARIABLE</span><span class="plain">(</span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="constant">LOCAL_VARIABLE_NT</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_text</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_constant_local_variable</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"bad local variable"</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Lvalues::new_actual_NONLOCAL_VARIABLE</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="constant">NONLOCAL_VARIABLE_NT</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_constant_nonlocal_variable</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">nlv</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_text</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">nlv</span><span class="plain">-></span><span class="element">name</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Lvalues::new_LOCAL_VARIABLE is used in 4/am (<a href="4-am.html#SP38_1">§38.1</a>), 10/teav (<a href="10-teav.html#SP10_1">§10.1</a>, <a href="10-teav.html#SP15">§15</a>), 12/is (<a href="12-is.html#SP6">§6</a>), 12/dtd (<a href="12-dtd.html#SP23">§23</a>), 12/cdp (<a href="12-cdp.html#SP5">§5</a>), 15/ma (<a href="15-ma.html#SP13">§13</a>), 25/cii (<a href="25-cii.html#SP1_2_1">§1.2.1</a>, <a href="25-cii.html#SP6">§6</a>), 25/cp (<a href="25-cp.html#SP5_3_5_3">§5.3.5.3</a>).</p>
|
|
|
|
<p class="endnote">The function Lvalues::new_actual_NONLOCAL_VARIABLE is used in 5/nv (<a href="5-nv.html#SP7_3">§7.3</a>), 9/tc (<a href="9-tc.html#SP5_4_2_2">§5.4.2.2</a>), 9/pk (<a href="9-pk.html#SP2">§2</a>), 10/teav (<a href="10-teav.html#SP16">§16</a>), 11/sm (<a href="11-sm.html#SP15">§15</a>), 12/ap (<a href="12-ap.html#SP9_5_2">§9.5.2</a>), 25/ci (<a href="25-ci.html#SP3_2_3_3_1_1">§3.2.3.3.1.1</a>, <a href="25-ci.html#SP3_2_3_4_1_1">§3.2.3.4.1.1</a>, <a href="25-ci.html#SP3_2_3_3_1_2_1">§3.2.3.3.1.2.1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b>Table entries have their arguments filled in by the relevant routines in
|
|
"Meaning List Conversion":
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Lvalues::new_TABLE_ENTRY</span><span class="plain">(</span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">ParseTree::new_with_words</span><span class="plain">(</span><span class="constant">TABLE_ENTRY_NT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Lvalues::new_TABLE_ENTRY is used in 10/teav (<a href="10-teav.html#SP21_1">§21.1</a>, <a href="10-teav.html#SP21_2">§21.2</a>, <a href="10-teav.html#SP21_3">§21.3</a>, <a href="10-teav.html#SP21_4">§21.4</a>, <a href="10-teav.html#SP21_5">§21.5</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. </b>List entries:
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Lvalues::new_LIST_ENTRY</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">owner</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">index</span><span class="plain">) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="constant">LIST_ENTRY_NT</span><span class="plain">);</span>
|
|
<span class="identifier">spec</span><span class="plain">-></span><span class="element">down</span><span class="plain"> = </span><span class="identifier">owner</span><span class="plain">;</span>
|
|
<span class="identifier">spec</span><span class="plain">-></span><span class="element">down</span><span class="plain">-></span><span class="element">next</span><span class="plain"> = </span><span class="identifier">index</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Lvalues::new_LIST_ENTRY is used in 10/teav (<a href="10-teav.html#SP10_3">§10.3</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§5. </b>Property values are constructed out of what's often only implied text:
|
|
for instance, "description" sometimes means "the description [of the
|
|
<code class="display"><span class="extract">self</span></code> object]". We give them a word range which is minimal such that it
|
|
must contain word ranges of both property and owner, if given. Thus
|
|
"carrying capacity of the trunk" will result from "carrying capacity"
|
|
and "trunk". This is not very scientific, perhaps, but it's done only to
|
|
make problem messages more readable.
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Lvalues::new_PROPERTY_VALUE</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">owner</span><span class="plain">) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="constant">PROPERTY_VALUE_NT</span><span class="plain">);</span>
|
|
<span class="identifier">spec</span><span class="plain">-></span><span class="element">down</span><span class="plain"> = </span><span class="identifier">prop</span><span class="plain">;</span>
|
|
<span class="identifier">spec</span><span class="plain">-></span><span class="element">down</span><span class="plain">-></span><span class="element">next</span><span class="plain"> = </span><span class="identifier">owner</span><span class="plain">;</span>
|
|
<span class="identifier">ParseTree::set_text</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">,</span>
|
|
<span class="identifier">Wordings::union</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">), </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">owner</span><span class="plain">)));</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Lvalues::new_PROPERTY_VALUE is used in 10/teav (<a href="10-teav.html#SP13">§13</a>), 11/sm (<a href="11-sm.html#SP17_1">§17.1</a>), 12/is (<a href="12-is.html#SP8">§8</a>), 14/ds2 (<a href="14-ds2.html#SP19_3_1_1">§19.3.1.1</a>), 15/ma (<a href="15-ma.html#SP13">§13</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§6. </b>On the other hand we sometimes want to refer to the property in abstract.
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Lvalues::underlying_property</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">PROPERTY_VALUE_NT</span><span class="plain">)) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_self_object_constant</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">-></span><span class="element">down</span><span class="plain">-></span><span class="element">next</span><span class="plain">))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">-></span><span class="element">down</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no underlying property"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Lvalues::underlying_property is used in 26/ts (<a href="26-ts.html#SP12">§12</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§7. Testing. </b></p>
|
|
|
|
<pre class="display">
|
|
<span class="identifier">node_type_t</span><span class="plain"> </span><span class="functiontext">Lvalues::get_storage_form</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTreeUsage::is_lvalue</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="constant">UNKNOWN_NT</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Lvalues::get_storage_form is used in 5/nv (<a href="5-nv.html#SP25">§25</a>), 9/ma (<a href="9-ma.html#SP3_3_39">§3.3.39</a>, <a href="9-ma.html#SP3_3_41_3">§3.3.41.3</a>), 10/varc (<a href="10-varc.html#SP13_4_1">§13.4.1</a>), 11/bas (<a href="11-bas.html#SP19">§19</a>), 11/sm (<a href="11-sm.html#SP4">§4</a>), 12/ter (<a href="12-ter.html#SP8">§8</a>), 12/dtd (<a href="12-dtd.html#SP10">§10</a>), 14/sp (<a href="14-sp.html#SP7_5">§7.5</a>), 14/ds2 (<a href="14-ds2.html#SP11_9_1_1_5_2">§11.9.1.1.5.2</a>, <a href="14-ds2.html#SP11_9_1_1_8">§11.9.1.1.8</a>), 22/ptd (<a href="22-ptd.html#SP18">§18</a>), 25/cii (<a href="25-cii.html#SP3_5_4">§3.5.4</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. </b>More specifically:
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Lvalues::is_actual_NONLOCAL_VARIABLE</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">NONLOCAL_VARIABLE_NT</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="functiontext">Lvalues::get_nonlocal_variable_if_any</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">NONLOCAL_VARIABLE_NT</span><span class="plain">))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::get_constant_nonlocal_variable</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Lvalues::is_constant_NONLOCAL_VARIABLE</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
|
|
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain"> = </span><span class="functiontext">Lvalues::get_nonlocal_variable_if_any</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nlv</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::is_constant</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Lvalues::is_actual_NONLOCAL_VARIABLE is used in 9/ma (<a href="9-ma.html#SP3_2">§3.2</a>), 9/pd (<a href="9-pd.html#SP5_6">§5.6</a>), 12/ter (<a href="12-ter.html#SP7">§7</a>).</p>
|
|
|
|
<p class="endnote">The function Lvalues::get_nonlocal_variable_if_any is used in <a href="#SP9">§9</a>, 5/nv (<a href="5-nv.html#SP23">§23</a>), 10/cad (<a href="10-cad.html#SP3">§3</a>, <a href="10-cad.html#SP4">§4</a>), 12/ter (<a href="12-ter.html#SP8_3">§8.3</a>), 19/tb (<a href="19-tb.html#SP24_5">§24.5</a>), 25/cii (<a href="25-cii.html#SP3_1_1_2">§3.1.1.2</a>, <a href="25-cii.html#SP3_5_4_2">§3.5.4.2</a>).</p>
|
|
|
|
<p class="endnote">The function Lvalues::is_constant_NONLOCAL_VARIABLE is used in 9/tc (<a href="9-tc.html#SP4_4">§4.4</a>), 18/lc (<a href="18-lc.html#SP8_1">§8.1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9"></a><b>§9. </b>Not all non-local variables are global — some have scope local to rulebooks,
|
|
actions and the like:
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Lvalues::is_global_variable</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Lvalues::get_nonlocal_variable_if_any</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Lvalues::is_global_variable is used in 12/cad (<a href="12-cad.html#SP4">§4</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10"></a><b>§10. Pretty-printing. </b></p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Lvalues::write_out_in_English</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
|
|
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LOCAL_VARIABLE_NT:</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"a temporary named value"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NONLOCAL_VARIABLE_NT:</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
|
|
<span class="identifier">Kinds::Textual::write_articled</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">ParseTree::get_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">));</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" that varies"</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"a non-temporary variable"</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">TABLE_ENTRY_NT:</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"a table entry"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LIST_ENTRY_NT:</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"a list entry"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">PROPERTY_VALUE_NT:</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ParseTree::no_children</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">) == </span><span class="constant">2</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">-></span><span class="element">down</span><span class="plain">, </span><span class="identifier">CON_property</span><span class="plain">))) {</span>
|
|
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_property</span><span class="plain">(</span>
|
|
<span class="identifier">spec</span><span class="plain">-></span><span class="element">down</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"a property whose value is "</span><span class="plain">);</span>
|
|
<span class="identifier">Kinds::Textual::write_articled</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="functiontext">Properties::Valued::kind</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">));</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"a property belonging to something"</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="identifier">default:</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"a stored value"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Lvalues::write_out_in_English is used in 14/sp (<a href="14-sp.html#SP6">§6</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11"></a><b>§11. </b>And the log.
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Lvalues::log</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LOCAL_VARIABLE_NT:</span><span class="plain"> {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">ParseTree::get_constant_local_variable</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"(%~L;$u)"</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">, </span><span class="functiontext">LocalVariables::unproblematic_kind</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">));</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NONLOCAL_VARIABLE_NT:</span><span class="plain"> {</span>
|
|
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">q</span><span class="plain"> = </span><span class="identifier">ParseTree::get_constant_nonlocal_variable</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"($Z)"</span><span class="plain">, </span><span class="identifier">q</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Lvalues::log is used in 7/ptu (<a href="7-ptu.html#SP14_1">§14.1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12"></a><b>§12. Compilation. </b></p>
|
|
|
|
<pre class="display">
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">Lvalues::to_kind</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">spec</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Rvalues::to_kind on NULL"</span><span class="plain">);</span>
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LOCAL_VARIABLE_NT:</span><span class="plain"> </span><<span class="cwebmacro">Return the kind of a local variable</span> <span class="cwebmacronumber">12.1</span>><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NONLOCAL_VARIABLE_NT:</span><span class="plain"> </span><<span class="cwebmacro">Return the kind of a non-local variable</span> <span class="cwebmacronumber">12.2</span>><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">TABLE_ENTRY_NT:</span><span class="plain"> </span><<span class="cwebmacro">Return the kind of a table entry</span> <span class="cwebmacronumber">12.3</span>><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LIST_ENTRY_NT:</span><span class="plain"> </span><<span class="cwebmacro">Return the kind of a list entry</span> <span class="cwebmacronumber">12.4</span>><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">PROPERTY_VALUE_NT:</span><span class="plain"> </span><<span class="cwebmacro">Return the kind of a property value</span> <span class="cwebmacronumber">12.5</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K_value</span><span class="plain">; </span><span class="comment">a generic answer for storage of an unknown sort</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Lvalues::to_kind is used in 14/sp (<a href="14-sp.html#SP1">§1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12_1"></a><b>§12.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Return the kind of a local variable</span> <span class="cwebmacronumber">12.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">ParseTree::get_constant_local_variable</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">K_value</span><span class="plain">; </span><span class="comment">for "existing"</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::unproblematic_kind</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP12">§12</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12_2"></a><b>§12.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Return the kind of a non-local variable</span> <span class="cwebmacronumber">12.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain"> = </span><span class="identifier">ParseTree::get_constant_nonlocal_variable</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::kind</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP12">§12</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12_3"></a><b>§12.3. </b>In every form of table entry, argument 0 is the column, and the column
|
|
is enough to determine the kind:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Return the kind of a table entry</span> <span class="cwebmacronumber">12.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::no_children</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">) > </span><span class="constant">0</span><span class="plain">) { </span><span class="comment">i.e., always, for actual table entry specifications</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">fts</span><span class="plain"> = </span><span class="identifier">spec</span><span class="plain">-></span><span class="element">down</span><span class="plain">;</span>
|
|
<span class="reserved">table_column</span><span class="plain"> *</span><span class="identifier">tc</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_table_column</span><span class="plain">(</span><span class="identifier">fts</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Tables::Columns::get_kind</span><span class="plain">(</span><span class="identifier">tc</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">; </span><span class="comment">can happen when scanning phrase arguments, which are generic</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP12">§12</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12_4"></a><b>§12.4. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Return the kind of a list entry</span> <span class="cwebmacronumber">12.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::no_children</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">) == </span><span class="constant">2</span><span class="plain">) { </span><span class="comment">i.e., always, for actual list entry specifications</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K1</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">-></span><span class="element">down</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::unary_construction_material</span><span class="plain">(</span><span class="identifier">K1</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Kinds::unary_construction_material</span><span class="plain">(</span><span class="identifier">K1</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K_value</span><span class="plain">; </span><span class="comment">to help the type-checker produce better problem messages</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">; </span><span class="comment">can happen when scanning phrase arguments, which are generic</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP12">§12</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12_5"></a><b>§12.5. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Return the kind of a property value</span> <span class="cwebmacronumber">12.5</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::no_children</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">) == </span><span class="constant">2</span><span class="plain">) {</span>
|
|
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_property</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">-></span><span class="element">down</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">prn</span><span class="plain">) && (</span><span class="functiontext">Properties::is_either_or</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Properties::Valued::kind</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K_value</span><span class="plain">; </span><span class="comment">to help the type-checker produce better problem messages</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">; </span><span class="comment">can happen when scanning phrase arguments, which are generic</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP12">§12</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP13"></a><b>§13. </b></p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">Lvalues::get_local_variable_if_any</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">LOCAL_VARIABLE_NT</span><span class="plain">))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::get_constant_local_variable</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Lvalues::get_local_variable_if_any is used in 14/ds2 (<a href="14-ds2.html#SP11_9_1_1_5">§11.9.1.1.5</a>), 25/cii (<a href="25-cii.html#SP3_5_2">§3.5.2</a>, <a href="25-cii.html#SP3_5_3">§3.5.3</a>, <a href="25-cii.html#SP3_5_4_2">§3.5.4.2</a>, <a href="25-cii.html#SP3_7">§3.7</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14"></a><b>§14. Rvalue compilation. </b>We finally reach the compilation routine which produces an I6 expression
|
|
evaluating to the contents of the storage item specified.
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Lvalues::compile</span><span class="plain">(</span><span class="identifier">value_holster</span><span class="plain"> *</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec_found</span><span class="plain">) {</span>
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">)) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LOCAL_VARIABLE_NT:</span><span class="plain"> </span><<span class="cwebmacro">Compile a local variable specification</span> <span class="cwebmacronumber">14.1</span>><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NONLOCAL_VARIABLE_NT:</span><span class="plain"> </span><<span class="cwebmacro">Compile a non-local variable specification</span> <span class="cwebmacronumber">14.2</span>><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">PROPERTY_VALUE_NT:</span><span class="plain"> </span><<span class="cwebmacro">Compile a property value specification</span> <span class="cwebmacronumber">14.3</span>><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LIST_ENTRY_NT:</span><span class="plain"> </span><<span class="cwebmacro">Compile a list entry specification</span> <span class="cwebmacronumber">14.4</span>><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">TABLE_ENTRY_NT:</span><span class="plain"> </span><<span class="cwebmacro">Compile a table entry specification</span> <span class="cwebmacronumber">14.5</span>><span class="plain">;</span>
|
|
<span class="identifier">default:</span><span class="plain"> </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Offender: $P\n"</span><span class="plain">, </span><span class="identifier">spec_found</span><span class="plain">);</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"unable to compile this STORAGE species"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Lvalues::compile is used in 14/cfs (<a href="14-cfs.html#SP7">§7</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14_1"></a><b>§14.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Compile a local variable specification</span> <span class="cwebmacronumber">14.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">ParseTree::get_constant_local_variable</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">);</span>
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">lvar_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="constant">8</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Bad: %08x\n"</span><span class="plain">, </span><span class="identifier">spec_found</span><span class="plain">);</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Compiled never-specified LOCAL VARIABLE SP"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">lvar_s</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP14">§14</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14_2"></a><b>§14.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Compile a non-local variable specification</span> <span class="cwebmacronumber">14.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain"> = </span><span class="identifier">ParseTree::get_constant_nonlocal_variable</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">);</span>
|
|
<span class="functiontext">NonlocalVariables::emit_lvalue</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP14">§14</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14_3"></a><b>§14.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Compile a property value specification</span> <span class="cwebmacronumber">14.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::no_children</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">) != </span><span class="constant">2</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"malformed PROPERTY_OF SP"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">spec_found</span><span class="plain">-></span><span class="element">down</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"PROPERTY_OF with null arg 0"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">spec_found</span><span class="plain">-></span><span class="element">down</span><span class="plain">-></span><span class="element">next</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"PROPERTY_OF with null arg 1"</span><span class="plain">);</span>
|
|
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_property</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">-></span><span class="element">down</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prn</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"PROPERTY_OF with null property"</span><span class="plain">);</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">prop_spec</span><span class="plain"> = </span><span class="identifier">spec_found</span><span class="plain">-></span><span class="element">down</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">owner</span><span class="plain"> = </span><span class="identifier">spec_found</span><span class="plain">-></span><span class="element">down</span><span class="plain">-></span><span class="element">next</span><span class="plain">;</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">owner_kind</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">owner</span><span class="plain">);</span>
|
|
|
|
<<span class="cwebmacro">Reinterpret the "self" for what are unambiguously conditions of single things</span> <span class="cwebmacronumber">14.3.1</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">JUST_ROUTINE_CMODE</span><span class="plain">)) {</span>
|
|
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">GPROPERTY_HL</span><span class="plain">));</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="reserved">if</span><span class="plain"> (!(</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">TREAT_AS_LVALUE_CMODE</span><span class="plain">))) {</span>
|
|
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">GPROPERTY_HL</span><span class="plain">));</span>
|
|
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="plain">}</span>
|
|
<span class="functiontext">Kinds::RunTime::emit_weak_id_as_val</span><span class="plain">(</span><span class="identifier">owner_kind</span><span class="plain">);</span>
|
|
<<span class="cwebmacro">Emit the property's owner</span> <span class="cwebmacronumber">14.3.2</span>><span class="character">;</span>
|
|
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">prop_spec</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (!(</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">TREAT_AS_LVALUE_CMODE</span><span class="plain">))) {</span>
|
|
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP14">§14</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14_3_1"></a><b>§14.3.1. </b>When Inform reads a text with a substitution like so:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>if the signpost is visible, say "The signpost is still [signpost condition]."</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">...it has to decide which object is meant as the owner of the property
|
|
"signpost condition". Ordinarily, missing property owners are the self object,
|
|
which works nicely because <code class="display"><span class="extract">self</span></code> always has the right value at run-time when
|
|
we're, e.g., printing names of things. But what if, as here, there is no
|
|
formal indication of the owner? If we compile with the self object as owner,
|
|
the code may fail at run-time, complaining about using a property of nothing.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The author who wrote the source text above, though, felt able to write
|
|
"[signpost condition]" without any indication of its owner because there
|
|
could only be one possible owner: the signpost. And so that's the convention
|
|
we use here. We replace "self" as a default owner by the only possible owner.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Reinterpret the "self" for what are unambiguously conditions of single things</span> <span class="cwebmacronumber">14.3.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_self_object_constant</span><span class="plain">(</span><span class="identifier">owner</span><span class="plain">)) {</span>
|
|
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain"> = </span><span class="functiontext">Properties::Conditions::of_what</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">);</span>
|
|
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::as_object_instance</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">I</span><span class="plain">) </span><span class="identifier">owner</span><span class="plain"> = </span><span class="functiontext">Rvalues::from_instance</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP14_3">§14.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14_3_2"></a><b>§14.3.2. </b>During type-checking, a small number of <code class="display"><span class="extract">PROPERTY_VALUE_NT</span></code> SPs are marked
|
|
with the <code class="display"><span class="extract">record_as_self_ANNOT</span></code> flag. Such a SP compiles not only to code
|
|
performing the property lookup, but also setting the <code class="display"><span class="extract">self</span></code> I6 variable at
|
|
run-time to the object whose property is being looked up. The point of this
|
|
is to change the context used for implicit property lookups involved in the
|
|
actual property: e.g., if the value of this property turns out to be text
|
|
which contains a substitution referring vaguely to another property, then
|
|
we need to make sure that this other property is looked up from the same
|
|
object as produced the original text containing the substitution.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Emit the property's owner</span> <span class="cwebmacronumber">14.3.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">, </span><span class="constant">record_as_self_ANNOT</span><span class="plain">)) {</span>
|
|
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="identifier">Produce::ref_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">SELF_HL</span><span class="plain">));</span>
|
|
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">owner</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">owner</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP14_3">§14.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14_4"></a><b>§14.4. </b>List entries are blessedly simpler.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Compile a list entry specification</span> <span class="cwebmacronumber">14.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::no_children</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">) != </span><span class="constant">2</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"malformed LIST_OF SP"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">spec_found</span><span class="plain">-></span><span class="element">down</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"LIST_OF with null arg 0"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">spec_found</span><span class="plain">-></span><span class="element">down</span><span class="plain">-></span><span class="element">next</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"LIST_OF with null arg 1"</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">JUST_ROUTINE_CMODE</span><span class="plain">)) {</span>
|
|
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">LIST_OF_TY_GETITEM_HL</span><span class="plain">));</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="reserved">if</span><span class="plain"> (!(</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">TREAT_AS_LVALUE_CMODE</span><span class="plain">))) {</span>
|
|
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">LIST_OF_TY_GETITEM_HL</span><span class="plain">));</span>
|
|
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="plain">}</span>
|
|
<span class="constant">BEGIN_COMPILATION_MODE</span><span class="plain">;</span>
|
|
<span class="identifier">COMPILATION_MODE_EXIT</span><span class="plain">(</span><span class="constant">DEREFERENCE_POINTERS_CMODE</span><span class="plain">);</span>
|
|
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">spec_found</span><span class="plain">-></span><span class="element">down</span><span class="plain">);</span>
|
|
<span class="constant">END_COMPILATION_MODE</span><span class="plain">;</span>
|
|
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">spec_found</span><span class="plain">-></span><span class="element">down</span><span class="plain">-></span><span class="element">next</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (!(</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">TREAT_AS_LVALUE_CMODE</span><span class="plain">))) {</span>
|
|
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP14">§14</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14_5"></a><b>§14.5. </b>Table entries are simple too, but come in four variant forms:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Compile a table entry specification</span> <span class="cwebmacronumber">14.5</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">lookup</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">TABLELOOKUPENTRY_HL</span><span class="plain">);</span>
|
|
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">lookup_corr</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">TABLELOOKUPCORR_HL</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="identifier">TABLE_EXISTENCE_CMODE_ISSBM</span><span class="plain">)) {</span>
|
|
<span class="identifier">lookup</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">EXISTSTABLELOOKUPENTRY_HL</span><span class="plain">);</span>
|
|
<span class="identifier">lookup_corr</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">EXISTSTABLELOOKUPCORR_HL</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">ParseTree::no_children</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">)) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">1</span><span class="plain">:</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">JUST_ROUTINE_CMODE</span><span class="plain">)) {</span>
|
|
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">lookup</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="functiontext">LocalVariables::used_stack_selection</span><span class="plain">();</span>
|
|
<span class="functiontext">LocalVariables::add_table_lookup</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (!(</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">TREAT_AS_LVALUE_CMODE</span><span class="plain">))) {</span>
|
|
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">lookup</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">ct_0_lv</span><span class="plain"> = </span><span class="functiontext">LocalVariables::by_name</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"ct_0"</span><span class="plain">);</span>
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">ct_0_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">ct_0_lv</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="constant">8</span><span class="plain">);</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">ct_1_lv</span><span class="plain"> = </span><span class="functiontext">LocalVariables::by_name</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"ct_1"</span><span class="plain">);</span>
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">ct_1_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">ct_1_lv</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="constant">8</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">ct_0_s</span><span class="plain">);</span>
|
|
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">spec_found</span><span class="plain">-></span><span class="element">down</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">ct_1_s</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">BLANK_OUT_CMODE</span><span class="plain">)) {</span>
|
|
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">4</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (!(</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">TREAT_AS_LVALUE_CMODE</span><span class="plain">))) {</span>
|
|
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">2</span><span class="plain">: </span><span class="comment">never here except when printing debugging code</span>
|
|
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">3</span><span class="plain">:</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">JUST_ROUTINE_CMODE</span><span class="plain">)) {</span>
|
|
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">lookup</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="reserved">if</span><span class="plain"> (!(</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">TREAT_AS_LVALUE_CMODE</span><span class="plain">))) {</span>
|
|
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">lookup</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="plain">}</span>
|
|
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">spec_found</span><span class="plain">-></span><span class="element">down</span><span class="plain">-></span><span class="element">next</span><span class="plain">-></span><span class="element">next</span><span class="plain">);</span>
|
|
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">spec_found</span><span class="plain">-></span><span class="element">down</span><span class="plain">);</span>
|
|
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">spec_found</span><span class="plain">-></span><span class="element">down</span><span class="plain">-></span><span class="element">next</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">BLANK_OUT_CMODE</span><span class="plain">)) {</span>
|
|
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">4</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (!(</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">TREAT_AS_LVALUE_CMODE</span><span class="plain">))) {</span>
|
|
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">4</span><span class="plain">:</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">JUST_ROUTINE_CMODE</span><span class="plain">)) {</span>
|
|
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">lookup_corr</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="reserved">if</span><span class="plain"> (!(</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">TREAT_AS_LVALUE_CMODE</span><span class="plain">))) {</span>
|
|
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">lookup_corr</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="plain">}</span>
|
|
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">spec_found</span><span class="plain">-></span><span class="element">down</span><span class="plain">-></span><span class="element">next</span><span class="plain">-></span><span class="element">next</span><span class="plain">-></span><span class="element">next</span><span class="plain">);</span>
|
|
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">spec_found</span><span class="plain">-></span><span class="element">down</span><span class="plain">);</span>
|
|
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">spec_found</span><span class="plain">-></span><span class="element">down</span><span class="plain">-></span><span class="element">next</span><span class="plain">);</span>
|
|
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">spec_found</span><span class="plain">-></span><span class="element">down</span><span class="plain">-></span><span class="element">next</span><span class="plain">-></span><span class="element">next</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">BLANK_OUT_CMODE</span><span class="plain">)) {</span>
|
|
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">4</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (!(</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">TREAT_AS_LVALUE_CMODE</span><span class="plain">))) {</span>
|
|
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="identifier">default:</span><span class="plain"> </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"TABLE REFERENCE with bad number of args"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP14">§14</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15"></a><b>§15. Lvalue compilation. </b>To recap, if an assignment takes the form "now X is Y" then X is the lvalue,
|
|
Y is the rvalue. We only need to read Y, but we need to write X. Compilation
|
|
applied to a STORAGE item produces code suitable for reading it, i.e., suitable
|
|
for use in position Y — but not in general suitable for X.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">To compile the lvalue form of a storage item, we use the following schemas.
|
|
These in effect take the rvalue form and modify it. There are three
|
|
versions, according to the nature of the data being moved; then two
|
|
variations for incrementing, and two for decrementing, where Y's value is
|
|
added to X's rather than replacing it. In these schemas, <code class="display"><span class="extract">*1</span></code> expands to
|
|
the storage item's rvalue form, and <code class="display"><span class="extract">*2</span></code> to the value being assigned to it.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">At present no arithmetic values are stored in pointer values, but that might
|
|
change if arbitrary-precision integers are ever added to Inform, for instance.
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">STORE_WORD_TO_WORD</span><span class="plain"> </span><span class="constant">1</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">STORE_WORD_TO_POINTER</span><span class="plain"> </span><span class="constant">2</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">STORE_POINTER_TO_POINTER</span><span class="plain"> </span><span class="constant">3</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">INCREASE_BY_WORD</span><span class="plain"> </span><span class="constant">4</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">INCREASE_BY_REAL</span><span class="plain"> </span><span class="constant">5</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">INCREASE_BY_POINTER</span><span class="plain"> </span><span class="constant">6</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">DECREASE_BY_WORD</span><span class="plain"> </span><span class="constant">7</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">DECREASE_BY_REAL</span><span class="plain"> </span><span class="constant">8</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">DECREASE_BY_POINTER</span><span class="plain"> </span><span class="constant">9</span>
|
|
</pre>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">char</span><span class="plain"> *</span><span class="functiontext">Lvalues::storage_class_schema</span><span class="plain">(</span><span class="identifier">node_type_t</span><span class="plain"> </span><span class="identifier">storage_class</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">kind_of_store</span><span class="plain">,</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">reducing_modulo_1440</span><span class="plain">) {</span>
|
|
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">kind_of_store</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">STORE_WORD_TO_WORD:</span>
|
|
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">storage_class</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LOCAL_VARIABLE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*1 = *<2"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NONLOCAL_VARIABLE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*1 = *<2"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">TABLE_ENTRY_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*$1(*%1,1,*<2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">PROPERTY_VALUE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-WriteGProperty(*|1,*<2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LIST_ENTRY_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-WriteLIST_OF_TY_GetItem(*%1,*<2)"</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="string">""</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">STORE_WORD_TO_POINTER:</span>
|
|
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">storage_class</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LOCAL_VARIABLE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-BlkValueCast(*1, *#2, *!2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NONLOCAL_VARIABLE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-BlkValueCast(*1, *#2, *!2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">TABLE_ENTRY_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-BlkValueCast(*$1(*%1, 5), *#2, *!2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">PROPERTY_VALUE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-BlkValueCast(*+1, *#2, *!2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LIST_ENTRY_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-BlkValueCast(*1, *#2, *!2)"</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="string">""</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">STORE_POINTER_TO_POINTER:</span>
|
|
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">storage_class</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LOCAL_VARIABLE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-BlkValueCopy(*1, *<2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NONLOCAL_VARIABLE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-BlkValueCopy(*1, *<2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">TABLE_ENTRY_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-BlkValueCopy(*$1(*%1, 5), *<2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">PROPERTY_VALUE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-BlkValueCopy(*+1, *<2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LIST_ENTRY_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-BlkValueCopy(*1, *<2)"</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="string">""</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">INCREASE_BY_WORD:</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">reducing_modulo_1440</span><span class="plain">) {</span>
|
|
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">storage_class</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LOCAL_VARIABLE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*1 = NUMBER_TY_to_TIME_TY(*1 + *<2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NONLOCAL_VARIABLE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*1 = NUMBER_TY_to_TIME_TY(*1 + *<2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">TABLE_ENTRY_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*$1(*%1,1,NUMBER_TY_to_TIME_TY(*1 + *<2))"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">PROPERTY_VALUE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-WriteGProperty(*|1,NUMBER_TY_to_TIME_TY(*+1 + *<2))"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LIST_ENTRY_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-WriteLIST_OF_TY_GetItem(*%1,NUMBER_TY_to_TIME_TY(*1 + *<2))"</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">storage_class</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LOCAL_VARIABLE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*1 = *1 + *<2"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NONLOCAL_VARIABLE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*1 = *1 + *<2"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">TABLE_ENTRY_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*$1(*%1, 1, *1 + *<2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">PROPERTY_VALUE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-WriteGProperty(*|1,*+1 + *<2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LIST_ENTRY_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-WriteLIST_OF_TY_GetItem(*%1,*1 + *<2)"</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="string">""</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">INCREASE_BY_REAL:</span>
|
|
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">storage_class</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LOCAL_VARIABLE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*1 = REAL_NUMBER_TY_Plus(*1, *<2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NONLOCAL_VARIABLE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*1 = REAL_NUMBER_TY_Plus(*1, *<2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">TABLE_ENTRY_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*$1(*%1,1,REAL_NUMBER_TY_Plus(*1, *<2))"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">PROPERTY_VALUE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-WriteGProperty(*|1,REAL_NUMBER_TY_Plus(*+1, *<2))"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LIST_ENTRY_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-WriteLIST_OF_TY_GetItem(*%1,REAL_NUMBER_TY_Plus(*1, *<2))"</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="string">""</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">INCREASE_BY_POINTER:</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"pointer value increments not implemented"</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="string">""</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">DECREASE_BY_WORD:</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">reducing_modulo_1440</span><span class="plain">) {</span>
|
|
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">storage_class</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LOCAL_VARIABLE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*1 = NUMBER_TY_to_TIME_TY(*1 - *<2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NONLOCAL_VARIABLE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*1 = NUMBER_TY_to_TIME_TY(*1 - *<2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">TABLE_ENTRY_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*$1(*%1,1,NUMBER_TY_to_TIME_TY(*1 - *<2))"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">PROPERTY_VALUE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-WriteGProperty(*|1,NUMBER_TY_to_TIME_TY(*+1 - *<2))"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LIST_ENTRY_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-WriteLIST_OF_TY_GetItem(*%1,NUMBER_TY_to_TIME_TY(*1 - *<2))"</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">storage_class</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LOCAL_VARIABLE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*1 = *1 - *<2"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NONLOCAL_VARIABLE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*1 = *1 - *<2"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">TABLE_ENTRY_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*$1(*%1,1,*1 - *<2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">PROPERTY_VALUE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-WriteGProperty(*|1,*+1 - *<2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LIST_ENTRY_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-WriteLIST_OF_TY_GetItem(*%1,*1 - *<2)"</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="string">""</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">DECREASE_BY_REAL:</span>
|
|
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">storage_class</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LOCAL_VARIABLE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*1 = REAL_NUMBER_TY_Minus(*1, *<2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NONLOCAL_VARIABLE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*1 = REAL_NUMBER_TY_Minus(*1, *<2)"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">TABLE_ENTRY_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-*$1(*%1,1,REAL_NUMBER_TY_Minus(*1, *<2))"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">PROPERTY_VALUE_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-WriteGProperty(*|1,REAL_NUMBER_TY_Minus(*+1, *<2))"</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LIST_ENTRY_NT:</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="string">"*=-WriteLIST_OF_TY_GetItem(*%1,REAL_NUMBER_TY_Minus(*1, *<2))"</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="string">""</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">DECREASE_BY_POINTER:</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"pointer value decrements not implemented"</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="string">""</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="string">""</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Lvalues::storage_class_schema is used in <a href="#SP16">§16</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP16"></a><b>§16. </b>Here we supply advice on whether shallow or deep copies are needed. <code class="display"><span class="extract">inc</span></code> is
|
|
positive if we're incrementing what's there, negative if decrementing, zero
|
|
if simply setting.
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">char</span><span class="plain"> *</span><span class="functiontext">Lvalues::interpret_store</span><span class="plain">(</span><span class="identifier">node_type_t</span><span class="plain"> </span><span class="identifier">storage_class</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">left</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">right</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">inc</span><span class="plain">) {</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">KIND_CHECKING</span><span class="plain">, </span><span class="string">"Interpreting assignment of kinds $u, $u\n"</span><span class="plain">, </span><span class="identifier">left</span><span class="plain">, </span><span class="identifier">right</span><span class="plain">);</span>
|
|
<span class="identifier">kind_constructor</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">R</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">left</span><span class="plain">) && (</span><span class="identifier">right</span><span class="plain">)) { </span><span class="identifier">L</span><span class="plain"> = </span><span class="identifier">left</span><span class="plain">-></span><span class="element">construct</span><span class="plain">; </span><span class="identifier">R</span><span class="plain"> = </span><span class="identifier">right</span><span class="plain">-></span><span class="element">construct</span><span class="plain">; }</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">form</span><span class="plain"> = </span><span class="constant">STORE_WORD_TO_WORD</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inc</span><span class="plain"> > </span><span class="constant">0</span><span class="plain">) {</span>
|
|
<span class="identifier">form</span><span class="plain"> = </span><span class="constant">INCREASE_BY_WORD</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::FloatingPoint::uses_floating_point</span><span class="plain">(</span><span class="identifier">left</span><span class="plain">)) </span><span class="identifier">form</span><span class="plain"> = </span><span class="constant">INCREASE_BY_REAL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inc</span><span class="plain"> < </span><span class="constant">0</span><span class="plain">) {</span>
|
|
<span class="identifier">form</span><span class="plain"> = </span><span class="constant">DECREASE_BY_WORD</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::FloatingPoint::uses_floating_point</span><span class="plain">(</span><span class="identifier">left</span><span class="plain">)) </span><span class="identifier">form</span><span class="plain"> = </span><span class="constant">DECREASE_BY_REAL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Constructors::uses_pointer_values</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">)) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Constructors::allow_word_as_pointer</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">)) {</span>
|
|
<span class="identifier">form</span><span class="plain"> = </span><span class="constant">STORE_WORD_TO_POINTER</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inc</span><span class="plain"> > </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">form</span><span class="plain"> = </span><span class="constant">INCREASE_BY_POINTER</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inc</span><span class="plain"> < </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">form</span><span class="plain"> = </span><span class="constant">DECREASE_BY_POINTER</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">form</span><span class="plain"> = </span><span class="constant">STORE_POINTER_TO_POINTER</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inc</span><span class="plain"> > </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">form</span><span class="plain"> = </span><span class="constant">INCREASE_BY_POINTER</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inc</span><span class="plain"> < </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">form</span><span class="plain"> = </span><span class="constant">DECREASE_BY_POINTER</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">reduce</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">KT</span><span class="plain"> = </span><span class="functiontext">PL::TimesOfDay::kind</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">KT</span><span class="plain">) && (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">left</span><span class="plain">, </span><span class="identifier">KT</span><span class="plain">))) </span><span class="identifier">reduce</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Lvalues::storage_class_schema</span><span class="plain">(</span><span class="identifier">storage_class</span><span class="plain">, </span><span class="identifier">form</span><span class="plain">, </span><span class="identifier">reduce</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Lvalues::interpret_store is used in 12/ter (<a href="12-ter.html#SP8">§8</a>), 25/cii (<a href="25-cii.html#SP3_5_4">§3.5.4</a>).</p>
|
|
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><a href="14-rv.html">Back to 'RValues'</a></li><li><a href="14-cn.html">Continue with 'Conditions'</a></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|