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/12-cad.html
2020-04-07 01:06:09 +01:00

336 lines
34 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>12/dtd</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 '12/cad' 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#12">Chapter 12: Use of Propositions</a></li><li><b>Cinders and Deferrals</b></li></ul><p class="purpose">To compile terms, having carefully preserved any constants which might have been lost in the process of deferring a proposition (such tricky constants being called "cinders").</p>
<ul class="toc"><li><a href="#SP1">&#167;1. About cinders</a></li><li><a href="#SP3">&#167;3. Finding cinders</a></li><li><a href="#SP5">&#167;5. Declaring cinder parameters</a></li><li><a href="#SP6">&#167;6. The kind of terms</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. About cinders. </b>Any proposition which includes quantification will, in general, need to be
deferred: the quantifier will become a loop, and the loop variable will be a
local variable in the deferred routine. Instead of compiling explicit code
in the current routine <code class="display"><span class="extract">R</span></code>, we will compile a call to, say, <code class="display"><span class="extract">Prop_19</span></code>.
</p>
<p class="inwebparagraph">It is both good and bad that <code class="display"><span class="extract">Prop_19</span></code> has its own set of local variables.
Good because this means it can have loop variables and counters to help it
to implement quantifiers, without having to use up scarce locals in <code class="display"><span class="extract">R</span></code>.
(Recall that I6 allows only 15 locals in any one routine.) But bad because
the proposition may itself involve mention of local variables in <code class="display"><span class="extract">R</span></code>, which
do not exist inside <code class="display"><span class="extract">Prop_19</span></code>.
</p>
<p class="inwebparagraph">There are two issues here. Suppose we have:
</p>
<blockquote>
<p>if a dark room contains the painting</p>
</blockquote>
<p class="inwebparagraph">This compiles to code quantifying over rooms x, requiring a loop, so it
will be deferred to a routine. "The painting" is, in predicate calculus
terms, a constant &mdash; in that it does not depend on x &mdash; but that does not
mean it's a value known at compile time. If it is a local variable in the
current routine, then it won't exist in the deferred one, as mentioned
above. But it might also be a phrase to decide something, which has
side-effects, so that it might be important not to evaluate it more than
once.
</p>
<p class="inwebparagraph">Any such constants are compiled into the call to <code class="display"><span class="extract">Prop_19</span></code> as parameters:
then, when the latter is compiled, they become locals <code class="display"><span class="extract">const_0</span></code>, <code class="display"><span class="extract">const_1</span></code>,
..., whose evaluation will be rapid and without side-effects.
</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>As part of the deferral process, then, we scan through a proposition to look
for constants which might cause trouble. These are called "cinders", which
is a contraction of "constants in deferred routines".
</p>
<p class="inwebparagraph">Within any given proposition, the cinders are numbered 0, 1, 2, ...; these
numbers are recorded in the <code class="display"><span class="extract">cinder</span></code> field of the relevant <code class="display"><span class="extract">pcalc_term</span></code>
structure. A constant term with <code class="display"><span class="extract">cinder</span></code> set to -1 is harmless, and
can be compiled in <code class="display"><span class="extract">Prop_19</span></code> as it stands: a literal number, for instance.
</p>
<p class="inwebparagraph">At any given moment, we can only be working on the compilation of a single
deferred proposition routine. The following records the information noted
down at the time when the proposition was deferred:
</p>
<pre class="display">
<span class="reserved">pcalc_prop_deferral</span><span class="plain"> *</span><span class="identifier">current_pdef</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="comment">used only in this section</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. Finding cinders. </b>In this operation, conducted when we defer a proposition, we look for
constant terms which need to be cindered, do so, compile their values as
a comma-separated list of I6 expressions (which can be used in a function
call), note down their kinds of value in the record of the deferral, and
return the number of cinders made.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::Cinders::find_count</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">, </span><span class="reserved">pcalc_prop_deferral</span><span class="plain"> *</span><span class="identifier">pdef</span><span class="plain">) {</span>
<span class="identifier">TRAVERSE_VARIABLE</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">cinder_number</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">pcalc_prop_deferral</span><span class="plain"> *</span><span class="identifier">save_current_pdef</span><span class="plain"> = </span><span class="identifier">current_pdef</span><span class="plain">;</span>
<span class="identifier">current_pdef</span><span class="plain"> = </span><span class="identifier">pdef</span><span class="plain">;</span>
<span class="identifier">TRAVERSE_PROPOSITION</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">)</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">arity</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="identifier">cinder_number</span><span class="plain"> =</span>
<span class="functiontext">Calculus::Deferrals::Cinders::cind_find_in_term_count</span><span class="plain">(&amp;(</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">terms</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]), </span><span class="identifier">cinder_number</span><span class="plain">);</span>
<span class="identifier">current_pdef</span><span class="plain"> = </span><span class="identifier">save_current_pdef</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">cinder_number</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::Cinders::find_emit</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">, </span><span class="reserved">pcalc_prop_deferral</span><span class="plain"> *</span><span class="identifier">pdef</span><span class="plain">) {</span>
<span class="identifier">TRAVERSE_VARIABLE</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">cinder_number</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">started</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">pcalc_prop_deferral</span><span class="plain"> *</span><span class="identifier">save_current_pdef</span><span class="plain"> = </span><span class="identifier">current_pdef</span><span class="plain">;</span>
<span class="identifier">current_pdef</span><span class="plain"> = </span><span class="identifier">pdef</span><span class="plain">;</span>
<span class="identifier">TRAVERSE_PROPOSITION</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">)</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">arity</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="identifier">cinder_number</span><span class="plain"> =</span>
<span class="functiontext">Calculus::Deferrals::Cinders::cind_find_in_term_emit</span><span class="plain">(&amp;(</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">terms</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]), </span><span class="identifier">cinder_number</span><span class="plain">, &amp;</span><span class="identifier">started</span><span class="plain">);</span>
<span class="identifier">current_pdef</span><span class="plain"> = </span><span class="identifier">save_current_pdef</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">cinder_number</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::Cinders::cind_find_in_term_emit</span><span class="plain">(</span><span class="reserved">pcalc_term</span><span class="plain"> *</span><span class="identifier">pt</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">cinder_number</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">started</span><span class="plain">) {</span>
<span class="comment">do not clear the local I6 stream</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="element">function</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::Cinders::cind_find_in_term_emit</span><span class="plain">(&amp;(</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="element">function</span><span class="plain">-&gt;</span><span class="element">fn_of</span><span class="plain">), </span><span class="identifier">cinder_number</span><span class="plain">, </span><span class="identifier">started</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="element">constant</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Deferrals::Cinders::spec_needs_to_be_cindered</span><span class="plain">(</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="element">constant</span><span class="plain">)) {</span>
<span class="identifier">pt</span><span class="plain">-&gt;</span><span class="element">cinder</span><span class="plain"> = </span><span class="identifier">cinder_number</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">pt</span><span class="plain">-&gt;</span><span class="element">constant</span><span class="plain">);</span>
<span class="identifier">current_pdef</span><span class="plain">-&gt;</span><span class="element">cinder_kinds</span><span class="plain">[</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="element">cinder</span><span class="plain">] =</span>
<span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="element">constant</span><span class="plain">);</span>
<span class="plain">*</span><span class="identifier">started</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="identifier">cinder</span><span class="plain"> = -1;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">cinder_number</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::Cinders::cind_find_in_term_count</span><span class="plain">(</span><span class="reserved">pcalc_term</span><span class="plain"> *</span><span class="identifier">pt</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">cinder_number</span><span class="plain">) {</span>
<span class="comment">do not clear the local I6 stream</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="element">function</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::Cinders::cind_find_in_term_count</span><span class="plain">(&amp;(</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="element">function</span><span class="plain">-&gt;</span><span class="element">fn_of</span><span class="plain">), </span><span class="identifier">cinder_number</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="element">constant</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Calculus::Deferrals::Cinders::spec_needs_to_be_cindered</span><span class="plain">(</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="element">constant</span><span class="plain">)) {</span>
<span class="identifier">cinder_number</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">cinder_number</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::Cinders::find_count is used in 12/dtd (<a href="12-dtd.html#SP16">&#167;16</a>, <a href="12-dtd.html#SP26">&#167;26</a>).</p>
<p class="endnote">The function Calculus::Deferrals::Cinders::find_emit is used in 12/dtd (<a href="12-dtd.html#SP7_1_2">&#167;7.1.2</a>, <a href="12-dtd.html#SP11">&#167;11</a>, <a href="12-dtd.html#SP16">&#167;16</a>, <a href="12-dtd.html#SP26">&#167;26</a>).</p>
<p class="endnote">The function Calculus::Deferrals::Cinders::cind_find_in_term_emit appears nowhere else.</p>
<p class="endnote">The function Calculus::Deferrals::Cinders::cind_find_in_term_count appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>Which leaves us to decide, given any specification, whether it represents
a value needing to be cindered.
</p>
<p class="inwebparagraph">If in doubt, we should cinder, but we don't want to go mad since there's a limit
to how many cinders can be passed as parameters. Currently we do cinder these:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) phrases to decide values, cindered because they might be slow or have
side-effects to evaluate;
</li><li>(b) stacked non-local variables, such as variables attached to actions or
activities, cindered because they are only allowed in certain routines, and
the eventual deferred proposition routine might not qualify;
</li><li>(c) local variables, cindered since they won't exist in the deferred routine;
</li><li>(d) list and table entries, cindered since they are relatively slow to look up.
</li></ul>
<p class="inwebparagraph">But we do not cinder these, since their evaluation never depends on context
and never needs more than a single array entry lookup at run-time:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) constants from literal numbers to names of scenes, rulebooks, and so on;
</li><li>(b) global variables.
</li></ul>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::Cinders::spec_needs_to_be_cindered</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">CONSTANT_NT</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="reserved">if</span><span class="plain"> (</span><span class="functiontext">Lvalues::is_global_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">FALSE</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="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::Cinders::spec_needs_to_be_cindered is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Declaring cinder parameters. </b>Symmetrically, when we come to compiled our deferred proposition routine
<code class="display"><span class="extract">Prop_19</span></code>, we need to place suitable cinder variables in its I6 header.
We print their names, separated by spaces, since that's the somewhat
assembler-like syntax used by I6 routine headers.
</p>
<p class="inwebparagraph">We also set <code class="display"><span class="extract">current_pdef</span></code>, since this is the first action taken in starting
a new deferred routine.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::Cinders::declare</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">, </span><span class="reserved">pcalc_prop_deferral</span><span class="plain"> *</span><span class="identifier">pdef</span><span class="plain">) {</span>
<span class="identifier">TRAVERSE_VARIABLE</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">cinder_number</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">pcalc_prop_deferral</span><span class="plain"> *</span><span class="identifier">save_current_pdef</span><span class="plain"> = </span><span class="identifier">current_pdef</span><span class="plain">;</span>
<span class="identifier">current_pdef</span><span class="plain"> = </span><span class="identifier">pdef</span><span class="plain">;</span>
<span class="identifier">TRAVERSE_PROPOSITION</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">)</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">arity</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="identifier">cinder_number</span><span class="plain"> = </span><span class="functiontext">Calculus::Deferrals::Cinders::cind_declare_in</span><span class="plain">(</span><span class="identifier">cinder_number</span><span class="plain">, &amp;(</span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="element">terms</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]));</span>
<span class="identifier">current_pdef</span><span class="plain"> = </span><span class="identifier">save_current_pdef</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::Cinders::cind_declare_in</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">cinder_number</span><span class="plain">, </span><span class="reserved">pcalc_term</span><span class="plain"> *</span><span class="identifier">pt</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="element">function</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::Cinders::cind_declare_in</span><span class="plain">(</span><span class="identifier">cinder_number</span><span class="plain">, &amp;(</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="element">function</span><span class="plain">-&gt;</span><span class="element">fn_of</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="element">constant</span><span class="plain">) &amp;&amp; (</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="element">cinder</span><span class="plain"> &gt;= </span><span class="constant">0</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">pt</span><span class="plain">-&gt;</span><span class="element">constant</span><span class="plain">, </span><span class="constant">CONSTANT_NT</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">cinder_name</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">cinder_name</span><span class="plain">, </span><span class="string">"const_%d"</span><span class="plain">, </span><span class="identifier">cinder_number</span><span class="plain">++);</span>
<span class="functiontext">LocalVariables::add_named_call_as_symbol</span><span class="plain">(</span><span class="identifier">cinder_name</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">cinder_name</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">cinder_number</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::Cinders::declare is used in 12/cdp (<a href="12-cdp.html#SP2_1_5">&#167;2.1.5</a>).</p>
<p class="endnote">The function Calculus::Deferrals::Cinders::cind_declare_in appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. The kind of terms. </b>We are now finally able to say what the kind of value of a term to be
compiled is. The only troublesome case is when the term is a cinder; its
kind is then part of the information recorded at deferral time.
</p>
<pre class="display">
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">Calculus::Deferrals::Cinders::kind_of_value_of_term</span><span class="plain">(</span><span class="reserved">pcalc_term</span><span class="plain"> </span><span class="identifier">pt</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">.</span><span class="element">variable</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">.</span><span class="element">term_checked_as_kind</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">pt</span><span class="plain">.</span><span class="element">term_checked_as_kind</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K_object</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">.</span><span class="element">constant</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">.</span><span class="element">cinder</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">current_pdef</span><span class="plain">-&gt;</span><span class="element">cinder_kinds</span><span class="plain">[</span><span class="identifier">pt</span><span class="plain">.</span><span class="element">cinder</span><span class="plain">];</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTreeUsage::is_phrasal</span><span class="plain">(</span><span class="identifier">pt</span><span class="plain">.</span><span class="element">constant</span><span class="plain">))</span>
<span class="functiontext">Dash::check_value</span><span class="plain">(</span><span class="identifier">pt</span><span class="plain">.</span><span class="element">constant</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="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">pt</span><span class="plain">.</span><span class="element">constant</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">.</span><span class="element">function</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">K_object</span><span class="plain">;</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Broken pcalc term"</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 Calculus::Deferrals::Cinders::kind_of_value_of_term is used in 12/ter (<a href="12-ter.html#SP8">&#167;8</a>), 12/qr (<a href="12-qr.html#SP7">&#167;7</a>), 15/tpr (<a href="15-tpr.html#SP7">&#167;7</a>), 15/cr (<a href="15-cr.html#SP7_1">&#167;7.1</a>), 15/spr2 (<a href="15-spr2.html#SP11">&#167;11</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::Cinders::compile</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">c</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"const_%d"</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Calculus::Deferrals::Cinders::emit</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">c</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="functiontext">LocalVariables::find_const_var</span><span class="plain">(</span><span class="identifier">c</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">"absent calculus variable"</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="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="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Calculus::Deferrals::Cinders::compile appears nowhere else.</p>
<p class="endnote">The function Calculus::Deferrals::Cinders::emit is used in 11/tr (<a href="11-tr.html#SP10">&#167;10</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="12-dtd.html">Back to 'Deciding to Defer'</a></li><li><a href="12-cdp.html">Continue with 'Compile Deferred Propositions'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>