1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 18:14:21 +03:00
inform7/docs/core-module/9-tfa.html
2020-04-15 23:49:59 +01:00

883 lines
88 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Traverse for Assertions</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="../index.html">
<img src="../docs-src/Figures/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="../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="../problems-module/index.html">problems</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>Shared Modules</h2><ul>
<li><a href="../arch-module/index.html">arch</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="../html-module/index.html">html</a></li>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Traverse for Assertions' generated by 7-->
<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#9">Chapter 9: The A-Parser</a></li><li><b>Traverse for Assertions</b></li></ul><p class="purpose">To manage the overall process of traversing the parse tree for assertion sentences.</p>
<ul class="toc"><li><a href="9-tfa.html#SP1">&#167;1. Definitions</a></li><li><a href="9-tfa.html#SP7">&#167;7. Performing the traverse</a></li><li><a href="9-tfa.html#SP8">&#167;8. The TRACE sentence handler</a></li><li><a href="9-tfa.html#SP9">&#167;9. The SENTENCE sentence handler</a></li><li><a href="9-tfa.html#SP12">&#167;12. The current object and subject</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>A "traverse" of the tree is a sentence-by-sentence walk through it,
taking action at each point. Because Inform holds the entire parse tree in
memory at once, this is the same thing as what used to be called a pass
through the source code.
</p>
<p class="inwebparagraph">Because Inform syntax requires little in the way of pre-declarations, and
Inform can accept the same material in many arrangements, we get around
timing problems &mdash; needing to know X before Y &mdash; by traversing the tree
many times over. There is little speed penalty for this.
</p>
<p class="inwebparagraph">But the majority of the work is done on two main traverses, so that Inform
behaves like a traditional two-pass compiler when reading assertions.
The following global variable indicates which pass we're in.
</p>
<p class="inwebparagraph">During the main assertion traverses, we also keep track of whether we
are near the start of an extension file or not. (If we are, then a lone
string of text is interpreted as the rubric of the extension &mdash; an
exception to Inform's normal rules.)
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">TRAVERSE1_SMFT</span>
<span class="definitionkeyword">enum</span> <span class="constant">TRAVERSE2_SMFT</span>
<span class="definitionkeyword">enum</span> <span class="constant">TRAVERSE_FOR_RULE_FILING_SMFT</span>
<span class="definitionkeyword">enum</span> <span class="constant">TRAVERSE_FOR_GRAMMAR_SMFT</span>
<span class="definitionkeyword">enum</span> <span class="constant">TRAVERSE_FOR_MAP1_SMFT</span>
<span class="definitionkeyword">enum</span> <span class="constant">TRAVERSE_FOR_MAP2_SMFT</span>
<span class="definitionkeyword">enum</span> <span class="constant">TRAVERSE_FOR_MAP_INDEX_SMFT</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">traverse</span><span class="plain">; </span><span class="comment"> always 1 or 2</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">near_start_of_extension</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Within each main traverse, we look at each sentence and decide which
part of Inform will deal with it.
</p>
<p class="inwebparagraph">Sentence handlers provide an abstraction for that choice of what to do
with each kind of sentence, on each traverse. This is really only a
disguise for a couple of <code class="display"><span class="extract">switch</span></code> statements and a lot of function calls.
The only real purpose is to make it easier to encapsulate code for one sort
of sentence away from the others: if we were writing <code class="display"><span class="extract">C++</span></code> or Python, it
would just be a method in the class for sentences.
</p>
<p class="inwebparagraph">Properly speaking, there can be sentence handlers for any node type at the
children-of-root level of the parse tree, although we mostly use this for
<code class="display"><span class="extract">SENTENCE_NT</span></code> nodes (and then we look further at the verb type in the <code class="display"><span class="extract">AVERB_NT</span></code>
first child). The main traverse is a two-pass operation, and we can supply
a routine to do something with the node on either of the passes (or neither,
or even both).
</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">sentence_handler</span><span class="plain"> {</span>
<span class="identifier">node_type_t</span><span class="plain"> </span><span class="identifier">sentence_node_type</span><span class="plain">; </span><span class="comment"> usually but not always <code class="display"><span class="extract">SENTENCE_NT</span></code></span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">verb_type</span><span class="plain">; </span><span class="comment"> for those which are indeed <code class="display"><span class="extract">SENTENCE_NT</span></code></span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">handle_on_traverse</span><span class="plain">; </span><span class="comment"> 1 or 2 to restrict to that pass, or 0 for both</span>
<span class="reserved">void</span><span class="plain"> (*</span><span class="identifier">handling_routine</span><span class="plain">)(</span><span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">PN</span><span class="plain">); </span><span class="comment"> or NULL not to handle</span>
<span class="plain">} </span><span class="reserved">sentence_handler</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure sentence_handler is private to this section.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>A global array &mdash; really a jump table &mdash; records who does what:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">MAX_OF_NTS_AND_VBS</span><span class="plain"> </span><span class="constant">75</span>
</pre>
<pre class="display">
<span class="reserved">sentence_handler</span><span class="plain"> *</span><span class="identifier">how_to_handle_nodes</span><span class="plain">[</span><span class="constant">MAX_OF_NTS_AND_VBS</span><span class="plain">]; </span><span class="comment"> for non-<code class="display"><span class="extract">SENTENCE_NT</span></code> nodes</span>
<span class="reserved">sentence_handler</span><span class="plain"> *</span><span class="identifier">how_to_handle_sentences</span><span class="plain">[</span><span class="constant">MAX_OF_NTS_AND_VBS</span><span class="plain">]; </span><span class="comment"> for <code class="display"><span class="extract">SENTENCE_NT</span></code> nodes</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>We recognise either node types <code class="display"><span class="extract">*_NT</span></code>, or node type <code class="display"><span class="extract">SENTENCE_NT</span></code> plus an
associated verb number <code class="display"><span class="extract">*_VB</span></code>. The following macro registers a sentence handler
by entering a pointer to it into one of the above tables:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="identifier">REGISTER_SENTENCE_HANDLER</span><span class="plain">(</span><span class="identifier">sh_name</span><span class="plain">) {</span>
<span class="reserved">sentence_handler</span><span class="plain"> *</span><span class="identifier">the_sh</span><span class="plain"> = &amp;</span><span class="identifier">sh_name</span><span class="plain">##</span><span class="identifier">_handler</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">the_sh</span><span class="plain">-&gt;</span><span class="element">sentence_node_type</span><span class="plain"> == </span><span class="identifier">SENTENCE_NT</span><span class="plain">) &amp;&amp; (</span><span class="identifier">the_sh</span><span class="plain">-&gt;</span><span class="element">verb_type</span><span class="plain"> != -1))</span>
<span class="identifier">how_to_handle_sentences</span><span class="plain">[</span><span class="identifier">the_sh</span><span class="plain">-&gt;</span><span class="element">verb_type</span><span class="plain">] = </span><span class="identifier">the_sh</span><span class="plain">;</span>
<span class="reserved">else</span>
<span class="identifier">how_to_handle_nodes</span><span class="plain">[</span><span class="identifier">the_sh</span><span class="plain">-&gt;</span><span class="element">sentence_node_type</span><span class="plain"> - </span><span class="identifier">BASE_OF_ENUMERATED_NTS</span><span class="plain">] = </span><span class="identifier">the_sh</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>The actual handlers are mostly not declared here (indeed, that's the
point of the whole exercise &mdash; to allow them to be decentralised). But we
do need to know their names, so every <code class="display"><span class="extract">*_SH</span></code> constant below must correspond
to a sentence handler structure called <code class="display"><span class="extract">*_SH_handler</span></code> defined somewhere
else in the program.
</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Performing the traverse. </b>The following routine is called twice, once with <code class="display"><span class="extract">pass</span></code> equal to 1, then
with <code class="display"><span class="extract">pass</span></code> equal to 2.
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">trace_sentences</span></code> is true between each pair of <code class="display"><span class="extract">TRACE_NT</span></code> nodes, if there
are any: these arise from the special debugging sentence consisting only
of an asterisk. When tracing, we print an account of what is being read to
the debugging log (both here, and in more detail elsewhere), except that
we don't bother to print details of the closing <code class="display"><span class="extract">TRACE_NT</span></code> node.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">sentence_handlers_initialised</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">assembly_position</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="comment"> where assembled sentences are added</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Traverse::traverse1<button class="popup" onclick="togglePopup('usagePopup500')">...<span class="popuptext" id="usagePopup500">Usage of <b>Assertions::Traverse::traverse1</b>:<br>How To Compile - <a href="1-htc.html#SP2_4">&#167;2.4</a></span></button></span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="functiontext"><a href="9-tfa.html#SP7">Assertions::Traverse::traverse</a></span><span class="plain">(1);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Traverse::traverse2<button class="popup" onclick="togglePopup('usagePopup501')">...<span class="popuptext" id="usagePopup501">Usage of <b>Assertions::Traverse::traverse2</b>:<br>How To Compile - <a href="1-htc.html#SP2_4">&#167;2.4</a></span></button></span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="functiontext"><a href="9-tfa.html#SP7">Assertions::Traverse::traverse</a></span><span class="plain">(2);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Traverse::traverse<button class="popup" onclick="togglePopup('usagePopup502')">...<span class="popuptext" id="usagePopup502">Usage of <b>Assertions::Traverse::traverse</b>:<br>none</span></button></span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">pass</span><span class="plain">) {</span>
<span class="functiontext"><a href="9-tfa.html#SP13">Assertions::Traverse::new_discussion</a></span><span class="plain">(); </span><span class="comment"> clear memory of what the subject and object of discussion are</span>
<span class="identifier">traverse</span><span class="plain"> = </span><span class="identifier">pass</span><span class="plain">;</span>
<span class="identifier">trace_sentences</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="identifier">sentence_handlers_initialised</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span>&lt;<span class="cwebmacro">Initialise sentence handlers</span> <span class="cwebmacronumber">7.3</span>&gt;<span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">last</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">ParseTree::traverse_ppn</span><span class="plain">(</span><span class="functiontext"><a href="1-wtc.html#SP5">Task::syntax_tree</a></span><span class="plain">(), </span><span class="functiontext"><a href="9-tfa.html#SP7_2">Assertions::Traverse::visit</a></span><span class="plain">, &amp;</span><span class="identifier">last</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pass</span><span class="plain"> == </span><span class="constant">2</span><span class="plain">) </span>&lt;<span class="cwebmacro">Extend the traverse to cover sentences needed when implicit kinds are set</span> <span class="cwebmacronumber">7.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP7_1"></a><b>&#167;7.1. </b>Here's a tricky timing problem, or rather, here's the fix for it. Assemblies
are made when the kinds of objects are set, and they're made by inserting
appropriate sentences. For instance, given the generalisation:
</p>
<blockquote>
<p>Every room contains a vehicle.</p>
</blockquote>
<p class="inwebparagraph">we would insert the following sentence into the tree:
</p>
<blockquote>
<p>Ballroom West contains a vehicle.</p>
</blockquote>
<p class="inwebparagraph">as soon as we discover that Ballroom West is a room. That works fine if we
discover this fact during traverses 1 or 2, but sometimes it can only be
known during the "positioning" stage, after traverse 2, when we look over
all the inferences drawn about Ballroom West. It's then too late to insert
any new sentences, or rather, it's too late to act on them.
</p>
<p class="inwebparagraph">So what we do is to call <code class="display"><span class="extract">position_objects</span></code> from the model-maker to make
any such deductions right at the end of traverse 2, and insert any sentences
arising right at the end of the source text. We then prolong traverse 2
artificially to run through those sentences.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Extend the traverse to cover sentences needed when implicit kinds are set</span> <span class="cwebmacronumber">7.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">last</span><span class="plain">;</span>
<span class="identifier">assembly_position</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
<span class="functiontext"><a href="26-pc.html#SP6">Plugins::Call::complete_model</a></span><span class="plain">(1);</span>
<span class="identifier">ParseTree::traverse_from_ppn</span><span class="plain">(</span><span class="identifier">last</span><span class="plain">, </span><span class="functiontext"><a href="9-tfa.html#SP7_2">Assertions::Traverse::visit</a></span><span class="plain">, &amp;</span><span class="identifier">last</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="9-tfa.html#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7_2"></a><b>&#167;7.2. </b>Let us go, and make our visit:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Traverse::visit<button class="popup" onclick="togglePopup('usagePopup503')">...<span class="popuptext" id="usagePopup503">Usage of <b>Assertions::Traverse::visit</b>:<br><a href="9-tfa.html#SP7">&#167;7</a>, <a href="9-tfa.html#SP7_1">&#167;7.1</a></span></button></span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> **</span><span class="identifier">last</span><span class="plain">) {</span>
<span class="identifier">assembly_position</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
<span class="identifier">compilation_module</span><span class="plain"> *</span><span class="identifier">cm</span><span class="plain"> = </span><span class="functiontext"><a href="27-cm.html#SP6">Modules::current</a></span><span class="plain">();</span>
<span class="functiontext"><a href="27-cm.html#SP6">Modules::set_current</a></span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Take a sceptical look at WITH nodes in the light of subsequent knowledge</span> <span class="cwebmacronumber">7.2.1</span>&gt;<span class="plain">;</span>
<span class="plain">*</span><span class="identifier">last</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Deal with an individual sentence</span> <span class="cwebmacronumber">7.2.2</span>&gt;<span class="plain">;</span>
<span class="functiontext"><a href="27-cm.html#SP6">Modules::set_current_to</a></span><span class="plain">(</span><span class="identifier">cm</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP7_3"></a><b>&#167;7.3. </b>If this hasn't already been done:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Initialise sentence handlers</span> <span class="cwebmacronumber">7.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">sentence_handlers_initialised</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Empty the sentence handler tables</span> <span class="cwebmacronumber">7.3.1</span>&gt;<span class="plain">;</span>
<span class="functiontext"><a href="26-shr.html#SP1">SHR::register_sentence_handlers</a></span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="9-tfa.html#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7_3_1"></a><b>&#167;7.3.1. </b>At this stage, all we do is empty the tables. The reason we have to delay
before entering the valid handlers is that some of them will be defined in
sections appearing after this one in the program: since C requires all
identifiers used to be predeclared, this means we can't enter the valid
handlers until right at the end of the program. The routine which does so,
<code class="display"><span class="extract">SHR::register_sentence_handlers</span></code>, consists only of a run of
<code class="display"><span class="extract">REGISTER_SENTENCE_HANDLER</span></code> macro expansions and can be found in Chapter
14.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Empty the sentence handler tables</span> <span class="cwebmacronumber">7.3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<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="constant">MAX_OF_NTS_AND_VBS</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">how_to_handle_nodes</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">how_to_handle_sentences</span><span class="plain">[</span><span class="identifier">i</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">This code is used in <a href="9-tfa.html#SP7_3">&#167;7.3</a>.</p>
<p class="inwebparagraph"><a id="SP7_2_1"></a><b>&#167;7.2.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Take a sceptical look at WITH nodes in the light of subsequent knowledge</span> <span class="cwebmacronumber">7.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">)) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">apparent_subject</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">apparent_subject</span><span class="plain">) == </span><span class="identifier">WITH_NT</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">apparent_subject</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">apparent_subject</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">)) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain"> = </span><span class="identifier">Wordings::up_to</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">apparent_subject</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">),</span>
<span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">apparent_subject</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">)));</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">ap</span><span class="plain"> = </span><span class="identifier">ExParser::parse_excerpt</span><span class="plain">(</span><span class="identifier">MISCELLANEOUS_MC</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext"><a href="14-rv.html#SP19">Rvalues::is_CONSTANT_of_kind</a></span><span class="plain">(</span><span class="identifier">ap</span><span class="plain">, </span><span class="identifier">K_action_name</span><span class="plain">)) {</span>
<span class="identifier">ParseTree::set_type_and_clear_annotations</span><span class="plain">(</span><span class="identifier">apparent_subject</span><span class="plain">, </span><span class="identifier">PROPER_NOUN_NT</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_text</span><span class="plain">(</span><span class="identifier">apparent_subject</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">apparent_subject</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="9-tfa.html#SP7_2">&#167;7.2</a>.</p>
<p class="inwebparagraph"><a id="SP7_2_2"></a><b>&#167;7.2.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Deal with an individual sentence</span> <span class="cwebmacronumber">7.2.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">trace_sentences</span><span class="plain">) &amp;&amp; (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">) != </span><span class="identifier">TRACE_NT</span><span class="plain">))</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"\n[%W]\n"</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">));</span>
&lt;<span class="cwebmacro">If this sentence can be handled, then do so and continue</span> <span class="cwebmacronumber">7.2.2.1</span>&gt;<span class="plain">;</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$T\n"</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">);</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"uncaught assertion"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="9-tfa.html#SP7_2">&#167;7.2</a>.</p>
<p class="inwebparagraph"><a id="SP7_2_2_1"></a><b>&#167;7.2.2.1. </b>Note that it's entirely open for the sentence handler to choose to do nothing
on either or both traverses, so the inner <code class="display"><span class="extract">if</span></code> can happily fail.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">If this sentence can be handled, then do so and continue</span> <span class="cwebmacronumber">7.2.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">) == </span><span class="identifier">ROOT_NT</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifndef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">) == </span><span class="identifier">BIBLIOGRAPHIC_NT</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">n</span><span class="plain"> = (</span><span class="reserved">int</span><span class="plain">) (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">) - </span><span class="identifier">BASE_OF_ENUMERATED_NTS</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (((</span><span class="identifier">n</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">n</span><span class="plain"> &lt; </span><span class="constant">MAX_OF_NTS_AND_VBS</span><span class="plain">)) &amp;&amp; (</span><span class="identifier">how_to_handle_nodes</span><span class="plain">[</span><span class="identifier">n</span><span class="plain">])) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">desired</span><span class="plain"> = </span><span class="identifier">how_to_handle_nodes</span><span class="plain">[</span><span class="identifier">n</span><span class="plain">]-&gt;</span><span class="element">handle_on_traverse</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (((</span><span class="identifier">traverse</span><span class="plain"> == </span><span class="identifier">desired</span><span class="plain">) || (</span><span class="identifier">desired</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">how_to_handle_nodes</span><span class="plain">[</span><span class="identifier">n</span><span class="plain">]-&gt;</span><span class="element">handling_routine</span><span class="plain">))</span>
<span class="plain">(*(</span><span class="identifier">how_to_handle_nodes</span><span class="plain">[</span><span class="identifier">n</span><span class="plain">]-&gt;</span><span class="element">handling_routine</span><span class="plain">))(</span><span class="identifier">p</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="9-tfa.html#SP7_2_2">&#167;7.2.2</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. The TRACE sentence handler. </b>While most of the sentence handlers are scattered across the rest of Inform,
two will be given here. The first is the one which acts on <code class="display"><span class="extract">TRACE_NT</span></code> asterisks;
this is a debugging feature of Inform. An asterisk on its own toggles logging
of work on sentences. An asterisk followed by double-quoted text is a note
for the telemetry file.
</p>
<pre class="display">
<span class="reserved">sentence_handler</span><span class="plain"> </span><span class="identifier">TRACE_SH_handler</span><span class="plain"> =</span>
<span class="plain">{ </span><span class="identifier">TRACE_NT</span><span class="plain">, -1, </span><span class="constant">0</span><span class="plain">, </span><span class="functiontext"><a href="9-tfa.html#SP8">Assertions::Traverse::switch_sentence_trace</a></span><span class="plain"> };</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Traverse::switch_sentence_trace<button class="popup" onclick="togglePopup('usagePopup504')">...<span class="popuptext" id="usagePopup504">Usage of <b>Assertions::Traverse::switch_sentence_trace</b>:<br>none</span></button></span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">PN</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::length</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">PN</span><span class="plain">)) &gt; </span><span class="constant">1</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">tr</span><span class="plain"> = </span><span class="identifier">telemetry_recording</span><span class="plain">;</span>
<span class="identifier">telemetry_recording</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">Telemetry::write_to_telemetry_file</span><span class="plain">(</span><span class="identifier">Lexer::word_text</span><span class="plain">(</span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">PN</span><span class="plain">))));</span>
<span class="identifier">telemetry_recording</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext"><a href="1-wtc.html#SP5">Task::syntax_tree</a></span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TelemetryAccepted</span><span class="plain">),</span>
<span class="string">"that's a message for the Author, not me"</span><span class="plain">,</span>
<span class="string">"so I'll note it down in the Telemetry file (if you're keeping one.)"</span><span class="plain">);</span>
<span class="plain"> </span><span class="identifier">telemetry_recording</span><span class="plain"> = </span><span class="identifier">tr</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">trace_sentences</span><span class="plain"> = </span><span class="constant">1</span><span class="plain"> - </span><span class="identifier">trace_sentences</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">traverse</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) </span><span class="identifier">Log::tracing_on</span><span class="plain">(</span><span class="identifier">trace_sentences</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Pass 1"</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Log::tracing_on</span><span class="plain">(</span><span class="identifier">trace_sentences</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Pass 2"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. The SENTENCE sentence handler. </b>The other special case is the handler for <code class="display"><span class="extract">SENTENCE_NT</span></code> itself, which is
special because it looks at the <code class="display"><span class="extract">AVERB_NT</span></code> child of the sentence and then
refers on to other sentence handlers accordingly:
</p>
<pre class="display">
<span class="reserved">sentence_handler</span><span class="plain"> </span><span class="identifier">SENTENCE_SH_handler</span><span class="plain"> =</span>
<span class="plain">{ </span><span class="identifier">SENTENCE_NT</span><span class="plain">, -1, </span><span class="constant">0</span><span class="plain">, </span><span class="functiontext"><a href="9-tfa.html#SP9">Assertions::Traverse::handle_sentence_with_primary_verb</a></span><span class="plain"> };</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Traverse::handle_sentence_with_primary_verb<button class="popup" onclick="togglePopup('usagePopup505')">...<span class="popuptext" id="usagePopup505">Usage of <b>Assertions::Traverse::handle_sentence_with_primary_verb</b>:<br>none</span></button></span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="identifier">prevailing_mood</span><span class="plain"> = </span><span class="identifier">UNKNOWN_CE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">language_element_ANNOT</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">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">you_can_ignore_ANNOT</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">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span>&lt;<span class="cwebmacro">Handle a sentence with no primary verb</span> <span class="cwebmacronumber">9.1</span>&gt;<span class="plain">;</span>
<span class="identifier">internal_error_if_node_type_wrong</span><span class="plain">(</span><span class="functiontext"><a href="1-wtc.html#SP5">Task::syntax_tree</a></span><span class="plain">(), </span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">, </span><span class="identifier">AVERB_NT</span><span class="plain">);</span>
<span class="identifier">prevailing_mood</span><span class="plain"> = </span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">, </span><span class="identifier">verbal_certainty_ANNOT</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Issue problem message if either subject or object contains mismatched brackets</span> <span class="cwebmacronumber">9.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Act on the primary verb in the sentence</span> <span class="cwebmacronumber">9.2</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP9_1"></a><b>&#167;9.1. </b>A sentence node with no children indicates that we couldn't find any verb
earlier. This might just be a piece of quoted matter which is intended as
the description or initial appearance of the most recent object, but in all
other eventualities we must produce a "no such sentence" problem.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Handle a sentence with no primary verb</span> <span class="cwebmacronumber">9.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Wordings::length</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">)) == </span><span class="constant">1</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Vocabulary::test_flags</span><span class="plain">(</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">)), </span><span class="identifier">TEXT_MC</span><span class="plain">+</span><span class="identifier">TEXTWITHSUBS_MC</span><span class="plain">))) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">traverse</span><span class="plain"> == </span><span class="constant">2</span><span class="plain">) </span><span class="functiontext"><a href="9-tfa.html#SP11">Assertions::Traverse::set_appearance</a></span><span class="plain">(</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">)));</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">&lt;</span><span class="identifier">no</span><span class="plain">-</span><span class="identifier">verb</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">));</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="9-tfa.html#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP9_2"></a><b>&#167;9.2. </b>We now use the other sentence-handler table, with almost the same code as
for the first (above). A small point of difference is that it's allowed for
a valid verb number to have no handler: if so, we handle the verb by doing
nothing on either traverse, of course.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Act on the primary verb in the sentence</span> <span class="cwebmacronumber">9.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">vn</span><span class="plain"> = </span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">, </span><span class="constant">verb_id_ANNOT</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">vn</span><span class="plain"> &lt; </span><span class="constant">0</span><span class="plain">) || (</span><span class="identifier">vn</span><span class="plain"> &gt;= </span><span class="constant">MAX_OF_NTS_AND_VBS</span><span class="plain">)) {</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Unimplemented verb %d\n"</span><span class="plain">, </span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">, </span><span class="constant">verb_id_ANNOT</span><span class="plain">));</span>
<span class="identifier">internal_error_on_node_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">how_to_handle_sentences</span><span class="plain">[</span><span class="identifier">vn</span><span class="plain">]) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">desired</span><span class="plain"> = </span><span class="identifier">how_to_handle_sentences</span><span class="plain">[</span><span class="identifier">vn</span><span class="plain">]-&gt;</span><span class="element">handle_on_traverse</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (((</span><span class="identifier">traverse</span><span class="plain"> == </span><span class="identifier">desired</span><span class="plain">) || (</span><span class="identifier">desired</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">how_to_handle_sentences</span><span class="plain">[</span><span class="identifier">vn</span><span class="plain">]-&gt;</span><span class="element">handling_routine</span><span class="plain">))</span>
<span class="plain">(*(</span><span class="identifier">how_to_handle_sentences</span><span class="plain">[</span><span class="identifier">vn</span><span class="plain">]-&gt;</span><span class="element">handling_routine</span><span class="plain">))(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="9-tfa.html#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>During early beta-testing, the problem message for "I can't find a verb"
split into cases. Inform is quite sensitive to punctuation errors as between
comma, paragraph break and semicolon, and this is where that sensitivity begins
to bite.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">no</span><span class="plain">-</span><span class="identifier">verb</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt; ::=</span>
<span class="identifier">before</span><span class="plain">/</span><span class="identifier">every</span><span class="plain">/</span><span class="identifier">after</span><span class="plain">/</span><span class="identifier">when</span><span class="plain">/</span><span class="identifier">instead</span><span class="plain">/</span><span class="identifier">check</span><span class="plain">/</span><span class="identifier">carry</span><span class="plain">/</span><span class="identifier">report</span><span class="plain"> ... | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_RuleWithoutColon problem</span> <span class="cwebmacronumber">10.1</span>&gt;
<span class="reserved">if</span><span class="plain"> ... | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_IfOutsidePhrase problem</span> <span class="cwebmacronumber">10.2</span>&gt;
<span class="plain">... , ... | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_NoSuchVerbComma problem</span> <span class="cwebmacronumber">10.3</span>&gt;
<span class="plain">... ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_NoSuchVerb problem</span> <span class="cwebmacronumber">10.4</span>&gt;
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP10_1"></a><b>&#167;10.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_RuleWithoutColon problem</span> <span class="cwebmacronumber">10.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext"><a href="1-wtc.html#SP5">Task::syntax_tree</a></span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RuleWithoutColon</span><span class="plain">),</span>
<span class="string">"I can't find a verb that I know how to deal with, so can't do anything "</span>
<span class="string">"with this sentence. It looks as if it might be a rule definition"</span><span class="plain">,</span>
<span class="string">"but if so then it is lacking the necessary colon (or comma). "</span>
<span class="string">"The punctuation style for rules is 'Rule conditions: do this; "</span>
<span class="string">"do that; do some more.' Perhaps you used a full stop instead "</span>
<span class="string">"of the colon?"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="9-tfa.html#SP10">&#167;10</a>.</p>
<p class="inwebparagraph"><a id="SP10_2"></a><b>&#167;10.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_IfOutsidePhrase problem</span> <span class="cwebmacronumber">10.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext"><a href="1-wtc.html#SP5">Task::syntax_tree</a></span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_IfOutsidePhrase</span><span class="plain">),</span>
<span class="string">"I can't find a verb that I know how to deal with. This looks like an 'if' "</span>
<span class="string">"phrase which has slipped its moorings"</span><span class="plain">,</span>
<span class="string">"so I am ignoring it. ('If' phrases, like all other such "</span>
<span class="string">"instructions, belong inside definitions of rules or phrases - "</span>
<span class="string">"not as sentences which have no context. Maybe a full stop or a "</span>
<span class="string">"skipped line was accidentally used instead of semicolon, so that you "</span>
<span class="string">"inadvertently ended the last rule early?)"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="9-tfa.html#SP10">&#167;10</a>.</p>
<p class="inwebparagraph"><a id="SP10_3"></a><b>&#167;10.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_NoSuchVerbComma problem</span> <span class="cwebmacronumber">10.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext"><a href="1-wtc.html#SP5">Task::syntax_tree</a></span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_NoSuchVerbComma</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In the sentence %1, I can't find a verb that I know how to deal with. "</span>
<span class="string">"(I notice there's a comma here, which is sometimes used to abbreviate "</span>
<span class="string">"rules which would normally be written with a colon - for instance, "</span>
<span class="string">"'Before taking: say \"You draw breath.\"' can be abbreviated to 'Before "</span>
<span class="string">"taking, say...' - but that's only allowed for Before, Instead and "</span>
<span class="string">"After rules. I mention all this in case you meant this sentence "</span>
<span class="string">"as a rule in some rulebook, but used a comma where there should "</span>
<span class="string">"have been a colon ':'?)"</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="9-tfa.html#SP10">&#167;10</a>.</p>
<p class="inwebparagraph"><a id="SP10_4"></a><b>&#167;10.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_NoSuchVerb problem</span> <span class="cwebmacronumber">10.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$T\n"</span><span class="plain">, </span><span class="identifier">current_sentence</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="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext"><a href="1-wtc.html#SP5">Task::syntax_tree</a></span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_NoSuchVerb</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In the sentence %1, I can't find a verb that I know how to deal with."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="9-tfa.html#SP10">&#167;10</a>.</p>
<p class="inwebparagraph"><a id="SP9_3"></a><b>&#167;9.3. </b>Inform source text does not make much use of parentheses to group subexpressions,
but the ability does exist, and we defend it a little here:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Issue problem message if either subject or object contains mismatched brackets</span> <span class="cwebmacronumber">9.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="identifier">next</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Wordings::mismatched_brackets</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">))) ||</span>
<span class="plain">(</span><span class="identifier">Wordings::mismatched_brackets</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">-&gt;</span><span class="element">next</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="identifier">Problems::quote_wording</span><span class="plain">(2,</span>
<span class="identifier">Wordings::one_word</span><span class="plain">(</span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">)) + </span><span class="constant">1</span><span class="plain">));</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(3, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">));</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(4, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext"><a href="1-wtc.html#SP5">Task::syntax_tree</a></span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">BelievedImpossible</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">)))</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"I must be misreading the sentence %1. The verb "</span>
<span class="string">"looks to me like '%2', but then the brackets don't "</span>
<span class="string">"match in what I have left: '%3' and '%4'."</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"I must be misreading the sentence %1. The verb "</span>
<span class="string">"looks to me like '%2', but then the brackets don't "</span>
<span class="string">"match in what I have left: '%3'."</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>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="9-tfa.html#SP9">&#167;9</a>.</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>The "appearance" is not a property as such. When a quoted piece of text
is given as a whole sentence, it might be:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) the "description" of a room or thing;
</li><li>(b) the title of the whole work, if at the top of the main source; or
</li><li>(c) the rubric of the extension, or the additional credits for an extension,
if near the top of an extension file.
</li></ul>
<p class="inwebparagraph">The title of the work is handled elsewhere, so we worry only about (a) and (c).
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Traverse::set_appearance<button class="popup" onclick="togglePopup('usagePopup506')">...<span class="popuptext" id="usagePopup506">Usage of <b>Assertions::Traverse::set_appearance</b>:<br><a href="9-tfa.html#SP9_1">&#167;9.1</a></span></button></span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">wn</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">near_start_of_extension</span><span class="plain"> &gt;= </span><span class="constant">1</span><span class="plain">) </span>&lt;<span class="cwebmacro">This is rubric or credit text for an extension</span> <span class="cwebmacronumber">11.1</span>&gt;<span class="plain">;</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain"> = </span><span class="functiontext"><a href="9-tfa.html#SP12">Assertions::Traverse::get_current_subject</a></span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">infs</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span>&lt;<span class="cwebmacro">Issue a problem for appearance without object</span> <span class="cwebmacronumber">11.2</span>&gt;<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="functiontext"><a href="14-rv.html#SP14">Rvalues::from_wording</a></span><span class="plain">(</span><span class="identifier">Wordings::one_word</span><span class="plain">(</span><span class="identifier">wn</span><span class="plain">));</span>
<span class="functiontext"><a href="15-ia.html#SP1">Properties::Appearance::infer</a></span><span class="plain">(</span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP11_1"></a><b>&#167;11.1. </b>The variable <code class="display"><span class="extract">near_start_of_extension</span></code> is always 0 except at the start of
an extension (immediately after the header line), when it is set to 1. The
following increments it to 2 to allow for up to two quoted lines; the first
is the rubric, the second the credit line.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">This is rubric or credit text for an extension</span> <span class="cwebmacronumber">11.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">source_file</span><span class="plain"> *</span><span class="identifier">pos</span><span class="plain"> = </span><span class="identifier">Lexer::file_of_origin</span><span class="plain">(</span><span class="identifier">wn</span><span class="plain">);</span>
<span class="identifier">inform_extension</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain"> = </span><span class="identifier">Extensions::corresponding_to</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">E</span><span class="plain">) {</span>
<span class="identifier">Word::dequote</span><span class="plain">(</span><span class="identifier">wn</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">, </span><span class="string">"%W"</span><span class="plain">, </span><span class="identifier">Wordings::one_word</span><span class="plain">(</span><span class="identifier">wn</span><span class="plain">));</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">near_start_of_extension</span><span class="plain">++) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">1</span><span class="plain">: </span><span class="identifier">Extensions::set_rubric</span><span class="plain">(</span><span class="identifier">E</span><span class="plain">, </span><span class="identifier">txt</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">2</span><span class="plain">: </span><span class="identifier">Extensions::set_extra_credit</span><span class="plain">(</span><span class="identifier">E</span><span class="plain">, </span><span class="identifier">txt</span><span class="plain">);</span>
<span class="identifier">near_start_of_extension</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">txt</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="9-tfa.html#SP11">&#167;11</a>.</p>
<p class="inwebparagraph"><a id="SP11_2"></a><b>&#167;11.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem for appearance without object</span> <span class="cwebmacronumber">11.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext"><a href="1-wtc.html#SP5">Task::syntax_tree</a></span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TextWithoutSubject</span><span class="plain">),</span>
<span class="string">"I'm not sure what you're referring to"</span><span class="plain">,</span>
<span class="string">"that is, I can't decide to what room or thing you intend that text to belong. "</span>
<span class="string">"Perhaps you could rephrase this more explicitly? ('The description of the Inner "</span>
<span class="string">"Sanctum is...')"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="9-tfa.html#SP11">&#167;11</a>.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. The current object and subject. </b>Inform is deliberately minimal when allowing the use of pronouns which carry
meanings from one sentence to another. It is unclear exactly how natural
language does this, and while some theories are more persuasive than others,
all seem vulnerable to odd cases that they get "wrong". It's therefore
hard to program a computer to understand "it" so that human users are
happy with the result.
</p>
<p class="inwebparagraph">But we try, just a little, by keeping track of the subject and object
under discussion. Even this is tricky. Consider:
</p>
<blockquote>
<p>The Pavilion is a room. East is the Cricket Square.</p>
</blockquote>
<p class="inwebparagraph">East of where? Clearly of the current subject, the Pavilion (not
the room kind). On the other hand,
</p>
<blockquote>
<p>On the desk is a pencil. It has description "2B."</p>
</blockquote>
<p class="inwebparagraph">"It" here is the pencil, not the desk. To disentangle such things,
we keep track of two different running references: the current subject and
the current object. English is an SVO language, so that in assertions of the
form "X is Y", X is the subject and Y the object. But it will turn out to
be more complicated than that, because we disregard all references which are
not to tangible things and kinds.
</p>
<pre class="display">
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">object_of_sentences</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">subject_of_sentences</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">subject_seems_to_be_plural</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="functiontext">Assertions::Traverse::get_current_subject<button class="popup" onclick="togglePopup('usagePopup507')">...<span class="popuptext" id="usagePopup507">Usage of <b>Assertions::Traverse::get_current_subject</b>:<br><a href="9-tfa.html#SP11">&#167;11</a>, Make Assertions - <a href="9-ma.html#SP3_3_41_1">&#167;3.3.41.1</a>, <a href="9-ma.html#SP3_3_41_4">&#167;3.3.41.4</a></span></button></span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">subject_of_sentences</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="functiontext">Assertions::Traverse::get_current_object<button class="popup" onclick="togglePopup('usagePopup508')">...<span class="popuptext" id="usagePopup508">Usage of <b>Assertions::Traverse::get_current_object</b>:<br>Refine Parse Tree - <a href="9-rpt.html#SP9_7_4">&#167;9.7.4</a></span></button></span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">object_of_sentences</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Assertions::Traverse::get_current_subject_plurality<button class="popup" onclick="togglePopup('usagePopup509')">...<span class="popuptext" id="usagePopup509">Usage of <b>Assertions::Traverse::get_current_subject_plurality</b>:<br>Refine Parse Tree - <a href="9-rpt.html#SP9_7_4">&#167;9.7.4</a></span></button></span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">subject_seems_to_be_plural</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>The routine <code class="display"><span class="extract">Assertions::Traverse::new_discussion</span></code> is called when we reach a
heading or other barrier in the source text, to make clear that there has
been a change of the topic discussed.
</p>
<p class="inwebparagraph"><code class="display"><span class="extract">Assertions::Traverse::change_discussion_topic</span></code> is called once at the end of
processing each assertion during each pass.
</p>
<p class="inwebparagraph">Note that we are careful to avoid changing the subject with sentences like:
</p>
<blockquote>
<p>East is the Central Plaza.</p>
</blockquote>
<p class="inwebparagraph">where this does not have the subject "east", but has instead an implicit
subject carried over from previous sentences.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Traverse::new_discussion<button class="popup" onclick="togglePopup('usagePopup510')">...<span class="popuptext" id="usagePopup510">Usage of <b>Assertions::Traverse::new_discussion</b>:<br><a href="9-tfa.html#SP7">&#167;7</a>, Headings - <a href="7-hdn.html#SP9">&#167;9</a><br>Extension Files - <a href="8-ef.html#SP14">&#167;14</a><br>To Be and To Have - <a href="9-tbath.html#SP5_1">&#167;5.1</a></span></button></span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">subject_of_sentences</span><span class="plain">)</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PRONOUNS</span><span class="plain">, </span><span class="string">"[Forgotten subject of sentences: $j]\n"</span><span class="plain">, </span><span class="identifier">subject_of_sentences</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">subject_of_sentences</span><span class="plain">)</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PRONOUNS</span><span class="plain">, </span><span class="string">"[Forgotten object of sentences: $j]\n"</span><span class="plain">, </span><span class="identifier">object_of_sentences</span><span class="plain">);</span>
<span class="identifier">subject_of_sentences</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">object_of_sentences</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Traverse::change_discussion_topic<button class="popup" onclick="togglePopup('usagePopup511')">...<span class="popuptext" id="usagePopup511">Usage of <b>Assertions::Traverse::change_discussion_topic</b>:<br>To Be and To Have - <a href="9-tbath.html#SP5_1">&#167;5.1</a></span></button></span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infsx</span><span class="plain">,</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infsy</span><span class="plain">, </span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infsy_full</span><span class="plain">) {</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">old_sub</span><span class="plain"> = </span><span class="identifier">subject_of_sentences</span><span class="plain">, *</span><span class="identifier">old_obj</span><span class="plain"> = </span><span class="identifier">object_of_sentences</span><span class="plain">;</span>
<span class="identifier">subject_seems_to_be_plural</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="identifier">Wordings::length</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">)) &gt; </span><span class="constant">1</span><span class="plain">) </span><span class="identifier">near_start_of_extension</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">ParseTree::set_interpretation_of_subject</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">, </span><span class="identifier">subject_of_sentences</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::has_annotation</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">, </span><span class="constant">implicit_in_creation_of_ANNOT</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">PL::Map::is_a_direction</span><span class="plain">(</span><span class="identifier">infsx</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">((</span><span class="functiontext"><a href="16-is.html#SP19">InferenceSubjects::as_object_instance</a></span><span class="plain">(</span><span class="identifier">infsx</span><span class="plain">) == </span><span class="identifier">NULL</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="functiontext"><a href="16-is.html#SP19">InferenceSubjects::as_object_instance</a></span><span class="plain">(</span><span class="identifier">infsy_full</span><span class="plain">)))) </span><span class="identifier">infsx</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">infsx</span><span class="plain">) </span><span class="identifier">subject_of_sentences</span><span class="plain"> = </span><span class="identifier">infsx</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">infsy</span><span class="plain">) &amp;&amp; (</span><span class="functiontext"><a href="16-is.html#SP21">InferenceSubjects::domain</a></span><span class="plain">(</span><span class="identifier">infsy</span><span class="plain">) == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="identifier">object_of_sentences</span><span class="plain"> = </span><span class="identifier">infsy</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">infsx</span><span class="plain">) </span><span class="identifier">object_of_sentences</span><span class="plain"> = </span><span class="identifier">infsx</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">subject_of_sentences</span><span class="plain"> != </span><span class="identifier">old_sub</span><span class="plain">)</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PRONOUNS</span><span class="plain">, </span><span class="string">"[Changed subject of sentences to $j]\n"</span><span class="plain">,</span>
<span class="identifier">subject_of_sentences</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">object_of_sentences</span><span class="plain"> != </span><span class="identifier">old_obj</span><span class="plain">)</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PRONOUNS</span><span class="plain">, </span><span class="string">"[Changed object of sentences to $j]\n"</span><span class="plain">,</span>
<span class="identifier">object_of_sentences</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. </b>Occasionally we need to force the issue, though:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Traverse::subject_of_discussion_a_list<button class="popup" onclick="togglePopup('usagePopup512')">...<span class="popuptext" id="usagePopup512">Usage of <b>Assertions::Traverse::subject_of_discussion_a_list</b>:<br>To Be and To Have - <a href="9-tbath.html#SP5_1">&#167;5.1</a></span></button></span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">subject_seems_to_be_plural</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="inwebparagraph"><a id="SP15"></a><b>&#167;15. </b></p>
<pre class="display">
<span class="reserved">sentence_handler</span><span class="plain"> </span><span class="identifier">SPECIAL_MEANING_SH_handler</span><span class="plain"> =</span>
<span class="plain">{ </span><span class="identifier">SENTENCE_NT</span><span class="plain">, </span><span class="constant">SPECIAL_MEANING_VB</span><span class="plain">, </span><span class="constant">0</span><span class="plain">, </span><span class="functiontext"><a href="9-tfa.html#SP15">Assertions::Traverse::special_meaning</a></span><span class="plain"> };</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Traverse::special_meaning<button class="popup" onclick="togglePopup('usagePopup513')">...<span class="popuptext" id="usagePopup513">Usage of <b>Assertions::Traverse::special_meaning</b>:<br>none</span></button></span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pn</span><span class="plain">) {</span>
<span class="functiontext"><a href="9-tfa.html#SP15">Assertions::Traverse::try_special_meaning</a></span><span class="plain">(</span><span class="identifier">traverse</span><span class="plain">, </span><span class="identifier">pn</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Assertions::Traverse::try_special_meaning<button class="popup" onclick="togglePopup('usagePopup514')">...<span class="popuptext" id="usagePopup514">Usage of <b>Assertions::Traverse::try_special_meaning</b>:<br>Construction Sequence - <a href="22-cs.html#SP9">&#167;9</a></span></button></span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">task</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pn</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">, </span><span class="constant">verb_id_ANNOT</span><span class="plain">) == </span><span class="constant">SPECIAL_MEANING_VB</span><span class="plain">) {</span>
<span class="identifier">verb_meaning</span><span class="plain"> *</span><span class="identifier">vm</span><span class="plain"> = </span><span class="identifier">ParseTree::get_verb_meaning</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VerbMeanings::is_meaningless</span><span class="plain">(</span><span class="identifier">vm</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rev</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">special_meaning_fn</span><span class="plain"> </span><span class="identifier">soa</span><span class="plain"> = </span><span class="identifier">VerbMeanings::get_special_meaning</span><span class="plain">(</span><span class="identifier">vm</span><span class="plain">, &amp;</span><span class="identifier">rev</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">soa</span><span class="plain">) {</span>
<span class="plain">(*</span><span class="identifier">soa</span><span class="plain">)(</span><span class="identifier">task</span><span class="plain">, </span><span class="identifier">pn</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<hr class="tocbar">
<ul class="toc"><li><a href="9-ita.html">Back to 'Introduction to Assertions'</a></li><li><a href="9-tbath.html">Continue with 'To Be and To Have'</a></li></ul><hr class="tocbar">
<!--End of weave-->
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
</main>
</body>
</html>