1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 10:04:21 +03:00
inform7/docs/core-module/12-cad.html
2020-08-25 21:47:14 +01:00

313 lines
45 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Cinders and Deferrals</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<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="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
MathJax = {
tex: {
inlineMath: '$', '$'], ['\\(', '\\)'
},
svg: {
fontCache: 'global'
}
};
</script>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Inform.png" height=72">
</a></h1>
<ul><li><a href="../compiler.html">compiler tools</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="../supervisor-module/index.html">supervisor</a></li>
</ul><h2>Inform7 Modules</h2><ul>
<li><a href="index.html"><span class="selectedlink">core</span></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="../bytecode-module/index.html">bytecode</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul><h2>Services</h2><ul>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../calculus-module/index.html">calculus</a></li>
<li><a href="../html-module/index.html">html</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Cinders and Deferrals' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7 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></div>
<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="12-cad.html#SP1">&#167;1. About cinders</a></li><li><a href="12-cad.html#SP3">&#167;3. Finding cinders</a></li><li><a href="12-cad.html#SP5">&#167;5. Declaring cinder parameters</a></li><li><a href="12-cad.html#SP6">&#167;6. The kind of terms</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></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 <span class="extract"><span class="extract-syntax">R</span></span>, we will compile a call to, say, <span class="extract"><span class="extract-syntax">Prop_19</span></span>.
</p>
<p class="commentary">It is both good and bad that <span class="extract"><span class="extract-syntax">Prop_19</span></span> 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 <span class="extract"><span class="extract-syntax">R</span></span>.
(Recall that I6 allows only 15 locals in any one routine.) But bad because
the proposition may itself involve mention of local variables in <span class="extract"><span class="extract-syntax">R</span></span>, which
do not exist inside <span class="extract"><span class="extract-syntax">Prop_19</span></span>.
</p>
<p class="commentary">There are two issues here. Suppose we have:
</p>
<blockquote>
<p>if a dark room contains the painting</p>
</blockquote>
<p class="commentary">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="commentary">Any such constants are compiled into the call to <span class="extract"><span class="extract-syntax">Prop_19</span></span> as parameters:
then, when the latter is compiled, they become locals <span class="extract"><span class="extract-syntax">const_0</span></span>, <span class="extract"><span class="extract-syntax">const_1</span></span>,
..., whose evaluation will be rapid and without side-effects.
</p>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></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="commentary">Within any given proposition, the cinders are numbered 0, 1, 2, ...; these
numbers are recorded in the <span class="extract"><span class="extract-syntax">cinder</span></span> field of the relevant <span class="extract"><span class="extract-syntax">pcalc_term</span></span>
structure. A constant term with <span class="extract"><span class="extract-syntax">cinder</span></span> set to \(-1\) is harmless, and
can be compiled in <span class="extract"><span class="extract-syntax">Prop_19</span></span> as it stands: a literal number, for instance.
</p>
<p class="commentary">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="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">pcalc_prop_deferral</span><span class="plain-syntax"> *</span><span class="identifier-syntax">current_pdef</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> used only in this section</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></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="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Calculus::Deferrals::Cinders::find_count</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Calculus::Deferrals::Cinders::find_count</span></span>:<br/>Deciding to Defer - <a href="12-dtd.html#SP15">&#167;15</a>, <a href="12-dtd.html#SP26">&#167;26</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prop</span><span class="plain-syntax">, </span><span class="reserved-syntax">pcalc_prop_deferral</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TRAVERSE_VARIABLE</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">pcalc_prop_deferral</span><span class="plain-syntax"> *</span><span class="identifier-syntax">save_current_pdef</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_pdef</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_pdef</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TRAVERSE_PROPOSITION</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">, </span><span class="identifier-syntax">prop</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax">&lt;pl-&gt;</span><span class="identifier-syntax">arity</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><a href="12-cad.html#SP3" class="function-link"><span class="function-syntax">Calculus::Deferrals::Cinders::cind_find_in_term_count</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">terms</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]), </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_pdef</span><span class="plain-syntax"> = </span><span class="identifier-syntax">save_current_pdef</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Calculus::Deferrals::Cinders::find_emit</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Calculus::Deferrals::Cinders::find_emit</span></span>:<br/>Deciding to Defer - <a href="12-dtd.html#SP6_1_2">&#167;6.1.2</a>, <a href="12-dtd.html#SP10">&#167;10</a>, <a href="12-dtd.html#SP15">&#167;15</a>, <a href="12-dtd.html#SP26">&#167;26</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prop</span><span class="plain-syntax">, </span><span class="reserved-syntax">pcalc_prop_deferral</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TRAVERSE_VARIABLE</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">started</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">pcalc_prop_deferral</span><span class="plain-syntax"> *</span><span class="identifier-syntax">save_current_pdef</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_pdef</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_pdef</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TRAVERSE_PROPOSITION</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">, </span><span class="identifier-syntax">prop</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax">&lt;pl-&gt;</span><span class="identifier-syntax">arity</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><a href="12-cad.html#SP3" class="function-link"><span class="function-syntax">Calculus::Deferrals::Cinders::cind_find_in_term_emit</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">terms</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]), </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">started</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_pdef</span><span class="plain-syntax"> = </span><span class="identifier-syntax">save_current_pdef</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Calculus::Deferrals::Cinders::cind_find_in_term_emit</span><span class="plain-syntax">(</span><span class="identifier-syntax">pcalc_term</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">started</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> do not clear the local I6 stream</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">function</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="12-cad.html#SP3" class="function-link"><span class="function-syntax">Calculus::Deferrals::Cinders::cind_find_in_term_emit</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">function</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">fn_of</span><span class="plain-syntax">), </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">started</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">constant</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="12-cad.html#SP4" class="function-link"><span class="function-syntax">Calculus::Deferrals::Cinders::spec_needs_to_be_cindered</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">constant</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">cinder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><a href="14-cfs.html#SP8" class="function-link"><span class="function-syntax">Specifications::Compiler::emit_as_val</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">constant</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cinder_kinds</span><span class="plain-syntax">[</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">cinder</span><span class="plain-syntax">] =</span>
<span class="plain-syntax"> </span><a href="14-sp.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">constant</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">started</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">cinder</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Calculus::Deferrals::Cinders::cind_find_in_term_count</span><span class="plain-syntax">(</span><span class="identifier-syntax">pcalc_term</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> do not clear the local I6 stream</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">function</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="12-cad.html#SP3" class="function-link"><span class="function-syntax">Calculus::Deferrals::Cinders::cind_find_in_term_count</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">function</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">fn_of</span><span class="plain-syntax">), </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">constant</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="12-cad.html#SP4" class="function-link"><span class="function-syntax">Calculus::Deferrals::Cinders::spec_needs_to_be_cindered</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">constant</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></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="commentary">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>
<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="commentary">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>
<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="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Calculus::Deferrals::Cinders::spec_needs_to_be_cindered</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Calculus::Deferrals::Cinders::spec_needs_to_be_cindered</span></span>:<br/><a href="12-cad.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">spec</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="constant-syntax">CONSTANT_NT</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="14-lv.html#SP9" class="function-link"><span class="function-syntax">Lvalues::is_global_variable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. Declaring cinder parameters. </b>Symmetrically, when we come to compiled our deferred proposition routine
<span class="extract"><span class="extract-syntax">Prop_19</span></span>, 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="commentary">We also set <span class="extract"><span class="extract-syntax">current_pdef</span></span>, since this is the first action taken in starting
a new deferred routine.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Calculus::Deferrals::Cinders::declare</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Calculus::Deferrals::Cinders::declare</span></span>:<br/>Compile Deferred Propositions - <a href="12-cdp.html#SP2_1_5">&#167;2.1.5</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prop</span><span class="plain-syntax">, </span><span class="reserved-syntax">pcalc_prop_deferral</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pdef</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TRAVERSE_VARIABLE</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">pcalc_prop_deferral</span><span class="plain-syntax"> *</span><span class="identifier-syntax">save_current_pdef</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_pdef</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_pdef</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pdef</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TRAVERSE_PROPOSITION</span><span class="plain-syntax">(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">, </span><span class="identifier-syntax">prop</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax">&lt;pl-&gt;</span><span class="identifier-syntax">arity</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax"> = </span><a href="12-cad.html#SP5" class="function-link"><span class="function-syntax">Calculus::Deferrals::Cinders::cind_declare_in</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax">, &amp;(</span><span class="identifier-syntax">pl</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">terms</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_pdef</span><span class="plain-syntax"> = </span><span class="identifier-syntax">save_current_pdef</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Calculus::Deferrals::Cinders::cind_declare_in</span><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">pcalc_term</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">function</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="12-cad.html#SP5" class="function-link"><span class="function-syntax">Calculus::Deferrals::Cinders::cind_declare_in</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax">, &amp;(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">function</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">fn_of</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">constant</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">cinder</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">constant</span><span class="plain-syntax">, </span><span class="constant-syntax">CONSTANT_NT</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">cinder_name</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">cinder_name</span><span class="plain-syntax">, </span><span class="string-syntax">"const_%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax">++);</span>
<span class="plain-syntax"> </span><a href="24-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_named_call_as_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cinder_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">cinder_name</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">cinder_number</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></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="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="function-syntax">Calculus::Deferrals::Cinders::kind_of_value_of_term</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Calculus::Deferrals::Cinders::kind_of_value_of_term</span></span>:<br/>The Equality Relation Revisited - <a href="12-terr.html#SP5">&#167;5</a><br/>Quasinumeric Relations - <a href="12-qr.html#SP6">&#167;6</a><br/>The Provision Relation - <a href="15-tpr.html#SP6">&#167;6</a><br/>Comparative Relations - <a href="15-cr.html#SP5_1">&#167;5.1</a><br/>Setting Property Relation - <a href="15-spr2.html#SP11">&#167;11</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">pcalc_term</span><span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">.</span><span class="identifier-syntax">variable</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">.</span><span class="identifier-syntax">term_checked_as_kind</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">.</span><span class="identifier-syntax">term_checked_as_kind</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">.</span><span class="identifier-syntax">constant</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">.</span><span class="identifier-syntax">cinder</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">current_pdef</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">cinder_kinds</span><span class="plain-syntax">[</span><span class="identifier-syntax">pt</span><span class="plain-syntax">.</span><span class="identifier-syntax">cinder</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="8-ptu.html#SP12" class="function-link"><span class="function-syntax">ParseTreeUsage::is_phrasal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">.</span><span class="identifier-syntax">constant</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="14-ds2.html#SP8" class="function-link"><span class="function-syntax">Dash::check_value</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">.</span><span class="identifier-syntax">constant</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="14-sp.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">.</span><span class="identifier-syntax">constant</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pt</span><span class="plain-syntax">.</span><span class="identifier-syntax">function</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Broken pcalc term"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Calculus::Deferrals::Cinders::emit</span><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax"> = </span><a href="24-lv.html#SP20" class="function-link"><span class="function-syntax">LocalVariables::find_const_var</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lvar</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"absent calculus variable"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar_s</span><span class="plain-syntax"> = </span><a href="24-lv.html#SP46" class="function-link"><span class="function-syntax">LocalVariables::declare_this</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="constant-syntax">8</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_symbol</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">lvar_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="12-dtd.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-cm.html">1</a></li><li class="progresschapter"><a href="2-up.html">2</a></li><li class="progresschapter"><a href="3-bv.html">3</a></li><li class="progresschapter"><a href="4-dlr.html">4</a></li><li class="progresschapter"><a href="5-rpt.html">5</a></li><li class="progresschapter"><a href="6-lp.html">6</a></li><li class="progresschapter"><a href="7-am.html">7</a></li><li class="progresschapter"><a href="8-ptu.html">8</a></li><li class="progresschapter"><a href="9-ef.html">9</a></li><li class="progresschapter"><a href="10-its.html">10</a></li><li class="progresschapter"></li><li class="progresscurrentchapter">12</li><li class="progresssection"><a href="12-terr.html">terr</a></li><li class="progresssection"><a href="12-qr.html">qr</a></li><li class="progresssection"><a href="12-ap.html">ap</a></li><li class="progresssection"><a href="12-ca.html">ca</a></li><li class="progresssection"><a href="12-dtd.html">dtd</a></li><li class="progresscurrent">cad</li><li class="progresssection"><a href="12-cdp.html">cdp</a></li><li class="progresschapter"><a href="13-kak.html">13</a></li><li class="progresschapter"><a href="14-sp.html">14</a></li><li class="progresschapter"><a href="15-pr.html">15</a></li><li class="progresschapter"><a href="16-is.html">16</a></li><li class="progresschapter"><a href="17-tl.html">17</a></li><li class="progresschapter"><a href="18-lc.html">18</a></li><li class="progresschapter"><a href="19-tc.html">19</a></li><li class="progresschapter"><a href="20-eq.html">20</a></li><li class="progresschapter"><a href="21-rl.html">21</a></li><li class="progresschapter"><a href="22-itp.html">22</a></li><li class="progresschapter"><a href="23-ad.html">23</a></li><li class="progresschapter"><a href="24-lv.html">24</a></li><li class="progresschapter"><a href="25-in.html">25</a></li><li class="progresschapter"><a href="26-fc.html">26</a></li><li class="progresschapter"><a href="27-hr.html">27</a></li><li class="progressnext"><a href="12-cdp.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>