1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 16:44:21 +03:00
inform7/docs/core-module/15-pov.html
2020-04-07 01:06:09 +01:00

206 lines
16 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>15/spr2</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 '15/pov' 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#15">Chapter 15: Properties</a></li><li><b>Properties of Values</b></li></ul><p class="purpose">Two unrelated but minor support needs for properties of values which are not objects.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. In-table storage</a></li><li><a href="#SP4">&#167;4. Avoiding a hacky I6 problem</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. In-table storage. </b>Some kinds of non-object are created by table, with the table columns holding the
relevant property values. The following structure indicates which column of
which table will store the property values at run-time, or else is left as
<code class="display"><span class="extract">-1, 0</span></code> if the property values aren't living inside a table structure.
</p>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">property_of_value_storage</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">storage_table_iname</span><span class="plain">; </span><span class="comment">for the relevant column array</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">property_of_value_storage</span><span class="plain">;</span>
<span class="reserved">property_of_value_storage</span><span class="plain"> *</span><span class="identifier">latest_povs</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="comment">see below</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure property_of_value_storage is private to this section.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>It's a little inconvenient to work out some elegant mechanism for the table
compilation code to tell each kind where it will be living, so instead we
rely on the fact that we're doing one at a time. The table-compiler simply
calls this routine to notify us of where the next batch of properties will be,
and we mark them down in the most recently created property permission.
</p>
<pre class="display">
<span class="reserved">property_of_value_storage</span><span class="plain"> *</span><span class="functiontext">Properties::OfValues::get_storage</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">property_of_value_storage</span><span class="plain"> *</span><span class="identifier">povs</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">property_of_value_storage</span><span class="plain">);</span>
<span class="identifier">povs</span><span class="plain">-&gt;</span><span class="element">storage_table_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">latest_povs</span><span class="plain"> = </span><span class="identifier">povs</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">povs</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Properties::OfValues::pp_set_table_storage</span><span class="plain">(</span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">store</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">store</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">"ugh"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">latest_povs</span><span class="plain">) {</span>
<span class="identifier">latest_povs</span><span class="plain">-&gt;</span><span class="element">storage_table_iname</span><span class="plain"> = </span><span class="identifier">store</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Properties::OfValues::get_storage is used in 5/ins (<a href="5-ins.html#SP27">&#167;27</a>), 13/kak (<a href="13-kak.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function Properties::OfValues::pp_set_table_storage is used in 19/tod (<a href="19-tod.html#SP6_4_2">&#167;6.4.2</a>).</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>The code generator will need to know these numbers, so we will annotate
the property-permission symbol accordingly:
</p>
<pre class="display">
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Properties::OfValues::annotate_table_storage</span><span class="plain">(</span><span class="reserved">property_permission</span><span class="plain"> *</span><span class="identifier">pp</span><span class="plain">) {</span>
<span class="reserved">property_of_value_storage</span><span class="plain"> *</span><span class="identifier">povs</span><span class="plain"> =</span>
<span class="identifier">RETRIEVE_POINTER_property_of_value_storage</span><span class="plain">(</span><span class="functiontext">World::Permissions::get_storage_data</span><span class="plain">(</span><span class="identifier">pp</span><span class="plain">));</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">povs</span><span class="plain">-&gt;</span><span class="element">storage_table_iname</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Properties::OfValues::annotate_table_storage is used in 15/pr (<a href="15-pr.html#SP27">&#167;27</a>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Avoiding a hacky I6 problem. </b>This is a rather distasteful provision, like everything to do with I6
translation. But we don't want to hand the problem downstream to the code
generator; we want to deal with it now. The issue arises with source text like:
</p>
<blockquote>
<p>A keyword is a kind of value. The keywords are xyzzy, plugh. A keyword can be mentioned.</p>
</blockquote>
<p class="inwebparagraph">where "mentioned" is implemented for objects as an <code class="display"><span class="extract">Attribute</span></code> in the I6 sense.
That would make it impossible for the code-generator to store the property
instead in a flat array, which is how it will want to handle properties of
values. There are ways we could fix this, but property lookup needs to be fast,
and it seems best to reject the extra complexity needed.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Properties::OfValues::check_allowable</span><span class="plain">(</span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Behaviour::definite</span><span class="plain">(</span><span class="identifier">K</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="reserved">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain">;</span>
<span class="reserved">property_permission</span><span class="plain"> *</span><span class="identifier">pp</span><span class="plain">;</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I_of</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="identifier">LOOP_OVER_INSTANCES</span><span class="plain">(</span><span class="identifier">I_of</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">)</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">infs</span><span class="plain"> = </span><span class="functiontext">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I_of</span><span class="plain">); </span><span class="identifier">infs</span><span class="plain">; </span><span class="identifier">infs</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::narrowest_broader_subject</span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">))</span>
<span class="identifier">LOOP_OVER_PERMISSIONS_FOR_INFS</span><span class="plain">(</span><span class="identifier">pp</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">prn</span><span class="plain"> = </span><span class="functiontext">World::Permissions::get_property</span><span class="plain">(</span><span class="identifier">pp</span><span class="plain">))) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Properties::can_be_compiled</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">)))</span>
&lt;<span class="cwebmacro">Check that the property is allowable here</span> <span class="cwebmacronumber">4.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Properties::OfValues::check_allowable is used in 13/kak (<a href="13-kak.html#SP5">&#167;5</a>).</p>
<p class="inwebparagraph"><a id="SP4_1"></a><b>&#167;4.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Check that the property is allowable here</span> <span class="cwebmacronumber">4.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">problem_count</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Properties::has_been_translated</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">)) &amp;&amp;</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">current_sentence</span><span class="plain"> = </span><span class="functiontext">World::Permissions::where_granted</span><span class="plain">(</span><span class="identifier">pp</span><span class="plain">);</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_property</span><span class="plain">(2, </span><span class="identifier">prn</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(3, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_AnomalousProperty</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"Sorry, but I'm going to have to disallow the sentence %1, even "</span>
<span class="string">"though it asks for something reasonable. A very small number "</span>
<span class="string">"of either-or properties with meanings special to Inform, like '%2', "</span>
<span class="string">"are restricted so that only kinds of object can have them. Since "</span>
<span class="string">"%3 isn't a kind of object, it can't be said to be %2. %P"</span>
<span class="string">"Probably you only need to call the property something else. The "</span>
<span class="string">"built-in meaning would only make sense if it were a kind of object "</span>
<span class="string">"in any case, so nothing is lost. Sorry for the inconvenience, all "</span>
<span class="string">"the same; there are good implementation reasons."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="15-spr2.html">Back to 'Setting Property Relation'</a></li><li><a href="15-epv.html">Continue with 'Emit Property Values'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>