1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 08:34:22 +03:00
inform7/docs/core-module/22-pu.html
2020-04-07 01:06:09 +01:00

1627 lines
186 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>22/ph</title>
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<nav role="navigation">
<h1><a href="../webs.html">Sources</a></h1>
<ul>
<li><a href="../compiler.html"><b>compiler tools</b></a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul>
<h2>Compiler Webs</h2>
<ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
</ul>
<h2>Inbuild Modules</h2>
<ul>
<li><a href="../inbuild-module/index.html">inbuild</a></li>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../html-module/index.html">html</a></li>
</ul>
<h2>Inform7 Modules</h2>
<ul>
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="../index-module/index.html">index</a></li>
</ul>
<h2>Inter Modules</h2>
<ul>
<li><a href="../inter-module/index.html">inter</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul>
<h2>Foundation</h2>
<ul>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of '22/pu' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Modules</a></li><li><a href="index.html">core</a></li><li><a href="index.html#22">Chapter 22: Phrases</a></li><li><b>Phrase Usage</b></li></ul><p class="purpose">To parse the preamble of a phrase declaration to a phrase usage (PHUD) structure containing a mostly textual representation of the conditions for its usage.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li><li><a href="#SP5">&#167;5. The mid-morning predeclarations</a></li><li><a href="#SP6">&#167;6. The late-morning creations</a></li><li><a href="#SP7">&#167;7. Parsing</a></li><li><a href="#SP13">&#167;13. Extracting the stem</a></li><li><a href="#SP16">&#167;16. Miscellaneous</a></li><li><a href="#SP17">&#167;17. Logging and indexing</a></li><li><a href="#SP20">&#167;20. How the PHUD translates into a PHRCD</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>As we've seen, phrases can be categorised according to their "effect".
We need one more code:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">AS_YET_UNKNOWN_EFF</span><span class="plain"> </span><span class="constant">0</span><span class="plain"> </span><span class="comment">used only temporarily during header parsing</span>
</pre>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>And here is the usage data.
</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">ph_usage_data</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">full_preamble</span><span class="plain">; </span><span class="comment">e.g. to identify nameless rules in the log</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">constant_phrase</span><span class="plain"> *</span><span class="identifier">constant_phrase_holder</span><span class="plain">; </span><span class="comment">for named To... phrases</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">phrase_effect</span><span class="plain">; </span><span class="comment">see below: basically, how the phrase is invoked</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">to_begin</span><span class="plain">; </span><span class="comment">used in Basic mode only: this is to be the main phrase</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">timing_of_event</span><span class="plain">; </span><span class="comment">one of two values defined below; or a specific time</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">use_as_event</span><span class="plain"> *</span><span class="identifier">uses_as_event</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">explicit_name</span><span class="plain">; </span><span class="comment">if a named rule, this is its name</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">explicit_name_used_in_maths</span><span class="plain">; </span><span class="comment">if so, this flag means it's like <code class="display"><span class="extract">log()</span></code> or <code class="display"><span class="extract">sin()</span></code></span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">explicit_name_for_inverse</span><span class="plain">; </span><span class="comment">e.g. <code class="display"><span class="extract">exp</span></code> for <code class="display"><span class="extract">log</span></code></span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">whenwhile</span><span class="plain">; </span><span class="comment">when/while for action/activity rulebooks</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">rule_preamble</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">rule_parameter</span><span class="plain">; </span><span class="comment">text of object or action parameter</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">during_scene_spec</span><span class="plain">; </span><span class="comment">what scene is currently under way</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">event_name</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">rulebook</span><span class="plain"> *</span><span class="identifier">owning_rulebook</span><span class="plain">; </span><span class="comment">the primary booking for the phrase will be here</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">owning_rulebook_placement</span><span class="plain">; </span><span class="comment">...and with this placement value: see Rulebooks</span>
<span class="plain">} </span><span class="reserved">ph_usage_data</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure ph_usage_data is accessed in 22/ph, 22/dptd, 22/pav, 22/tp2 and here.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>We will need to store values temporarily here while parsing:
</p>
<pre class="display">
<span class="reserved">rulebook_match</span><span class="plain"> </span><span class="identifier">parsed_rm</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. The mid-morning predeclarations. </b>Recall that early in Inform's run, we make a coarse parsing of the preamble
of each rule to look for a name: if we find it, we declare it as a rule;
and in any event we throw away the PHUD produced. (We will make a better one
just before noon.)
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Usage::predeclare_name_in</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="reserved">ph_usage_data</span><span class="plain"> </span><span class="identifier">phud</span><span class="plain"> = </span><span class="functiontext">Phrases::Usage::new</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">TRUE</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">phud</span><span class="plain">.</span><span class="element">explicit_name</span><span class="plain">))</span>
<span class="functiontext">Rules::new</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">.</span><span class="element">explicit_name</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Usage::predeclare_name_in is used in 22/cs (<a href="22-cs.html#SP2">&#167;2</a>).</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. The late-morning creations. </b>A little later on, we've made a rule phrase, and it now has a proper PHUD.
If the rule is an anonymous one, such as:
</p>
<blockquote>
<p>Instead of jumping: say "Don't."</p>
</blockquote>
<p class="inwebparagraph">then we need to call <code class="display"><span class="extract">Rules::new</span></code> to create a nameless <code class="display"><span class="extract">rule</span></code> structure
to be connected to it. But if the phrase has an explicit name:
</p>
<blockquote>
<p>Instead of swimming (this is the avoid water rule): say "Don't."</p>
</blockquote>
<p class="inwebparagraph">then we have a predeclared rule called "avoid water rule" already, so we
connect this existing one to the phrase.
</p>
<pre class="display">
<span class="reserved">rule</span><span class="plain"> *</span><span class="functiontext">Phrases::Usage::to_rule</span><span class="plain">(</span><span class="reserved">ph_usage_data</span><span class="plain"> *</span><span class="identifier">phud</span><span class="plain">, </span><span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</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">EMPTY_WORDING</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">explicitly</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Find the name of the phrase, and whether or not it's explicitly given</span> <span class="cwebmacronumber">6.1</span>&gt;<span class="character">;</span>
<span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">Rules::by_name</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="identifier">R</span><span class="plain">) </span>&lt;<span class="cwebmacro">Check that this isn't duplicating the name of a rule already made</span> <span class="cwebmacronumber">6.2</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">Rules::new</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">explicitly</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::empty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">))</span>
<span class="functiontext">Hierarchy::markup_wording</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">-&gt;</span><span class="element">rule_package</span><span class="plain">, </span><span class="constant">RULE_NAME_HMD</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">declaration_node</span><span class="plain">));</span>
<span class="functiontext">Rules::set_I7_definition</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">);</span>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="functiontext">Rules::package</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">);</span>
<span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">ph_iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_localised_iname_in</span><span class="plain">(</span><span class="constant">RULE_FN_HL</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">owning_module</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Do some tedious business for indexing the rule later on</span> <span class="cwebmacronumber">6.3</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">R</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Usage::to_rule is used in 22/ph (<a href="22-ph.html#SP6_7">&#167;6.7</a>).</p>
<p class="inwebparagraph"><a id="SP6_1"></a><b>&#167;6.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Find the name of the phrase, and whether or not it's explicitly given</span> <span class="cwebmacronumber">6.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">event_name</span><span class="plain">)) {</span>
<span class="identifier">W</span><span class="plain"> = </span><span class="identifier">Articles::remove_the</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">event_name</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">explicit_name</span><span class="plain">)) {</span>
<span class="identifier">W</span><span class="plain"> = </span><span class="identifier">Articles::remove_the</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">explicit_name</span><span class="plain">);</span>
<span class="identifier">explicitly</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP6_2"></a><b>&#167;6.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Check that this isn't duplicating the name of a rule already made</span> <span class="cwebmacronumber">6.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph_found</span><span class="plain"> = </span><span class="functiontext">Rules::get_I7_definition</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ph_found</span><span class="plain">) &amp;&amp; (</span><span class="identifier">ph_found</span><span class="plain"> != </span><span class="identifier">ph</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">W</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_DuplicateRuleName</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but this would give a name ('%2') to a "</span>
<span class="string">"new rule which already belongs to an existing one."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP6_3"></a><b>&#167;6.3. </b>This is simply to make the rule's entry in the Index more helpful.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Do some tedious business for indexing the rule later on</span> <span class="cwebmacronumber">6.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">IX</span><span class="plain"> = </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</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">phud</span><span class="plain">-&gt;</span><span class="element">whenwhile</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">whenwhile</span><span class="plain">) == </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</span><span class="plain">) + </span><span class="constant">1</span><span class="plain">) {</span>
<span class="identifier">IX</span><span class="plain"> = </span><span class="identifier">Wordings::new</span><span class="plain">(</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</span><span class="plain">), </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">whenwhile</span><span class="plain">));</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">IX</span><span class="plain"> = </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="identifier">whenwhile</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="functiontext">Rules::set_italicised_index_text</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">, </span><span class="identifier">IX</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Parsing. </b>For our purposes here, phrase definitions and rules are the same thing. Inform
detects these from the punctuation used, not from their wording, and divides
them into a "preamble" (the part before the colon, or in limited cases a
comma) and a "body". Early on in Inform's run, we parse the preamble in
what's called "coarse mode" &mdash; we look for very little detail, and detect
just enough from the wording to tell what sort of rule/phrase is to follow.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">&gt; ::=</span>
<span class="reserved">definition</span><span class="plain"> | ==&gt; </span><span class="constant">DEFINITIONAL_PHRASE_EFF</span>
<span class="identifier">this</span><span class="plain"> </span><span class="identifier">is</span><span class="plain"> </span><span class="identifier">the</span><span class="plain"> {... </span><span class="reserved">rule</span><span class="plain">} | ==&gt; </span><span class="constant">RULE_NOT_IN_RULEBOOK_EFF</span><span class="plain">; &lt;&lt;</span><span class="identifier">event</span><span class="plain">-</span><span class="identifier">time</span><span class="plain">&gt;&gt; = </span><span class="constant">NOT_AN_EVENT</span><span class="plain">; &lt;&lt;</span><span class="identifier">written</span><span class="plain">&gt;&gt; = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">this</span><span class="plain"> </span><span class="identifier">is</span><span class="plain"> </span><span class="identifier">the</span><span class="plain"> </span><span class="reserved">rule</span><span class="plain"> | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_NamelessRule problem</span> <span class="cwebmacronumber">7.1</span>&gt;
<span class="identifier">this</span><span class="plain"> </span><span class="identifier">is</span><span class="plain"> ... </span><span class="reserved">rule</span><span class="plain"> | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_UnarticledRule problem</span> <span class="cwebmacronumber">7.2</span>&gt;
<span class="identifier">this</span><span class="plain"> </span><span class="identifier">is</span><span class="plain"> ... </span><span class="identifier">rules</span><span class="plain"> | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_PluralisedRule problem</span> <span class="cwebmacronumber">7.3</span>&gt;
<span class="plain">&lt;</span><span class="identifier">event</span><span class="plain">-</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">&gt; | ==&gt; </span><span class="constant">RULE_NOT_IN_RULEBOOK_EFF</span><span class="plain">; &lt;&lt;</span><span class="identifier">event</span><span class="plain">-</span><span class="identifier">time</span><span class="plain">&gt;&gt; = </span><span class="identifier">R</span><span class="plain">[1]</span>
<span class="identifier">to</span><span class="plain"> | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_BareTo problem</span> <span class="cwebmacronumber">7.4</span>&gt;
<span class="identifier">to</span><span class="plain"> ... ( </span><span class="identifier">called</span><span class="plain"> ... ) | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_DontCallPhrasesWithCalled problem</span> <span class="cwebmacronumber">7.5</span>&gt;
<span class="plain">{</span><span class="identifier">to</span><span class="plain"> ...} ( </span><span class="identifier">this</span><span class="plain"> </span><span class="identifier">is</span><span class="plain"> </span><span class="identifier">the</span><span class="plain"> {### </span><span class="identifier">function</span><span class="plain">} </span><span class="identifier">inverse</span><span class="plain"> </span><span class="identifier">to</span><span class="plain"> ### ) | ==&gt; </span><span class="constant">TO_PHRASE_EFF</span><span class="plain">; &lt;&lt;</span><span class="identifier">named</span><span class="plain">&gt;&gt; = </span><span class="identifier">TRUE</span><span class="plain">; &lt;&lt;</span><span class="identifier">written</span><span class="plain">&gt;&gt; = </span><span class="identifier">TRUE</span><span class="plain">; &lt;&lt;</span><span class="identifier">inverted</span><span class="plain">&gt;&gt; = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">{</span><span class="identifier">to</span><span class="plain"> ...} ( </span><span class="identifier">this</span><span class="plain"> </span><span class="identifier">is</span><span class="plain"> </span><span class="identifier">the</span><span class="plain"> {### </span><span class="identifier">function</span><span class="plain">} ) | ==&gt; </span><span class="constant">TO_PHRASE_EFF</span><span class="plain">; &lt;&lt;</span><span class="identifier">named</span><span class="plain">&gt;&gt; = </span><span class="identifier">TRUE</span><span class="plain">; &lt;&lt;</span><span class="identifier">written</span><span class="plain">&gt;&gt; = </span><span class="identifier">TRUE</span><span class="plain">; &lt;&lt;</span><span class="identifier">inverted</span><span class="plain">&gt;&gt; = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">{</span><span class="identifier">to</span><span class="plain"> ...} ( </span><span class="identifier">this</span><span class="plain"> </span><span class="identifier">is</span><span class="plain"> ... ) | ==&gt; </span><span class="constant">TO_PHRASE_EFF</span><span class="plain">; &lt;&lt;</span><span class="identifier">named</span><span class="plain">&gt;&gt; = </span><span class="identifier">TRUE</span><span class="plain">; &lt;&lt;</span><span class="identifier">written</span><span class="plain">&gt;&gt; = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">to</span><span class="plain"> ... | ==&gt; </span><span class="constant">TO_PHRASE_EFF</span><span class="plain">; &lt;&lt;</span><span class="identifier">named</span><span class="plain">&gt;&gt; = </span><span class="identifier">FALSE</span>
<span class="plain">... ( </span><span class="identifier">this</span><span class="plain"> </span><span class="identifier">is</span><span class="plain"> </span><span class="identifier">the</span><span class="plain"> {... </span><span class="reserved">rule</span><span class="plain">} ) | ==&gt; </span><span class="constant">RULE_IN_RULEBOOK_EFF</span><span class="plain">; &lt;&lt;</span><span class="identifier">named</span><span class="plain">&gt;&gt; = </span><span class="identifier">TRUE</span><span class="plain">; &lt;&lt;</span><span class="identifier">written</span><span class="plain">&gt;&gt; = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">... ( </span><span class="identifier">this</span><span class="plain"> </span><span class="identifier">is</span><span class="plain"> </span><span class="identifier">the</span><span class="plain"> </span><span class="reserved">rule</span><span class="plain"> ) | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_NamelessRule problem</span> <span class="cwebmacronumber">7.1</span>&gt;
<span class="plain">... ( </span><span class="identifier">this</span><span class="plain"> </span><span class="identifier">is</span><span class="plain"> ... </span><span class="reserved">rule</span><span class="plain"> ) | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_UnarticledRule problem</span> <span class="cwebmacronumber">7.2</span>&gt;
<span class="plain">... ( </span><span class="identifier">this</span><span class="plain"> </span><span class="identifier">is</span><span class="plain"> ... </span><span class="identifier">rules</span><span class="plain"> ) | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_PluralisedRule problem</span> <span class="cwebmacronumber">7.3</span>&gt;
<span class="plain">... ==&gt; </span><span class="constant">RULE_IN_RULEBOOK_EFF</span><span class="plain">; &lt;&lt;</span><span class="identifier">named</span><span class="plain">&gt;&gt; = </span><span class="identifier">FALSE</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP7_1"></a><b>&#167;7.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_NamelessRule problem</span> <span class="cwebmacronumber">7.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_NamelessRule</span><span class="plain">),</span>
<span class="string">"there are many rules in Inform"</span><span class="plain">,</span>
<span class="string">"so you need to give a name: 'this is the abolish dancing rule', say, "</span>
<span class="string">"not just 'this is the rule'."</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a> (twice).</p>
<p class="inwebparagraph"><a id="SP7_2"></a><b>&#167;7.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_UnarticledRule problem</span> <span class="cwebmacronumber">7.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_UnarticledRule</span><span class="plain">),</span>
<span class="string">"a rule must be given a definite name"</span><span class="plain">,</span>
<span class="string">"which begins with 'the', just to emphasise that it is the only one "</span>
<span class="string">"with this name: 'this is the promote dancing rule', say, not just "</span>
<span class="string">"'this is promote dancing rule'."</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a> (twice).</p>
<p class="inwebparagraph"><a id="SP7_3"></a><b>&#167;7.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_PluralisedRule problem</span> <span class="cwebmacronumber">7.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_PluralisedRule</span><span class="plain">),</span>
<span class="string">"a rule must be given a definite name ending in 'rule' not 'rules'"</span><span class="plain">,</span>
<span class="string">"since the plural is only used for rulebooks, which can of course "</span>
<span class="string">"contain many rules at once."</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a> (twice).</p>
<p class="inwebparagraph"><a id="SP7_4"></a><b>&#167;7.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_BareTo problem</span> <span class="cwebmacronumber">7.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_BareTo</span><span class="plain">),</span>
<span class="string">"'to' what? No name is given"</span><span class="plain">,</span>
<span class="string">"which means that this would not define a new phrase."</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7_5"></a><b>&#167;7.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_DontCallPhrasesWithCalled problem</span> <span class="cwebmacronumber">7.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_DontCallPhrasesWithCalled</span><span class="plain">),</span>
<span class="string">"phrases aren't named using 'called'"</span><span class="plain">,</span>
<span class="string">"and instead use 'this is...'. For example, 'To salute (called saluting)' "</span>
<span class="string">"isn't allowed, but 'To salute (this is saluting)' is."</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>As a safety measure, to avoid ambiguities, Inform only allows one phrase
definition to begin with "now". It recognises such phrases as those whose
preambles match:
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">now</span><span class="plain">-</span><span class="reserved">phrase</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">&gt; ::=</span>
<span class="identifier">to</span><span class="plain"> </span><span class="identifier">now</span><span class="plain"> ...</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>In basic mode (only), the To phrase "to begin" acts as something like
<code class="display"><span class="extract">main</span></code> in a C-like language, so we need to take note of where it's defined:
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">begin</span><span class="plain">-</span><span class="reserved">phrase</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">&gt; ::=</span>
<span class="identifier">to</span><span class="plain"> </span><span class="identifier">begin</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>Much later on, Inform returns to the definition. If the preamble matches
either of the final two productions of &lt;rule-preamble&gt;, then we definitely
have a rule rather than a phrase definition or a timed event; and in that
case the rule's preamble (without its name, if given) has to match the
following grammar. (Parsing this is "fine mode".)
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">-</span><span class="identifier">fine</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">-</span><span class="identifier">finer</span><span class="plain">&gt; </span><span class="identifier">during</span><span class="plain"> &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">scene</span><span class="plain">-</span><span class="identifier">description</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">R</span><span class="plain">[1]; &lt;&lt;</span><span class="identifier">parse_node:scenes</span><span class="plain">&gt;&gt; = </span><span class="identifier">RP</span><span class="plain">[2]</span>
<span class="plain">&lt;</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">-</span><span class="identifier">finer</span><span class="plain">&gt; ==&gt; </span><span class="identifier">R</span><span class="plain">[1]; &lt;&lt;</span><span class="identifier">parse_node:scenes</span><span class="plain">&gt;&gt; = </span><span class="identifier">NULL</span>
<span class="plain">&lt;</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">-</span><span class="identifier">finer</span><span class="plain">&gt; ::=</span>
<span class="plain">{&lt;</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">stem</span><span class="plain">-</span><span class="identifier">embellished</span><span class="plain">&gt;} {</span><span class="identifier">when</span><span class="plain">/</span><span class="reserved">while</span><span class="plain"> ...} | ==&gt; </span><span class="identifier">TRUE</span>
<span class="plain">{&lt;</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">stem</span><span class="plain">-</span><span class="identifier">embellished</span><span class="plain">&gt;} | ==&gt; </span><span class="identifier">FALSE</span>
<span class="plain">... ==&gt; </span><span class="identifier">NOT_APPLICABLE</span>
<span class="plain">&lt;</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">stem</span><span class="plain">-</span><span class="identifier">embellished</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">stem</span><span class="plain">&gt; *** | ==&gt; </span><span class="constant">0</span><span class="plain">; &lt;&lt;</span><span class="identifier">bud1</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[1]); &lt;&lt;</span><span class="identifier">bud2</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[1])</span>
<span class="plain">&lt;</span><span class="identifier">article</span><span class="plain">&gt; </span><span class="reserved">rule</span><span class="plain"> </span><span class="reserved">for</span><span class="plain"> &lt;</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">stem</span><span class="plain">&gt; *** | ==&gt; </span><span class="constant">0</span><span class="plain">; &lt;&lt;</span><span class="identifier">bud1</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[1]); &lt;&lt;</span><span class="identifier">bud2</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[1])</span>
<span class="plain">&lt;</span><span class="identifier">article</span><span class="plain">&gt; </span><span class="reserved">rule</span><span class="plain"> &lt;</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">stem</span><span class="plain">&gt; *** | ==&gt; </span><span class="constant">0</span><span class="plain">; &lt;&lt;</span><span class="identifier">bud1</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[1]); &lt;&lt;</span><span class="identifier">bud2</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[1])</span>
<span class="reserved">rule</span><span class="plain"> </span><span class="reserved">for</span><span class="plain"> &lt;</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">stem</span><span class="plain">&gt; *** | ==&gt; </span><span class="constant">0</span><span class="plain">; &lt;&lt;</span><span class="identifier">bud1</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[1]); &lt;&lt;</span><span class="identifier">bud2</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[1])</span>
<span class="reserved">rule</span><span class="plain"> &lt;</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">stem</span><span class="plain">&gt; *** ==&gt; </span><span class="constant">0</span><span class="plain">; &lt;&lt;</span><span class="identifier">bud1</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[1]); &lt;&lt;</span><span class="identifier">bud2</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[1])</span>
<span class="plain">&lt;</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">bud</span><span class="plain">&gt; ::=</span>
<span class="identifier">of</span><span class="plain">/</span><span class="reserved">for</span><span class="plain"> ... | ==&gt; </span><span class="identifier">TRUE</span>
<span class="reserved">rule</span><span class="plain"> </span><span class="identifier">about</span><span class="plain">/</span><span class="reserved">for</span><span class="plain">/</span><span class="identifier">on</span><span class="plain"> ... | ==&gt; </span><span class="identifier">TRUE</span>
<span class="reserved">rule</span><span class="plain"> ==&gt; </span><span class="identifier">FALSE</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>The following turns the preamble text into a PHUD. It can be used as often
as necessary in "coarse mode", but should be run once and once only on any
given phrase when in "fine mode".
</p>
<p class="inwebparagraph">Coarse mode uses only punctuation and some fixed keywords, so it works at
any time in the "morning" &mdash; that is, when most of the names don't yet
exist. The down side is that it doesn't provide detailed usage information
for <code class="display"><span class="extract">RULE_IN_RULEBOOK_EFF</span></code> rules, but it does get everything else right.
(This is only possible because an ambiguity was removed in December 2006,
removing the possibility of "when" introducing rules of two different
effects &mdash; see below.)
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_now_phrases</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">ph_usage_data</span><span class="plain"> </span><span class="functiontext">Phrases::Usage::new</span><span class="plain">(</span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">coarse_mode</span><span class="plain">) {</span>
<span class="reserved">ph_usage_data</span><span class="plain"> </span><span class="identifier">phud</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Empty the PHUD</span> <span class="cwebmacronumber">11.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">)) {</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">phrase_effect</span><span class="plain"> = &lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">switch</span><span class="plain"> (&lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt;) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">TO_PHRASE_EFF:</span>
&lt;<span class="cwebmacro">The preamble parses to a To phrase</span> <span class="cwebmacronumber">11.2</span>&gt;<span class="plain">;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">DEFINITIONAL_PHRASE_EFF:</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">RULE_IN_RULEBOOK_EFF:</span>
&lt;<span class="cwebmacro">The preamble parses to a rule with a specified rulebook</span> <span class="cwebmacronumber">11.3</span>&gt;<span class="plain">;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">RULE_NOT_IN_RULEBOOK_EFF:</span>
&lt;<span class="cwebmacro">The preamble parses to a rule with no specified rulebook</span> <span class="cwebmacronumber">11.4</span>&gt;<span class="plain">;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">phud</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Usage::new is used in <a href="#SP5">&#167;5</a>, 22/ph (<a href="22-ph.html#SP6_2">&#167;6.2</a>).</p>
<p class="inwebparagraph"><a id="SP11_1"></a><b>&#167;11.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Empty the PHUD</span> <span class="cwebmacronumber">11.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">phud</span><span class="plain">.</span><span class="element">full_preamble</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">;</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">constant_phrase_holder</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">phrase_effect</span><span class="plain"> = </span><span class="constant">AS_YET_UNKNOWN_EFF</span><span class="plain">;</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">explicit_name</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">explicit_name_used_in_maths</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">rule_preamble</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">rule_parameter</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">whenwhile</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">to_begin</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">during_scene_spec</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="identifier">phud</span><span class="plain">.</span><span class="element">event_name</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">timing_of_event</span><span class="plain"> = </span><span class="constant">NOT_A_TIMED_EVENT</span><span class="plain">;</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">uses_as_event</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">owning_rulebook</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">owning_rulebook_placement</span><span class="plain"> = </span><span class="constant">MIDDLE_PLACEMENT</span><span class="plain">;</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">explicit_name_for_inverse</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#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">The preamble parses to a To phrase</span> <span class="cwebmacronumber">11.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">phud</span><span class="plain">.</span><span class="element">rule_preamble</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;&lt;</span><span class="identifier">named</span><span class="plain">&gt;&gt;) </span>&lt;<span class="cwebmacro">The preamble parses to a named To phrase</span> <span class="cwebmacronumber">11.2.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">now</span><span class="plain">-</span><span class="reserved">phrase</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">coarse_mode</span><span class="plain">) &amp;&amp; (</span><span class="identifier">no_now_phrases</span><span class="plain">++ == </span><span class="constant">1</span><span class="plain">)) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RedefinedNow</span><span class="plain">),</span>
<span class="string">"creating new variants on 'now' is not allowed"</span><span class="plain">,</span>
<span class="string">"because 'now' plays a special role in the language. "</span>
<span class="string">"It has a wide-ranging ability to make a condition "</span>
<span class="string">"become immediately true. (To give it wider abilities, "</span>
<span class="string">"the idea is to create new relations.)"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">begin</span><span class="plain">-</span><span class="reserved">phrase</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">)) {</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">to_begin</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11">&#167;11</a>.</p>
<p class="inwebparagraph"><a id="SP11_2_1"></a><b>&#167;11.2.1. </b>When we parse a named phrase in coarse mode, we need to make sure that
name is registered as a constant value; when we parse it again in fine
mode, we can get that value back again if we look it up by name.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">The preamble parses to a named To phrase</span> <span class="cwebmacronumber">11.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">RW</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">&gt;, </span><span class="constant">1</span><span class="plain">);</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">NW</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">&gt;, </span><span class="constant">2</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">coarse_mode</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">type</span><span class="plain">-</span><span class="identifier">expression</span><span class="plain">&gt;(</span><span class="identifier">NW</span><span class="plain">)) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_PhraseNameDuplicated</span><span class="plain">),</span>
<span class="string">"that name for this new phrase is not allowed"</span><span class="plain">,</span>
<span class="string">"because it already has a meaning."</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">constant_phrase_holder</span><span class="plain"> = </span><span class="functiontext">Phrases::Constants::parse</span><span class="plain">(</span><span class="identifier">NW</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phud</span><span class="plain">.</span><span class="element">constant_phrase_holder</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">constant_phrase_holder</span><span class="plain"> =</span>
<span class="functiontext">Phrases::Constants::create</span><span class="plain">(</span><span class="identifier">NW</span><span class="plain">, </span><span class="identifier">RW</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">constant_phrase</span><span class="plain"> *</span><span class="identifier">cphr</span><span class="plain"> = </span><span class="functiontext">Phrases::Constants::parse</span><span class="plain">(</span><span class="identifier">NW</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Behaviour::definite</span><span class="plain">(</span><span class="identifier">cphr</span><span class="plain">-&gt;</span><span class="element">cphr_kind</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain"> = </span><span class="functiontext">Phrases::Constants::as_phrase</span><span class="plain">(</span><span class="identifier">cphr</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ph</span><span class="plain">) </span><span class="identifier">current_sentence</span><span class="plain"> = </span><span class="functiontext">Phrases::declaration_node</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">);</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">NounPhrases::new_raw</span><span class="plain">(</span><span class="identifier">Nouns::nominative</span><span class="plain">(</span><span class="identifier">cphr</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">)));</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">Nouns::nominative</span><span class="plain">(</span><span class="identifier">cphr</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_NamedGeneric</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"I can't allow %1, because the phrase it gives a name to "</span>
<span class="string">"is generic, that is, it has a kind which is too vague. "</span>
<span class="string">"That means there isn't any single phrase which '%2' "</span>
<span class="string">"could refer to - there would have to be different versions "</span>
<span class="string">"for every setting where it might be needed, and we can't "</span>
<span class="string">"predict in advance which one '%2' might need to be."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"CPHR failed at %d, $u\n"</span><span class="plain">, </span><span class="identifier">cphr</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">, </span><span class="identifier">cphr</span><span class="plain">-&gt;</span><span class="element">cphr_kind</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (&lt;&lt;</span><span class="identifier">written</span><span class="plain">&gt;&gt;) {</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">explicit_name_used_in_maths</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;&lt;</span><span class="identifier">inverted</span><span class="plain">&gt;&gt;) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">IW</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">&gt;, </span><span class="constant">3</span><span class="plain">);</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">explicit_name_for_inverse</span><span class="plain"> = </span><span class="identifier">Wordings::first_word</span><span class="plain">(</span><span class="identifier">IW</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">constant_phrase_holder</span><span class="plain"> = </span><span class="identifier">cphr</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">rule_preamble</span><span class="plain"> = </span><span class="identifier">RW</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11_2">&#167;11.2</a>.</p>
<p class="inwebparagraph"><a id="SP11_3"></a><b>&#167;11.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">The preamble parses to a rule with a specified rulebook</span> <span class="cwebmacronumber">11.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (&lt;&lt;</span><span class="identifier">named</span><span class="plain">&gt;&gt;) {</span>
<span class="identifier">W</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">&gt;, </span><span class="constant">1</span><span class="plain">);</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">explicit_name</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">&gt;, </span><span class="constant">2</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">coarse_mode</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span>&lt;<span class="cwebmacro">Parse the rulebook stem in fine mode</span> <span class="cwebmacronumber">11.3.1</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11">&#167;11</a>.</p>
<p class="inwebparagraph"><a id="SP11_4"></a><b>&#167;11.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">The preamble parses to a rule with no specified rulebook</span> <span class="cwebmacronumber">11.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (&lt;&lt;</span><span class="identifier">event</span><span class="plain">-</span><span class="identifier">time</span><span class="plain">&gt;&gt; == </span><span class="constant">NOT_AN_EVENT</span><span class="plain">) {</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">explicit_name</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">&gt;, </span><span class="constant">1</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rules::vet_name</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">.</span><span class="element">explicit_name</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">explicit_name</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">timing_of_event</span><span class="plain"> = &lt;&lt;</span><span class="identifier">event</span><span class="plain">-</span><span class="identifier">time</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">if</span><span class="plain"> (&lt;&lt;</span><span class="identifier">event</span><span class="plain">-</span><span class="identifier">time</span><span class="plain">&gt;&gt; == </span><span class="constant">NO_FIXED_TIME</span><span class="plain">)</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">event_name</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="identifier">event</span><span class="plain">-</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">&gt;, </span><span class="constant">1</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11">&#167;11</a>.</p>
<p class="inwebparagraph"><a id="SP11_3_1"></a><b>&#167;11.3.1. </b>That's it for coarse mode. The rest is what happens in fine mode, which
affects rules giving a rulebook and some circumstances:
</p>
<blockquote>
<p>Instead of taking a container: ...</p>
</blockquote>
<p class="inwebparagraph">Here "Instead of" is the stem and "taking a container" the bud.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Parse the rulebook stem in fine mode</span> <span class="cwebmacronumber">11.3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">&lt;</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">-</span><span class="identifier">fine</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">W</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">-</span><span class="identifier">finer</span><span class="plain">&gt;, </span><span class="constant">1</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (&lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt; == </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">) {</span>
<span class="plain">&lt;</span><span class="identifier">unrecognised</span><span class="plain">-</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">stem</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (&lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt;) </span><span class="identifier">phud</span><span class="plain">.</span><span class="element">whenwhile</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">preamble</span><span class="plain">-</span><span class="identifier">finer</span><span class="plain">&gt;, </span><span class="constant">2</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">during_scene_spec</span><span class="plain"> = &lt;&lt;</span><span class="identifier">parse_node:scenes</span><span class="plain">&gt;&gt;;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">owning_rulebook</span><span class="plain"> = </span><span class="identifier">parsed_rm</span><span class="plain">.</span><span class="identifier">matched_rulebook</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phud</span><span class="plain">.</span><span class="element">owning_rulebook</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"rulebook stem misparsed"</span><span class="plain">);</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">owning_rulebook_placement</span><span class="plain"> = </span><span class="identifier">parsed_rm</span><span class="plain">.</span><span class="element">placement_requested</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Disallow the definite article for anonymous rules</span> <span class="cwebmacronumber">11.3.1.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Cut off the bud from the stem</span> <span class="cwebmacronumber">11.3.1.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">rule_preamble</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11_3">&#167;11.3</a>.</p>
<p class="inwebparagraph"><a id="SP11_3_1_1"></a><b>&#167;11.3.1.1. </b>The bud is not always present at all, and need not always be at the end
of the stem, so we have to be very careful:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Cut off the bud from the stem</span> <span class="cwebmacronumber">11.3.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">b1</span><span class="plain"> = &lt;&lt;</span><span class="identifier">bud1</span><span class="plain">&gt;&gt;, </span><span class="identifier">b2</span><span class="plain"> = &lt;&lt;</span><span class="identifier">bud2</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">b1</span><span class="plain"> == -1) || (</span><span class="identifier">b1</span><span class="plain"> &gt; </span><span class="identifier">b2</span><span class="plain">)) {</span>
<span class="identifier">b1</span><span class="plain"> = </span><span class="identifier">parsed_rm</span><span class="plain">.</span><span class="element">match_from</span><span class="plain"> + </span><span class="identifier">parsed_rm</span><span class="plain">.</span><span class="element">advance_words</span><span class="plain">;</span>
<span class="identifier">b2</span><span class="plain"> = </span><span class="identifier">parsed_rm</span><span class="plain">.</span><span class="element">match_from</span><span class="plain"> + </span><span class="identifier">parsed_rm</span><span class="plain">.</span><span class="element">advance_words</span><span class="plain"> - </span><span class="constant">1</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">b2</span><span class="plain"> -= </span><span class="identifier">parsed_rm</span><span class="plain">.</span><span class="element">tail_words</span><span class="plain">;</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">BW</span><span class="plain"> = </span><span class="identifier">Wordings::new</span><span class="plain">(</span><span class="identifier">b1</span><span class="plain">, </span><span class="identifier">b2</span><span class="plain">);</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">CW</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parsed_rm</span><span class="plain">.</span><span class="element">advance_words</span><span class="plain"> != </span><span class="identifier">parsed_rm</span><span class="plain">.</span><span class="element">match_length</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (!((&lt;</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">bud</span><span class="plain">&gt;(</span><span class="identifier">BW</span><span class="plain">)) &amp;&amp; (&lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt; == </span><span class="identifier">FALSE</span><span class="plain">))) {</span>
<span class="identifier">BW</span><span class="plain"> = </span><span class="identifier">Wordings::from</span><span class="plain">(</span><span class="identifier">BW</span><span class="plain">, </span><span class="identifier">parsed_rm</span><span class="plain">.</span><span class="element">match_from</span><span class="plain"> + </span><span class="identifier">parsed_rm</span><span class="plain">.</span><span class="element">match_length</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">bud</span><span class="plain">&gt;(</span><span class="identifier">BW</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (&lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt;) </span><span class="identifier">CW</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">bud</span><span class="plain">&gt;, </span><span class="constant">1</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">CW</span><span class="plain"> = </span><span class="identifier">BW</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">bud</span><span class="plain">&gt;(</span><span class="identifier">BW</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (&lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt;) </span><span class="identifier">CW</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">bud</span><span class="plain">&gt;, </span><span class="constant">1</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">CW</span><span class="plain"> = </span><span class="identifier">BW</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">bud</span><span class="plain">&gt;(</span><span class="identifier">BW</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (&lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt;) </span><span class="identifier">CW</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">bud</span><span class="plain">&gt;, </span><span class="constant">1</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parsed_rm</span><span class="plain">.</span><span class="element">advance_words</span><span class="plain"> != </span><span class="identifier">parsed_rm</span><span class="plain">.</span><span class="element">match_length</span><span class="plain">) {</span>
<span class="identifier">BW</span><span class="plain"> = </span><span class="identifier">Wordings::from</span><span class="plain">(</span><span class="identifier">BW</span><span class="plain">, </span><span class="identifier">parsed_rm</span><span class="plain">.</span><span class="element">match_from</span><span class="plain"> + </span><span class="identifier">parsed_rm</span><span class="plain">.</span><span class="element">match_length</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">bud</span><span class="plain">&gt;(</span><span class="identifier">BW</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (&lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt;) </span><span class="identifier">CW</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">bud</span><span class="plain">&gt;, </span><span class="constant">1</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">CW</span><span class="plain"> = </span><span class="identifier">BW</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">CW</span><span class="plain"> = </span><span class="identifier">BW</span><span class="plain">;</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">CW</span><span class="plain">)) </span><span class="identifier">phud</span><span class="plain">.</span><span class="identifier">rule_parameter</span><span class="plain"> = </span><span class="identifier">CW</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">phud</span><span class="plain">.</span><span class="identifier">owning_rulebook</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Rulebooks::runs_during_activities</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">.</span><span class="element">owning_rulebook</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Rulebooks::focus</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">.</span><span class="element">owning_rulebook</span><span class="plain">) == </span><span class="constant">ACTION_FOCUS</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">.</span><span class="element">rule_parameter</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">.</span><span class="element">whenwhile</span><span class="plain">))) {</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">rule_parameter</span><span class="plain"> =</span>
<span class="identifier">Wordings::new</span><span class="plain">(</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">.</span><span class="element">rule_parameter</span><span class="plain">),</span>
<span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">.</span><span class="element">whenwhile</span><span class="plain">));</span>
<span class="identifier">phud</span><span class="plain">.</span><span class="element">whenwhile</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11_3_1">&#167;11.3.1</a>.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>If we can't find a stem, the following chooses which problem to issue:
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">unrecognised</span><span class="plain">-</span><span class="reserved">rule</span><span class="plain">-</span><span class="identifier">stem</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt; ::=</span>
<span class="identifier">when</span><span class="plain"> *** | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_BadRulePreambleWhen problem</span> <span class="cwebmacronumber">12.1</span>&gt;
<span class="plain">... ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_BadRulePreamble problem</span> <span class="cwebmacronumber">12.2</span>&gt;
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP12_1"></a><b>&#167;12.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_BadRulePreambleWhen problem</span> <span class="cwebmacronumber">12.1</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">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_BadRulePreambleWhen</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The punctuation makes me think %1 should be a definition "</span>
<span class="string">"of a phrase or a rule, but it doesn't begin as it should, "</span>
<span class="string">"with either 'To' (e.g. 'To flood the riverplain:'), 'Definition:', "</span>
<span class="string">"a name for a rule (e.g. 'This is the devilishly cunning rule:'), "</span>
<span class="string">"'At' plus a time (e.g. 'At 11:12 PM:' or 'At the time when "</span>
<span class="string">"the clock chimes:') or the name of a rulebook. %P"</span>
<span class="string">"As your rule begins with 'When', it may be worth noting that in "</span>
<span class="string">"December 2006 the syntax used by Inform for timed events changed: "</span>
<span class="string">"the old syntax 'When the sky falls in:' to create a named "</span>
<span class="string">"event, the sky falls in, became 'At the time when the sky "</span>
<span class="string">"falls in:'. This was changed to avoid confusion with rules "</span>
<span class="string">"relating to when scenes begin or end. %P"</span>
<span class="string">"Or perhaps you meant to say that something would only happen "</span>
<span class="string">"when some condition held. Inform often allows this, but the "</span>
<span class="string">"'when...' part tends to be at the end, not up front - for "</span>
<span class="string">"instance, 'Understand \"blue\" as the deep crevasse when the "</span>
<span class="string">"location is the South Pole.'"</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="#SP12">&#167;12</a>.</p>
<p class="inwebparagraph"><a id="SP12_2"></a><b>&#167;12.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_BadRulePreamble problem</span> <span class="cwebmacronumber">12.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_BadRulePreamble</span><span class="plain">),</span>
<span class="string">"the punctuation here ':' makes me think this should be a definition "</span>
<span class="string">"of a phrase and it doesn't begin as it should"</span><span class="plain">,</span>
<span class="string">"with either 'To' (e.g. 'To flood the riverplain:'), 'Definition:', "</span>
<span class="string">"a name for a rule (e.g. 'This is the devilishly cunning rule:'), "</span>
<span class="string">"'At' plus a time (e.g. 'At 11:12 PM:' or 'At the time when "</span>
<span class="string">"the clock chimes') or the name of a rulebook, possibly followed "</span>
<span class="string">"by some description of the action or value to apply to (e.g. "</span>
<span class="string">"'Instead of taking something:' or 'Every turn:')."</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP12">&#167;12</a>.</p>
<p class="inwebparagraph"><a id="SP11_3_1_2"></a><b>&#167;11.3.1.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Disallow the definite article for anonymous rules</span> <span class="cwebmacronumber">11.3.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">parsed_rm</span><span class="plain">.</span><span class="element">article_used</span><span class="plain"> == </span><span class="identifier">DEF_ART</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">parsed_rm</span><span class="plain">.</span><span class="identifier">placement_requested</span><span class="plain"> == </span><span class="constant">MIDDLE_PLACEMENT</span><span class="plain">))</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_RuleWithDefiniteArticle</span><span class="plain">),</span>
<span class="string">"a rulebook can contain any number of rules"</span><span class="plain">,</span>
<span class="string">"so (e.g.) 'the before rule: ...' is disallowed; you should "</span>
<span class="string">"write 'a before rule: ...' instead."</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP11_3_1">&#167;11.3.1</a>.</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. Extracting the stem. </b>A couple of routines to read but not really parse the stem and the bud.
</p>
<pre class="display">
<span class="identifier">wording</span><span class="plain"> </span><span class="functiontext">Phrases::Usage::get_preamble_text</span><span class="plain">(</span><span class="reserved">ph_usage_data</span><span class="plain"> *</span><span class="identifier">phud</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="identifier">phrase_effect</span><span class="plain"> == </span><span class="constant">TO_PHRASE_EFF</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_preamble</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">full_preamble</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Usage::get_preamble_text is used in 2/si (<a href="2-si.html#SP5">&#167;5</a>), 22/ph (<a href="22-ph.html#SP6_3">&#167;6.3</a>, <a href="22-ph.html#SP6_8">&#167;6.8</a>).</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. </b>For example, for the rule
</p>
<blockquote>
<p>Instead of taking the box while the skylight is open: ...</p>
</blockquote>
<p class="inwebparagraph">this returns "taking the box".
</p>
<pre class="display">
<span class="identifier">wording</span><span class="plain"> </span><span class="functiontext">Phrases::Usage::get_prewhile_text</span><span class="plain">(</span><span class="reserved">ph_usage_data</span><span class="plain"> *</span><span class="identifier">phud</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">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</span><span class="plain">)) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">E</span><span class="plain"> = </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">when</span><span class="plain">-</span><span class="reserved">while</span><span class="plain">-</span><span class="identifier">clause</span><span class="plain">&gt;(</span><span class="identifier">E</span><span class="plain">)) </span><span class="identifier">E</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(&lt;</span><span class="identifier">when</span><span class="plain">-</span><span class="reserved">while</span><span class="plain">-</span><span class="identifier">clause</span><span class="plain">&gt;, </span><span class="constant">1</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">E</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Usage::get_prewhile_text is used in 21/rb (<a href="21-rb.html#SP9">&#167;9</a>).</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. </b></p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">when</span><span class="plain">-</span><span class="reserved">while</span><span class="plain">-</span><span class="identifier">clause</span><span class="plain">&gt; ::=</span>
<span class="plain">... </span><span class="identifier">when</span><span class="plain">/</span><span class="reserved">while</span><span class="plain"> ...</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. Miscellaneous. </b>Some access routines.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Phrases::Usage::get_effect</span><span class="plain">(</span><span class="reserved">ph_usage_data</span><span class="plain"> *</span><span class="identifier">phud</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">phrase_effect</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Phrases::Usage::get_rulebook_placement</span><span class="plain">(</span><span class="reserved">ph_usage_data</span><span class="plain"> *</span><span class="identifier">phud</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">owning_rulebook_placement</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">rulebook</span><span class="plain"> *</span><span class="functiontext">Phrases::Usage::get_rulebook</span><span class="plain">(</span><span class="reserved">ph_usage_data</span><span class="plain"> *</span><span class="identifier">phud</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">owning_rulebook</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Usage::set_rulebook</span><span class="plain">(</span><span class="reserved">ph_usage_data</span><span class="plain"> *</span><span class="identifier">phud</span><span class="plain">, </span><span class="reserved">rulebook</span><span class="plain"> *</span><span class="identifier">rb</span><span class="plain">) {</span>
<span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">owning_rulebook</span><span class="plain"> = </span><span class="identifier">rb</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Phrases::Usage::get_timing_of_event</span><span class="plain">(</span><span class="reserved">ph_usage_data</span><span class="plain"> *</span><span class="identifier">phud</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">timing_of_event</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Phrases::Usage::has_name_as_constant</span><span class="plain">(</span><span class="reserved">ph_usage_data</span><span class="plain"> *</span><span class="identifier">phud</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="identifier">constant_phrase_holder</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">explicit_name_used_in_maths</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">Nouns::nominative</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">constant_phrase_holder</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">)))) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="functiontext">Phrases::Usage::get_equation_form</span><span class="plain">(</span><span class="reserved">ph_usage_data</span><span class="plain"> *</span><span class="identifier">phud</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="identifier">explicit_name_used_in_maths</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Wordings::first_word</span><span class="plain">(</span><span class="identifier">Nouns::nominative</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">constant_phrase_holder</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">));</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">phrase</span><span class="plain"> *</span><span class="functiontext">Phrases::Usage::get_equation_inverse</span><span class="plain">(</span><span class="reserved">ph_usage_data</span><span class="plain"> *</span><span class="identifier">phud</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">phud</span><span class="plain">-&gt;</span><span class="element">explicit_name_for_inverse</span><span class="plain">)) {</span>
<span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">, </span><span class="reserved">phrase</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="functiontext">Phrases::Usage::get_equation_form</span><span class="plain">(&amp;(</span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">usage_data</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">W</span><span class="plain">))</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::match</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">explicit_name_for_inverse</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ph</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Usage::get_effect is used in 21/rb (<a href="21-rb.html#SP9">&#167;9</a>), 22/cs (<a href="22-cs.html#SP10_4">&#167;10.4</a>), 22/ph (<a href="22-ph.html#SP6">&#167;6</a>, <a href="22-ph.html#SP12">&#167;12</a>), 22/pi (<a href="22-pi.html#SP1">&#167;1</a>), 25/cp (<a href="25-cp.html#SP5_3_3">&#167;5.3.3</a>).</p>
<p class="endnote">The function Phrases::Usage::get_rulebook_placement is used in 21/rb (<a href="21-rb.html#SP9">&#167;9</a>).</p>
<p class="endnote">The function Phrases::Usage::get_rulebook is used in 21/rb (<a href="21-rb.html#SP8">&#167;8</a>, <a href="21-rb.html#SP9">&#167;9</a>).</p>
<p class="endnote">The function Phrases::Usage::set_rulebook is used in 21/rb (<a href="21-rb.html#SP9">&#167;9</a>).</p>
<p class="endnote">The function Phrases::Usage::get_timing_of_event is used in 22/tp2 (<a href="22-tp2.html#SP4">&#167;4</a>, <a href="22-tp2.html#SP5">&#167;5</a>, <a href="22-tp2.html#SP6">&#167;6</a>, <a href="22-tp2.html#SP7_1">&#167;7.1</a>, <a href="22-tp2.html#SP7_2">&#167;7.2</a>).</p>
<p class="endnote">The function Phrases::Usage::has_name_as_constant is used in 22/cs (<a href="22-cs.html#SP10_7">&#167;10.7</a>).</p>
<p class="endnote">The function Phrases::Usage::get_equation_form is used in 20/eq (<a href="20-eq.html#SP21">&#167;21</a>), 22/dptd (<a href="22-dptd.html#SP5">&#167;5</a>, <a href="22-dptd.html#SP6_3">&#167;6.3</a>).</p>
<p class="endnote">The function Phrases::Usage::get_equation_inverse is used in 20/eq (<a href="20-eq.html#SP50_3_2">&#167;50.3.2</a>).</p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. Logging and indexing. </b>The length and thoroughness of this may give some hint of how troublesome
it was to debug the preamble-parsing code:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Usage::log</span><span class="plain">(</span><span class="reserved">ph_usage_data</span><span class="plain"> *</span><span class="identifier">phud</span><span class="plain">) {</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">ram</span><span class="plain"> = </span><span class="string">"&lt;UNKNOWN_NT&gt;"</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">phrase_effect</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">AS_YET_UNKNOWN_EFF:</span><span class="plain"> </span><span class="identifier">ram</span><span class="plain"> = </span><span class="string">"AS_YET_UNKNOWN_EFF"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">DEFINITIONAL_PHRASE_EFF:</span><span class="plain"> </span><span class="identifier">ram</span><span class="plain"> = </span><span class="string">"DEFINITIONAL_PHRASE_EFF"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">RULE_NOT_IN_RULEBOOK_EFF:</span><span class="plain"> </span><span class="identifier">ram</span><span class="plain"> = </span><span class="string">"RULE_NOT_IN_RULEBOOK_EFF"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">TO_PHRASE_EFF:</span><span class="plain"> </span><span class="identifier">ram</span><span class="plain"> = </span><span class="string">"TO_PHRASE_EFF"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">RULE_IN_RULEBOOK_EFF:</span><span class="plain"> </span><span class="identifier">ram</span><span class="plain"> = </span><span class="string">"RULE_IN_RULEBOOK_EFF"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"PHUD: &lt;%W&gt;: rule attachment mode %s\n"</span><span class="plain">, </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">full_preamble</span><span class="plain">, </span><span class="identifier">ram</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="identifier">constant_phrase_holder</span><span class="plain">)</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">" Constant name: &lt;%W&gt;\n"</span><span class="plain">, </span><span class="identifier">Nouns::nominative</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">constant_phrase_holder</span><span class="plain">-&gt;</span><span class="element">name</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">phud</span><span class="plain">-&gt;</span><span class="element">explicit_name</span><span class="plain">))</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">" Explicit name: &lt;%W&gt;\n"</span><span class="plain">, </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">explicit_name</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="identifier">explicit_name_used_in_maths</span><span class="plain">)</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">" Used functionally in equations\n"</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">phud</span><span class="plain">-&gt;</span><span class="element">rule_preamble</span><span class="plain">))</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">" Rule preamble: &lt;%W&gt;\n"</span><span class="plain">, </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_preamble</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">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</span><span class="plain">))</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">" Rule parameter: &lt;%W&gt;\n"</span><span class="plain">, </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</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">phud</span><span class="plain">-&gt;</span><span class="element">whenwhile</span><span class="plain">))</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">" When/while text: &lt;%W&gt;\n"</span><span class="plain">, </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">whenwhile</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">phud</span><span class="plain">-&gt;</span><span class="element">event_name</span><span class="plain">))</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">" Event name: &lt;%W&gt;\n"</span><span class="plain">, </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">event_name</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="identifier">timing_of_event</span><span class="plain"> != </span><span class="constant">NOT_A_TIMED_EVENT</span><span class="plain">)</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">" Timed event: at %d\n"</span><span class="plain">, </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">timing_of_event</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">phud</span><span class="plain">-&gt;</span><span class="identifier">during_scene_spec</span><span class="plain">)</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">" During scene: &lt;$P&gt;\n"</span><span class="plain">, </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">during_scene_spec</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">phud</span><span class="plain">-&gt;</span><span class="identifier">owning_rulebook</span><span class="plain">) {</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">place</span><span class="plain"> = </span><span class="string">"&lt;UNKNOWN_NT&gt;"</span><span class="plain">;</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">" Owned by rulebook: "</span><span class="plain">);</span>
<span class="functiontext">Rulebooks::log_name_only</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">owning_rulebook</span><span class="plain">);</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">owning_rulebook_placement</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">MIDDLE_PLACEMENT:</span><span class="plain"> </span><span class="identifier">place</span><span class="plain"> = </span><span class="string">"MIDDLE_PLACEMENT"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">FIRST_PLACEMENT:</span><span class="plain"> </span><span class="identifier">place</span><span class="plain"> = </span><span class="string">"FIRST_PLACEMENT"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LAST_PLACEMENT:</span><span class="plain"> </span><span class="identifier">place</span><span class="plain"> = </span><span class="string">"LAST_PLACEMENT"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"\n Placement: %s\n"</span><span class="plain">, </span><span class="identifier">place</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Usage::log_rule_name</span><span class="plain">(</span><span class="reserved">ph_usage_data</span><span class="plain"> *</span><span class="identifier">phud</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::empty</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">explicit_name</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">phud</span><span class="plain">-&gt;</span><span class="element">full_preamble</span><span class="plain">))</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"\"%W\""</span><span class="plain">, </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">full_preamble</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"(nameless)"</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"(%W)"</span><span class="plain">, </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">explicit_name</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Usage::log is used in <a href="#SP21_1_1_1">&#167;21.1.1.1</a>, <a href="#SP21_1_1_2">&#167;21.1.1.2</a>, 1/cm (<a href="1-cm.html#SP5">&#167;5</a>, <a href="1-cm.html#SP6_6">&#167;6.6</a>), 21/rb (<a href="21-rb.html#SP9">&#167;9</a>).</p>
<p class="endnote">The function Phrases::Usage::log_rule_name is used in 22/ph (<a href="22-ph.html#SP9">&#167;9</a>).</p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. </b>In our compiled code, it's useful to label routines with I6 comments:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Usage::write_I6_comment_describing</span><span class="plain">(</span><span class="reserved">ph_usage_data</span><span class="plain"> *</span><span class="identifier">phud</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="string">"%~W:"</span><span class="plain">, </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">full_preamble</span><span class="plain">);</span>
<span class="identifier">Produce::comment</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Usage::write_I6_comment_describing is used in 21/rl (<a href="21-rl.html#SP21">&#167;21</a>), 25/cp (<a href="25-cp.html#SP3_1">&#167;3.1</a>).</p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. </b>And similarly:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Usage::index_preamble</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">ph_usage_data</span><span class="plain"> *</span><span class="identifier">phud</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">full_preamble</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Usage::index_preamble is used in 22/tp2 (<a href="22-tp2.html#SP7_1">&#167;7.1</a>, <a href="22-tp2.html#SP7_2">&#167;7.2</a>).</p>
<p class="inwebparagraph"><a id="SP20"></a><b>&#167;20. How the PHUD translates into a PHRCD. </b>Recall that in the early afternoon, the PHUD for a rule phrase is translated
into a PHRCD, that is, a set of instructions about the circumstances for
the rule to fire.
</p>
<p class="inwebparagraph">As will be seen, about six-sevenths of the code is given over to choosing good
problem messages when the PHUD is malformed &mdash; these are some of the most
seen problems in Inform. A couple of variables are needed just for that:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">NAP_problem_explained</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span><span class="comment">pertains to Named Action Patterns</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">issuing_ANL_problem</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span><span class="comment">pertains to Action Name Lists</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP21"></a><b>&#167;21. </b></p>
<pre class="display">
<span class="reserved">ph_runtime_context_data</span><span class="plain"> </span><span class="functiontext">Phrases::Usage::to_runtime_context_data</span><span class="plain">(</span><span class="reserved">ph_usage_data</span><span class="plain"> *</span><span class="identifier">phud</span><span class="plain">) {</span>
<span class="reserved">ph_runtime_context_data</span><span class="plain"> </span><span class="identifier">phrcd</span><span class="plain"> = </span><span class="functiontext">Phrases::Context::new</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="identifier">phrase_effect</span><span class="plain"> == </span><span class="constant">RULE_NOT_IN_RULEBOOK_EFF</span><span class="plain">)</span>
<span class="identifier">phrcd</span><span class="plain">.</span><span class="element">permit_all_outcomes</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="identifier">phrase_effect</span><span class="plain"> == </span><span class="constant">RULE_IN_RULEBOOK_EFF</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Finish work parsing the conditions for the rule to fire</span> <span class="cwebmacronumber">21.1</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">phrcd</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Phrases::Usage::to_runtime_context_data is used in 22/cs (<a href="22-cs.html#SP7">&#167;7</a>).</p>
<p class="inwebparagraph"><a id="SP21_1"></a><b>&#167;21.1. </b>All of this is just dumb copying...
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Finish work parsing the conditions for the rule to fire</span> <span class="cwebmacronumber">21.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">phrcd</span><span class="plain">.</span><span class="element">compile_for_rulebook</span><span class="plain"> = &amp;(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">owning_rulebook</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">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</span><span class="plain">)) </span>&lt;<span class="cwebmacro">Parse what used to be the bud into the PHRCD</span> <span class="cwebmacronumber">21.1.1</span>&gt;<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">phud</span><span class="plain">-&gt;</span><span class="element">whenwhile</span><span class="plain">)) {</span>
<span class="identifier">phrcd</span><span class="plain">.</span><span class="element">activity_context</span><span class="plain"> =</span>
<span class="identifier">Wordings::new</span><span class="plain">(</span>
<span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">whenwhile</span><span class="plain">) + </span><span class="constant">1</span><span class="plain">,</span>
<span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">whenwhile</span><span class="plain">));</span>
<span class="identifier">phrcd</span><span class="plain">.</span><span class="element">activity_where</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</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">phud</span><span class="plain">-&gt;</span><span class="identifier">during_scene_spec</span><span class="plain">) </span><span class="identifier">phrcd</span><span class="plain">.</span><span class="element">during_scene</span><span class="plain"> = </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">during_scene_spec</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP21">&#167;21</a>.</p>
<p class="inwebparagraph"><a id="SP21_1_1"></a><b>&#167;21.1.1. </b>...except for this:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Parse what used to be the bud into the PHRCD</span> <span class="cwebmacronumber">21.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<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="functiontext">Rulebooks::focus</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">owning_rulebook</span><span class="plain">) == </span><span class="constant">ACTION_FOCUS</span><span class="plain">) {</span>
<span class="identifier">permit_trying_omission</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="functiontext">Frames::set_stvol</span><span class="plain">(</span>
<span class="functiontext">Frames::current_stack_frame</span><span class="plain">(), </span><span class="identifier">all_action_processing_vars</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">action</span><span class="plain">-</span><span class="identifier">pattern</span><span class="plain">&gt;(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</span><span class="plain">)) </span><span class="identifier">phrcd</span><span class="plain">.</span><span class="element">ap</span><span class="plain"> = *((</span><span class="identifier">action_pattern</span><span class="plain"> *) &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;);</span>
<span class="functiontext">Frames::remove_nonphrase_stack_frame</span><span class="plain">();</span>
<span class="identifier">permit_trying_omission</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">PL::Actions::Patterns::is_valid</span><span class="plain">(&amp;(</span><span class="identifier">phrcd</span><span class="plain">.</span><span class="element">ap</span><span class="plain">)) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Issue a problem message for a bad action</span> <span class="cwebmacronumber">21.1.1.1</span>&gt;<span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">pk</span><span class="plain"> = </span><span class="functiontext">Rulebooks::get_parameter_kind</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">owning_rulebook</span><span class="plain">);</span>
<span class="identifier">phrcd</span><span class="plain">.</span><span class="element">ap</span><span class="plain"> = </span><span class="identifier">PL::Actions::Patterns::parse_parametric</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</span><span class="plain">, </span><span class="identifier">pk</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PL::Actions::Patterns::is_valid</span><span class="plain">(&amp;(</span><span class="identifier">phrcd</span><span class="plain">.</span><span class="element">ap</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::nonempty</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">whenwhile</span><span class="plain">)) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">F</span><span class="plain"> = </span><span class="identifier">Wordings::up_to</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</span><span class="plain">, </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">whenwhile</span><span class="plain">));</span>
<span class="identifier">phrcd</span><span class="plain">.</span><span class="element">ap</span><span class="plain"> = </span><span class="identifier">PL::Actions::Patterns::parse_parametric</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">pk</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PL::Actions::Patterns::is_valid</span><span class="plain">(&amp;(</span><span class="identifier">phrcd</span><span class="plain">.</span><span class="element">ap</span><span class="plain">)) == </span><span class="identifier">TRUE</span><span class="plain">) {</span>
<span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</span><span class="plain"> = </span><span class="identifier">F</span><span class="plain">;</span>
<span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">whenwhile</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PL::Actions::Patterns::is_valid</span><span class="plain">(&amp;(</span><span class="identifier">phrcd</span><span class="plain">.</span><span class="element">ap</span><span class="plain">)) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Issue a problem message for a bad parameter</span> <span class="cwebmacronumber">21.1.1.2</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">#</span><span class="identifier">ifndef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">pk</span><span class="plain"> = </span><span class="functiontext">Rulebooks::get_parameter_kind</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">owning_rulebook</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Issue a problem message for a bad parameter</span> <span class="cwebmacronumber">21.1.1.2</span>&gt;<span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP21_1">&#167;21.1</a>.</p>
<p class="inwebparagraph"><a id="SP21_1_1_1"></a><b>&#167;21.1.1.1. </b>All that's left is to issue a "good" problem message, but this is quite
a large undertaking, because the situation as we currently know it is just
that something's wrong with the rule preamble &mdash; which covers an enormous
range of different faults.
</p>
<p class="inwebparagraph">The "PAP failure reason" is a sort of error code set by the action pattern
parser, recording how it most recently failed.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for a bad action</span> <span class="cwebmacronumber">21.1.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Phrases::Usage::log</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">);</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Bad action pattern: %W = $A\nPAP failure reason: %d\n"</span><span class="plain">,</span>
<span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</span><span class="plain">, &amp;(</span><span class="identifier">phrcd</span><span class="plain">.</span><span class="element">ap</span><span class="plain">), </span><span class="identifier">pap_failure_reason</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">phud</span><span class="plain">-&gt;</span><span class="identifier">rule_parameter</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">action</span><span class="plain">-</span><span class="identifier">problem</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt;(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">pap_failure_reason</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">MIXEDNOUNS_PAPF:</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue PM_APWithDisjunction problem</span> <span class="cwebmacronumber">21.1.1.1.1</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NOPARTICIPLE_PAPF:</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue PM_APWithNoParticiple problem</span> <span class="cwebmacronumber">21.1.1.1.2</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">IMMISCIBLE_PAPF:</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue PM_APWithImmiscible problem</span> <span class="cwebmacronumber">21.1.1.1.3</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">WHEN_PAPF:</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue PM_APWithBadWhen problem</span> <span class="cwebmacronumber">21.1.1.1.4</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="identifier">default:</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue PM_APUnknown problem</span> <span class="cwebmacronumber">21.1.1.1.5</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP21_1_1">&#167;21.1.1</a>.</p>
<p class="inwebparagraph"><a id="SP21_1_1_1_1"></a><b>&#167;21.1.1.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_APWithDisjunction problem</span> <span class="cwebmacronumber">21.1.1.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_APWithDisjunction</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, which seems to introduce a rule, but the "</span>
<span class="string">"circumstances ('%2') seem to be too general for me to "</span>
<span class="string">"understand in a single rule. I can understand a choice of "</span>
<span class="string">"of actions, in a list such as 'taking or dropping the ball', "</span>
<span class="string">"but there can only be one set of noun(s) supplied. So 'taking "</span>
<span class="string">"the ball or taking the bat' is disallowed. You can get around "</span>
<span class="string">"this by using named actions ('Taking the ball is being "</span>
<span class="string">"mischievous. Taking the bat is being mischievous. Instead of "</span>
<span class="string">"being mischievous...'), or it may be less bother just to "</span>
<span class="string">"write more than one rule."</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="#SP21_1_1_1">&#167;21.1.1.1</a>.</p>
<p class="inwebparagraph"><a id="SP21_1_1_1_2"></a><b>&#167;21.1.1.1.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_APWithNoParticiple problem</span> <span class="cwebmacronumber">21.1.1.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_APWithNoParticiple</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, which seems to introduce a rule taking effect "</span>
<span class="string">"only '%2'. But this does not look like an action, since "</span>
<span class="string">"there is no sign of a participle ending '-ing' (as in "</span>
<span class="string">"'taking the brick', say) - which makes me think I have "</span>
<span class="string">"badly misunderstood what you intended."</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="#SP21_1_1_1">&#167;21.1.1.1</a>.</p>
<p class="inwebparagraph"><a id="SP21_1_1_1_3"></a><b>&#167;21.1.1.1.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_APWithImmiscible problem</span> <span class="cwebmacronumber">21.1.1.1.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_APWithImmiscible</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, which seems to introduce a rule taking effect "</span>
<span class="string">"only '%2'. But this is a combination of actions which cannot "</span>
<span class="string">"be mixed. The only alternatives where 'or' is allowed are "</span>
<span class="string">"cases where a choice of actions is given but applying to "</span>
<span class="string">"the same objects in each case. (So 'taking or dropping the "</span>
<span class="string">"CD' is allowed, but 'dropping the CD or inserting the CD "</span>
<span class="string">"into the jewel box' is not, because the alternatives there "</span>
<span class="string">"would make different use of objects from each other.)"</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="#SP21_1_1_1">&#167;21.1.1.1</a>.</p>
<p class="inwebparagraph"><a id="SP21_1_1_1_4"></a><b>&#167;21.1.1.1.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_APWithBadWhen problem</span> <span class="cwebmacronumber">21.1.1.1.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_APWithBadWhen</span><span class="plain">));</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">Q</span><span class="plain"> = </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">diagnosis</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">action</span><span class="plain">-</span><span class="identifier">when</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt;(</span><span class="identifier">Q</span><span class="plain">)) {</span>
<span class="identifier">Q</span><span class="plain"> = </span><span class="identifier">Wordings::new</span><span class="plain">(&lt;&lt;</span><span class="identifier">cw1</span><span class="plain">&gt;&gt;, &lt;&lt;</span><span class="identifier">cw2</span><span class="plain">&gt;&gt;);</span>
<span class="identifier">diagnosis</span><span class="plain"> = &lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt;;</span>
<span class="plain">}</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">Q</span><span class="plain">);</span>
<span class="identifier">Problems::quote_text</span><span class="plain">(3, </span><span class="string">"so I am unable to accept this rule."</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">diagnosis</span><span class="plain"> == </span><span class="constant">2</span><span class="plain">) {</span>
<span class="identifier">Problems::quote_text</span><span class="plain">(3,</span>
<span class="string">"perhaps because 'nothing' tends not to be allowed in Inform conditions? "</span>
<span class="string">"(Whereas 'no thing' is usually allowed.)"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">diagnosis</span><span class="plain"> == </span><span class="constant">3</span><span class="plain">) {</span>
<span class="identifier">Problems::quote_text</span><span class="plain">(3,</span>
<span class="string">"perhaps because 'nowhere' tends not to be allowed in Inform conditions? "</span>
<span class="string">"(Whereas 'no room' is usually allowed.)"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, which seems to introduce a rule taking effect "</span>
<span class="string">"only '%2'. But this condition did not make sense, %3"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">diagnosis</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">)</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"%PIt might be worth mentioning that a 'when' condition tacked on to "</span>
<span class="string">"an action like this is not allowed to mention or use 'called' values."</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">diagnosis</span><span class="plain"> == </span><span class="constant">4</span><span class="plain">)</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"%PThe problem might be that 'and' has been followed by 'when' or "</span>
<span class="string">"'while'. For example, to make a rule with two conditions, this is "</span>
<span class="string">"okay: 'Instead of jumping when Peter is happy and Peter is in the "</span>
<span class="string">"location'; but the same thing with '...and when Peter is...' is not allowed."</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="#SP21_1_1_1">&#167;21.1.1.1</a>.</p>
<p class="inwebparagraph"><a id="SP21_1_1_1_5"></a><b>&#167;21.1.1.1.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_APUnknown problem</span> <span class="cwebmacronumber">21.1.1.1.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="identifier">rule_parameter</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pap_failure_reason</span><span class="plain"> == </span><span class="identifier">WHENOKAY_PAPF</span><span class="plain">)</span>
<span class="identifier">Problems::quote_text</span><span class="plain">(3,</span>
<span class="string">"The part after 'when' (or 'while') was fine, but the earlier words"</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Problems::quote_text</span><span class="plain">(3, </span><span class="string">"But that"</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_APUnknown</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, which seems to introduce a rule taking effect only if the "</span>
<span class="string">"action is '%2'. %3 did not make sense as a description of an action."</span><span class="plain">);</span>
&lt;<span class="cwebmacro">See if it starts with a valid action name, at least</span> <span class="cwebmacronumber">21.1.1.1.5.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">See if this might be a when-for confusion</span> <span class="cwebmacronumber">21.1.1.1.5.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Break down the action list and say which are okay</span> <span class="cwebmacronumber">21.1.1.1.5.3</span>&gt;<span class="plain">;</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">" I am unable to place this rule into any rulebook."</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="#SP21_1_1_1">&#167;21.1.1.1</a>.</p>
<p class="inwebparagraph"><a id="SP21_1_1_1_5_1"></a><b>&#167;21.1.1.1.5.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">See if it starts with a valid action name, at least</span> <span class="cwebmacronumber">21.1.1.1.5.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">action_name</span><span class="plain"> *</span><span class="identifier">an</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">an</span><span class="plain">, </span><span class="identifier">action_name</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">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</span><span class="plain">) &lt; </span><span class="identifier">Wordings::length</span><span class="plain">(</span><span class="identifier">an</span><span class="plain">-&gt;</span><span class="identifier">present_name</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Wordings::match</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</span><span class="plain">,</span>
<span class="identifier">Wordings::truncate</span><span class="plain">(</span><span class="identifier">an</span><span class="plain">-&gt;</span><span class="identifier">present_name</span><span class="plain">, </span><span class="identifier">Wordings::length</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</span><span class="plain">))))) {</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(3, </span><span class="identifier">an</span><span class="plain">-&gt;</span><span class="identifier">present_name</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">" I notice that there's an action called '%3', though: perhaps "</span>
<span class="string">"this is what you meant?"</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP21_1_1_1_5">&#167;21.1.1.1.5</a>.</p>
<p class="inwebparagraph"><a id="SP21_1_1_1_5_2"></a><b>&#167;21.1.1.1.5.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">See if this might be a when-for confusion</span> <span class="cwebmacronumber">21.1.1.1.5.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pap_failure_reason</span><span class="plain"> == </span><span class="identifier">WHENOKAY_PAPF</span><span class="plain">) {</span>
<span class="identifier">time_period</span><span class="plain"> </span><span class="identifier">duration</span><span class="plain"> = </span><span class="identifier">Occurrence::parse</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_preamble</span><span class="plain">);</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Checking %W\n"</span><span class="plain">, </span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_preamble</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Occurrence::is_valid</span><span class="plain">(&amp;</span><span class="identifier">duration</span><span class="plain">)) {</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(3,</span>
<span class="identifier">Wordings::from</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_preamble</span><span class="plain">, </span><span class="identifier">Occurrence::is_valid</span><span class="plain">(&amp;</span><span class="identifier">duration</span><span class="plain">) + </span><span class="constant">1</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">" (I wonder if this might be because '%3', which looks like a "</span>
<span class="string">"condition on the timing, is the wrong side of the 'when...' "</span>
<span class="string">"clause?)"</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="#SP21_1_1_1_5">&#167;21.1.1.1.5</a>.</p>
<p class="inwebparagraph"><a id="SP21_1_1_1_5_3"></a><b>&#167;21.1.1.1.5.3. </b>If the action pattern contains what looks like a list of action names, as
for example
</p>
<blockquote>
<p>Instead of taking or dropping the magnet: ...</p>
</blockquote>
<p class="inwebparagraph">then the anl-diagnosis grammar will parse this and return N equal to 2, the
apparent number of action names. We then run the grammar again, but this time
allowing it to print comments on each apparent action name it sees.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Break down the action list and say which are okay</span> <span class="cwebmacronumber">21.1.1.1.5.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">issuing_ANL_problem</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span><span class="identifier">NAP_problem_explained</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">&lt;</span><span class="identifier">anl</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt;(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = &lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</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">avoids</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((&lt;</span><span class="identifier">action</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">&gt;(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</span><span class="plain">)) &amp;&amp; (&lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt; == </span><span class="identifier">FALSE</span><span class="plain">)) </span><span class="identifier">avoids</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">avoids</span><span class="plain">)</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">" This looks like a list of actions to avoid: "</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">" Looking at this as a list of alternative actions: "</span><span class="plain">);</span>
<span class="identifier">issuing_ANL_problem</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="identifier">NAP_problem_explained</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">&lt;</span><span class="identifier">anl</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt;(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_parameter</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">" so"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP21_1_1_1_5">&#167;21.1.1.1.5</a>.</p>
<p class="inwebparagraph"><a id="SP21_1_1_2"></a><b>&#167;21.1.1.2. </b>We have a much easier time if the rulebook was value-focused, so that
the only possible problem is that the value was wrong.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for a bad parameter</span> <span class="cwebmacronumber">21.1.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Phrases::Usage::log</span><span class="plain">(</span><span class="identifier">phud</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">phud</span><span class="plain">-&gt;</span><span class="identifier">rule_parameter</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(3, </span><span class="identifier">pk</span><span class="plain">);</span>
<span class="plain">&lt;</span><span class="identifier">parametric</span><span class="plain">-</span><span class="identifier">problem</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt;(</span><span class="identifier">phud</span><span class="plain">-&gt;</span><span class="element">rule_preamble</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP21_1_1">&#167;21.1.1</a> (twice).</p>
<p class="inwebparagraph"><a id="SP22"></a><b>&#167;22. </b>And that is the end of the code as such, but we still have to define the
three diagnosis grammars we needed.
</p>
<p class="inwebparagraph"><a id="SP23"></a><b>&#167;23. </b>Parametric rules are those applying to values not actions, and the following
is used to choose a problem message if the value makes no sense.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">parametric</span><span class="plain">-</span><span class="identifier">problem</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt; ::=</span>
<span class="identifier">when</span><span class="plain"> </span><span class="identifier">the</span><span class="plain"> </span><span class="identifier">play</span><span class="plain"> </span><span class="identifier">begins</span><span class="plain">/</span><span class="identifier">ends</span><span class="plain"> | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_WhenThePlay problem</span> <span class="cwebmacronumber">23.1</span>&gt;
<span class="plain">... ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_BadParameter problem</span> <span class="cwebmacronumber">23.2</span>&gt;
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP23_1"></a><b>&#167;23.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_WhenThePlay problem</span> <span class="cwebmacronumber">23.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_WhenThePlay</span><span class="plain">),</span>
<span class="string">"there's no scene called 'the play'"</span><span class="plain">,</span>
<span class="string">"so I think you need to remove 'the' - Inform has two "</span>
<span class="string">"special rulebooks, 'When play begins' and 'When play ends', "</span>
<span class="string">"and I think you probably mean to refer to one of those."</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP23">&#167;23</a>.</p>
<p class="inwebparagraph"><a id="SP23_2"></a><b>&#167;23.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_BadParameter problem</span> <span class="cwebmacronumber">23.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_BadParameter</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but the description of the thing(s) to which the rule "</span>
<span class="string">"applies ('%2') did not make sense. This is %3 based rulebook, so "</span>
<span class="string">"that should have described %3."</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="#SP23">&#167;23</a>.</p>
<p class="inwebparagraph"><a id="SP24"></a><b>&#167;24. </b>And here we choose a problem message if a rule applying to an action is used,
but the action isn't one we recognise.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">action</span><span class="plain">-</span><span class="identifier">problem</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt; ::=</span>
<span class="identifier">in</span><span class="plain"> </span><span class="identifier">the</span><span class="plain"> </span><span class="identifier">presence</span><span class="plain"> </span><span class="identifier">of</span><span class="plain"> ... | ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_NonActionInPresenceOf problem</span> <span class="cwebmacronumber">24.1</span>&gt;
<span class="identifier">in</span><span class="plain"> ... ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_NonActionIn problem</span> <span class="cwebmacronumber">24.2</span>&gt;
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP24_1"></a><b>&#167;24.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_NonActionInPresenceOf problem</span> <span class="cwebmacronumber">24.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_NonActionInPresenceOf</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but 'in the presence of...' is a clause which can "</span>
<span class="string">"only be used to talk about an action: so, for instance, 'waiting "</span>
<span class="string">"in the presence of...' is needed. "</span>
<span class="string">"This problem arises especially with 'every turn' rules, where "</span>
<span class="string">"'every turn in the presence of...' looks plausible but doesn't "</span>
<span class="string">"work. This could be fixed by writing 'Every turn doing something "</span>
<span class="string">"in the presence of...', but a neater solution talks about the "</span>
<span class="string">"current situation instead: 'Every turn when the player can "</span>
<span class="string">"see...'."</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="#SP24">&#167;24</a>.</p>
<p class="inwebparagraph"><a id="SP24_2"></a><b>&#167;24.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_NonActionIn problem</span> <span class="cwebmacronumber">24.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_NonActionIn</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but 'in...' used in this way should really belong "</span>
<span class="string">"to an action: for instance, 'Before waiting in the Library'. "</span>
<span class="string">"Rules like 'Every turn in the Library' don't work, because "</span>
<span class="string">"'every turn' is not an action; what's wanted is 'Every turn "</span>
<span class="string">"when in the Library'."</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="#SP24">&#167;24</a>.</p>
<p class="inwebparagraph"><a id="SP25"></a><b>&#167;25. </b>The following is used to choose a problem when the trouble with the rule
occurred in a when/while condition at the end; while all five cases produce
the PM_APWithBadWhen problem, they each provide different clues as to what
might have gone wrong.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">action</span><span class="plain">-</span><span class="identifier">when</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt; ::=</span>
<span class="plain">... </span><span class="identifier">called</span><span class="plain"> ... {</span><span class="identifier">when</span><span class="plain">/</span><span class="reserved">while</span><span class="plain"> ...} | ==&gt; </span><span class="constant">1</span><span class="plain">; &lt;&lt;</span><span class="identifier">cw1</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[3]); &lt;&lt;</span><span class="identifier">cw2</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[3])</span>
<span class="plain">... {</span><span class="identifier">when</span><span class="plain">/</span><span class="reserved">while</span><span class="plain"> *** </span><span class="identifier">nothing</span><span class="plain"> ***} | ==&gt; </span><span class="constant">2</span><span class="plain">; &lt;&lt;</span><span class="identifier">cw1</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[2]); &lt;&lt;</span><span class="identifier">cw2</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[2])</span>
<span class="plain">... {</span><span class="identifier">when</span><span class="plain">/</span><span class="reserved">while</span><span class="plain"> *** </span><span class="identifier">nowhere</span><span class="plain"> ***} | ==&gt; </span><span class="constant">3</span><span class="plain">; &lt;&lt;</span><span class="identifier">cw1</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[2]); &lt;&lt;</span><span class="identifier">cw2</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[2])</span>
<span class="plain">... </span><span class="identifier">and</span><span class="plain"> {</span><span class="identifier">when</span><span class="plain">/</span><span class="reserved">while</span><span class="plain"> ...} | ==&gt; </span><span class="constant">4</span><span class="plain">; &lt;&lt;</span><span class="identifier">cw1</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[2]); &lt;&lt;</span><span class="identifier">cw2</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[2])</span>
<span class="plain">... {</span><span class="identifier">when</span><span class="plain">/</span><span class="reserved">while</span><span class="plain"> ...} ==&gt; </span><span class="constant">5</span><span class="plain">; &lt;&lt;</span><span class="identifier">cw1</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[2]); &lt;&lt;</span><span class="identifier">cw2</span><span class="plain">&gt;&gt; = </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">WR</span><span class="plain">[2])</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP26"></a><b>&#167;26. </b></p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">anl</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">anl</span><span class="plain">-</span><span class="identifier">inner</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt; </span><span class="identifier">when</span><span class="plain">/</span><span class="reserved">while</span><span class="plain"> ... | ==&gt; </span><span class="identifier">R</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">anl</span><span class="plain">-</span><span class="identifier">inner</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt; ==&gt; </span><span class="identifier">R</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">anl</span><span class="plain">-</span><span class="identifier">inner</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">anl</span><span class="plain">-</span><span class="identifier">entry</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt; &lt;</span><span class="identifier">anl</span><span class="plain">-</span><span class="identifier">tail</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">R</span><span class="plain">[1]+</span><span class="identifier">R</span><span class="plain">[2]</span>
<span class="plain">&lt;</span><span class="identifier">anl</span><span class="plain">-</span><span class="identifier">entry</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt; ==&gt; </span><span class="identifier">R</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">anl</span><span class="plain">-</span><span class="identifier">tail</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt; ::=</span>
<span class="plain">, </span><span class="identifier">_or</span><span class="plain"> &lt;</span><span class="identifier">anl</span><span class="plain">-</span><span class="identifier">inner</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">R</span><span class="plain">[1]</span>
<span class="identifier">_</span><span class="plain">,/</span><span class="identifier">or</span><span class="plain"> &lt;</span><span class="identifier">anl</span><span class="plain">-</span><span class="identifier">inner</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt; ==&gt; </span><span class="identifier">R</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">anl</span><span class="plain">-</span><span class="identifier">entry</span><span class="plain">-</span><span class="identifier">diagnosis</span><span class="plain">&gt; ::=</span>
<span class="plain">...... ==&gt; </span>&lt;<span class="cwebmacro">Diagnose problem with this ANL entry</span> <span class="cwebmacronumber">26.1</span>&gt;
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP26_1"></a><b>&#167;26.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Diagnose problem with this ANL entry</span> <span class="cwebmacronumber">26.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">issuing_ANL_problem</span><span class="plain">) &amp;&amp; (!</span><span class="identifier">preform_lookahead_mode</span><span class="plain">)) {</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(4, </span><span class="identifier">W</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"> (&lt;</span><span class="identifier">action</span><span class="plain">-</span><span class="identifier">pattern</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"'%4' did not make sense; "</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">action_pattern</span><span class="plain"> *</span><span class="identifier">ap</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">form</span><span class="plain"> = &lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PL::Actions::Patterns::is_request</span><span class="plain">(</span><span class="identifier">ap</span><span class="plain">)) {</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"'%4' would make sense as an action on its own, but 'or' can't "</span>
<span class="string">"be used in combination with 'asking... to try...' actions; "</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PL::Actions::Patterns::refers_to_past</span><span class="plain">(</span><span class="identifier">ap</span><span class="plain">)) {</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"'%4' would make sense as an action on its own, but 'or' can't "</span>
<span class="string">"be used in combination with actions with time periods attached; "</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">named</span><span class="plain">-</span><span class="identifier">action</span><span class="plain">-</span><span class="identifier">pattern</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">NAP_problem_explained</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"'%4' only made sense as a named kind of action, which can "</span>
<span class="string">"be used on its own but not in an action list; "</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">"'%4' is another named kind of action; "</span><span class="plain">);</span>
<span class="identifier">NAP_problem_explained</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">form</span><span class="plain"> == </span><span class="identifier">ACTOR_EXPLICITLY_PLAYER</span><span class="plain">) {</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"'%4' would have been okay except for using the word 'trying', "</span>
<span class="string">"which isn't allowed in a list like this; "</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"'%4' was okay; "</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP26">&#167;26</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="22-ph.html">Back to 'Phrases'</a></li><li><a href="22-prcd.html">Continue with 'Phrase Runtime Context Data'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>