1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 16:44:21 +03:00
inform7/docs/core-module/21-rb.html
2019-09-01 11:50:12 +01:00

1399 lines
176 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>21/rl</title>
<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>
<!--Weave of '21/rb' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">core</a></li><li><a href="index.html#21">Chapter 21: Rules and Rulebooks</a></li><li><b>Rule Bookings</b></li></ul><p class="purpose">Bookings are assignments of rules to rulebooks. We can think of them as being looseleaf pages, of which we have an unlimited supply: any rule can be written on them, and they can be bound into any rulebook at any specified position.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li><li><a href="#SP4">&#167;4. Creation</a></li><li><a href="#SP7">&#167;7. Automatic placement into rulebooks</a></li><li><a href="#SP10">&#167;10. Specificity of bookings</a></li><li><a href="#SP11">&#167;11. Lists of bookings</a></li><li><a href="#SP16">&#167;16. Logging lists</a></li><li><a href="#SP17">&#167;17. Scanning lists for their contents</a></li><li><a href="#SP18">&#167;18. Indexing of lists</a></li><li><a href="#SP21">&#167;21. Calculating the specificities</a></li><li><a href="#SP22">&#167;22. Compilation of rule definitions for rulebook</a></li><li><a href="#SP23">&#167;23. Compilation of I6-format rulebook</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>Bookings are simple structures. They record which rule is to appear, and
whether it's to appear at the front, middle, or back of the rulebook:
</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">booking</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">next_rule</span><span class="plain">; </span> <span class="comment">in the linked list of pages for the rulebook</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">rule_being_booked</span><span class="plain">; </span> <span class="comment">what appears on this page</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">placement</span><span class="plain">; </span> <span class="comment">one of three placement values: see below</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">automatic_placement</span><span class="plain">; </span> <span class="comment">should this be inserted automatically?</span>
<span class="comment">used only to show how the page was added to its rulebook, for the index:</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">next_rule_specificity</span><span class="plain">; </span> <span class="comment">1 more specific than following, 0 equal, -1 less</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">next_rule_specificity_law</span><span class="plain">; </span> <span class="comment">description of reason</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">next_rule_specificity_lawname</span><span class="plain">; </span> <span class="comment">name of Law used to sort</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">booking</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure booking is private to this section.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>When bookings are gathered into linked lists, they are positioned using
"placements". Ordinarily they go somewhere in the middle, but
declarations are allowed to specify that they must occur at the front or
back, e.g.:
</p>
<blockquote>
<p>The first reaching inside rule: ...</p>
</blockquote>
<p class="inwebparagraph">The <code class="display"><span class="extract">placement</span></code> field is therefore always one of the following three values:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">MIDDLE_PLACEMENT</span><span class="plain"> 0 </span> <span class="comment">most rules are somewhere in the middle</span>
<span class="definitionkeyword">define</span> <span class="constant">FIRST_PLACEMENT</span><span class="plain"> 1</span>
<span class="definitionkeyword">define</span> <span class="constant">LAST_PLACEMENT</span><span class="plain"> 2</span>
</pre>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Creation. </b></p>
<pre class="display">
<span class="reserved">booking</span><span class="plain"> *</span><span class="functiontext">Rules::Bookings::new</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">) {</span>
<span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">booking</span><span class="plain">);</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;rule_being_booked</span><span class="plain"> = </span><span class="identifier">R</span><span class="plain">;</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain"> = </span><span class="constant">MIDDLE_PLACEMENT</span><span class="plain">;</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;automatic_placement</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity</span><span class="plain"> = 0;</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity_law</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity_lawname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">br</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::Bookings::new is used in <a href="#SP12">&#167;12</a>, 21/rl (<a href="21-rl.html#SP17">&#167;17</a>), 21/rps (<a href="21-rps.html#SP18">&#167;18</a>).</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>Here's a rather arcane notation used in the debugging log:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::log</span><span class="plain">(</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">br</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">br</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) { </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"BR:&lt;null-booked-rule&gt;"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"BR%d"</span><span class="plain">, </span><span class="identifier">br</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">);</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">MIDDLE_PLACEMENT</span><span class="plain">: </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"m"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">FIRST_PLACEMENT</span><span class="plain">: </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"f"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">LAST_PLACEMENT</span><span class="plain">: </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"l"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">: </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"?"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="functiontext">Rules::log</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;rule_being_booked</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::Bookings::log is used in 1/cm (<a href="1-cm.html#SP5">&#167;5</a>, <a href="1-cm.html#SP6_6">&#167;6.6</a>).</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>And this is the only externally useful information in a booking:
</p>
<pre class="display">
<span class="reserved">rule</span><span class="plain"> *</span><span class="functiontext">Rules::Bookings::get_rule</span><span class="plain">(</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">br</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">br</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;rule_being_booked</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::Bookings::get_rule is used in <a href="#SP9">&#167;9</a>, <a href="#SP14_2">&#167;14.2</a>, <a href="#SP14_3">&#167;14.3</a>, <a href="#SP14_6_1">&#167;14.6.1</a>, <a href="#SP15">&#167;15</a>, <a href="#SP17">&#167;17</a>, 21/rl2 (<a href="21-rl2.html#SP19">&#167;19</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Automatic placement into rulebooks. </b>Some bookings result from explicit sentences like:
</p>
<blockquote>
<p>The can't reach inside closed containers rule is listed in the reaching inside rules.</p>
</blockquote>
<p class="inwebparagraph">But others have their placements made implicitly in their definitions:
</p>
<blockquote>
<p>Before eating something: ...</p>
</blockquote>
<p class="inwebparagraph">(which creates a nameless rule and implicitly places it in the "before"
rulebook). When Inform reads such a rule, it creates a booking, but does
not immediately insert it into a rulebook: instead it marks the booking
for "automatic placement" later on.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::request_automatic_placement</span><span class="plain">(</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">br</span><span class="plain">) {</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;automatic_placement</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 Rules::Bookings::request_automatic_placement is used in 21/rl (<a href="21-rl.html#SP17">&#167;17</a>).</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>Automatic placement occurs in declaration order. This is important, because
it ensures that it is declaration order which the rule-sorting code falls back
on when it can see no other justification for placing one rule either side
of another.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::make_automatic_placements</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">br</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">, </span><span class="reserved">booking</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;automatic_placement</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">Rules::get_I7_definition</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;rule_being_booked</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="identifier">ph</span><span class="plain">-</span><span class="element">&gt;declaration_node</span><span class="plain">;</span>
<span class="functiontext">Rules::Bookings::place</span><span class="plain">(&amp;(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">&gt;usage_data</span><span class="plain">), </span><span class="identifier">br</span><span class="plain">);</span>
<span class="functiontext">Rules::set_kind_from</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;rule_being_booked</span><span class="plain">,</span>
<span class="functiontext">Phrases::Usage::get_rulebook</span><span class="plain">(&amp;(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">&gt;usage_data</span><span class="plain">)));</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::Bookings::make_automatic_placements is used in 22/cs (<a href="22-cs.html#SP8">&#167;8</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>Having long ago decided where and how to place the phrase into a rulebook,
we finally get the opportunity to do this. The BR supplied must be the one
generated from the PHUD elsewhere.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::place</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">booking</span><span class="plain"> *</span><span class="identifier">br</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Phrases::Usage::get_effect</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">) == </span><span class="constant">RULE_IN_RULEBOOK_EFF</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">rulebook</span><span class="plain"> *</span><span class="identifier">original_owner</span><span class="plain"> = </span><span class="functiontext">Phrases::Usage::get_rulebook</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="functiontext">Rulebooks::requires_specific_action</span><span class="plain">(</span><span class="identifier">original_owner</span><span class="plain">)) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">waiver</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">action_name_list</span><span class="plain"> *</span><span class="identifier">anl</span><span class="plain">;</span>
<span class="identifier">action_name</span><span class="plain"> *</span><span class="identifier">an</span><span class="plain">;</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">PW</span><span class="plain"> = </span><span class="functiontext">Phrases::Usage::get_prewhile_text</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">PW</span><span class="plain">)) {</span>
<span class="identifier">LOOP_THROUGH_WORDING</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">PW</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PL::Actions::Patterns::Named::by_name</span><span class="plain">(</span><span class="identifier">Wordings::from</span><span class="plain">(</span><span class="identifier">PW</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)))</span>
<span class="reserved">goto</span><span class="plain"> </span><span class="identifier">NotSingleAction</span><span class="plain">;</span>
<span class="identifier">anl</span><span class="plain"> = </span><span class="identifier">PL::Actions::Lists::extract_actions_only</span><span class="plain">(</span><span class="identifier">PW</span><span class="plain">);</span>
<span class="identifier">an</span><span class="plain"> = </span><span class="identifier">PL::Actions::Lists::get_single_action</span><span class="plain">(</span><span class="identifier">anl</span><span class="plain">);</span>
<span class="functiontext">Rules::set_marked_for_anyone</span><span class="plain">(</span><span class="functiontext">Rules::Bookings::get_rule</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">),</span>
<span class="identifier">PL::Actions::Lists::get_explicit_anyone_flag</span><span class="plain">(</span><span class="identifier">anl</span><span class="plain">));</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">anl</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">an</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">waiver</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">original_owner</span><span class="plain"> == </span><span class="identifier">built_in_rulebooks</span><span class="plain">[</span><span class="constant">CHECK_RB</span><span class="plain">]) </span><span class="identifier">waiver</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">original_owner</span><span class="plain"> == </span><span class="identifier">built_in_rulebooks</span><span class="plain">[</span><span class="constant">CARRY_OUT_RB</span><span class="plain">]) </span><span class="identifier">waiver</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">original_owner</span><span class="plain"> == </span><span class="identifier">built_in_rulebooks</span><span class="plain">[</span><span class="constant">REPORT_RB</span><span class="plain">]) </span><span class="identifier">waiver</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">RULE_ATTACHMENTS</span><span class="plain">, </span><span class="string">"BR is: $b\</span><span class="plain">n</span><span class="string"> AN is: $l\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">br</span><span class="plain">, </span><span class="identifier">an</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">an</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) &amp;&amp; (</span><span class="identifier">waiver</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">x</span><span class="plain">;</span>
<span class="identifier">an</span><span class="plain"> = </span><span class="identifier">PL::Actions::longest_null</span><span class="plain">(</span><span class="identifier">PW</span><span class="plain">, </span><span class="identifier">IS_TENSE</span><span class="plain">, &amp;</span><span class="identifier">x</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">an</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) &amp;&amp; (</span><span class="identifier">waiver</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)) {</span>
<span class="identifier">NotSingleAction</span><span class="plain">:</span>
<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">PW</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_MultipleCCR</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 situation this refers to ('%2') is "</span>
<span class="string">"not a single action. Rules in the form of 'check', 'carry "</span>
<span class="string">"out' and 'report' are tied to specific actions, and must "</span>
<span class="string">"give a single explicit action name - even if they then go "</span>
<span class="string">"on to very complicated conditions about any nouns also "</span>
<span class="string">"involved. So 'Check taking something: ...' is fine, "</span>
<span class="string">"but not 'Check taking or dropping something: ...' or "</span>
<span class="string">"'Check doing something: ...' - the former names two "</span>
<span class="string">"actions, the latter none."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">} </span><span class="reserved">else</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">original_owner</span><span class="plain"> == </span><span class="identifier">built_in_rulebooks</span><span class="plain">[</span><span class="constant">CHECK_RB</span><span class="plain">]) {</span>
<span class="functiontext">Phrases::Usage::set_rulebook</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">,</span>
<span class="identifier">PL::Actions::get_fragmented_rulebook</span><span class="plain">(</span><span class="identifier">an</span><span class="plain">, </span><span class="identifier">built_in_rulebooks</span><span class="plain">[</span><span class="constant">CHECK_RB</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">original_owner</span><span class="plain"> == </span><span class="identifier">built_in_rulebooks</span><span class="plain">[</span><span class="constant">CARRY_OUT_RB</span><span class="plain">]) {</span>
<span class="functiontext">Phrases::Usage::set_rulebook</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">,</span>
<span class="identifier">PL::Actions::get_fragmented_rulebook</span><span class="plain">(</span><span class="identifier">an</span><span class="plain">, </span><span class="identifier">built_in_rulebooks</span><span class="plain">[</span><span class="constant">CARRY_OUT_RB</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">original_owner</span><span class="plain"> == </span><span class="identifier">built_in_rulebooks</span><span class="plain">[</span><span class="constant">REPORT_RB</span><span class="plain">]) {</span>
<span class="functiontext">Phrases::Usage::set_rulebook</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">,</span>
<span class="identifier">PL::Actions::get_fragmented_rulebook</span><span class="plain">(</span><span class="identifier">an</span><span class="plain">, </span><span class="identifier">built_in_rulebooks</span><span class="plain">[</span><span class="constant">REPORT_RB</span><span class="plain">]));</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">Phrases::Usage::set_rulebook</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">,</span>
<span class="identifier">PL::Actions::switch_fragmented_rulebook</span><span class="plain">(</span><span class="identifier">an</span><span class="plain">, </span><span class="identifier">original_owner</span><span class="plain">));</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">original_owner</span><span class="plain"> != </span><span class="functiontext">Phrases::Usage::get_rulebook</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">))</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">RULE_ATTACHMENTS</span><span class="plain">, </span><span class="string">"Rerouting $b to $K\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">br</span><span class="plain">,</span>
<span class="functiontext">Phrases::Usage::get_rulebook</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="functiontext">Rulebooks::attach_rule</span><span class="plain">(</span><span class="functiontext">Phrases::Usage::get_rulebook</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">), </span><span class="identifier">br</span><span class="plain">,</span>
<span class="functiontext">Phrases::Usage::get_rulebook_placement</span><span class="plain">(</span><span class="identifier">phud</span><span class="plain">), 0, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::Bookings::place is used in <a href="#SP8">&#167;8</a>.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. Specificity of bookings. </b>The following is one of Inform's standardised comparison routines, which
takes a pair of objects A, B and returns 1 if A makes a more specific
description than B, 0 if they seem equally specific, or -1 if B makes a
more specific description than A. This is transitive, and intended to be
used in sorting algorithms.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::compare_specificity_of_br</span><span class="plain">(</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">br1</span><span class="plain">, </span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">br2</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">log</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">br1</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">br2</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">"compared null specificity"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">log</span><span class="plain">) </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Comparing specificity of rules:\</span><span class="plain">n</span><span class="string">(1) $b\</span><span class="plain">n</span><span class="string">(2) $b\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">br1</span><span class="plain">, </span><span class="identifier">br2</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Rules::compare_specificity</span><span class="plain">(</span>
<span class="identifier">br1</span><span class="plain">-</span><span class="element">&gt;rule_being_booked</span><span class="plain">, </span><span class="identifier">br2</span><span class="plain">-</span><span class="element">&gt;rule_being_booked</span><span class="plain">, </span><span class="identifier">log</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::Bookings::compare_specificity_of_br is used in <a href="#SP14_6_3">&#167;14.6.3</a>, <a href="#SP21_2">&#167;21.2</a>.</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. Lists of bookings. </b>Bookings are intended to be bound together in linked lists, each of which
represents the interior pages of a single rulebook.
</p>
<p class="inwebparagraph">There are only three operations on lists: creation, addition of a booking,
and removal of a booking. The following invariants are preserved:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) The list head is a dummy booking which has never been the subject of any
addition operation and has never moved.
</li></ul>
<ul class="items"><li>(b) The only <code class="display"><span class="extract">FIRST_PLACEMENT</span></code> entries in the list immediately follow the list
head. Those which were added explicitly as first-placed are in reverse order
of addition to the list.
</li></ul>
<ul class="items"><li>(c) The only <code class="display"><span class="extract">LAST_PLACEMENT</span></code> entries in the list are at the end. Those which
were added explicitly as last-placed are in order of addition to the list.
</li></ul>
<ul class="items"><li>(d) If R and S are middle-placed rules which were placed in the list within
the same range (say, both anywhere, or both "after T" or "before U")
and R precedes S, then either R is more specific than S, or they are
equally specific and R was added to the list before S.
</li></ul>
<ul class="items"><li>(e) The list never contains duplicates, that is, never contains two bookings
whose rules are equal, in the sense of <code class="display"><span class="extract">Rules::eq</span></code>.
</li></ul>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>A new list is a dummy header (see (a) above):
</p>
<pre class="display">
<span class="reserved">booking</span><span class="plain"> *</span><span class="functiontext">Rules::Bookings::list_new</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::new</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 Rules::Bookings::list_new is used in 21/rl2 (<a href="21-rl2.html#SP10">&#167;10</a>).</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>When rule R is explicitly placed into (the rule list of) rulebook B
(by an assertion like "R is listed after S in B", say), there are
evidently two possibilities:
</p>
<p class="inwebparagraph">Case (i). R's phrase already occurs somewhere in rulebook B, so that this
affects only the ordering of rulebook B. We therefore remove it (so that it
does not occur twice in B) and reinsert it within the position range
indicated. Note that this process still makes use of logical precedence; it
simply confines itself to a narrower range. If R has to occur before S,
then R is placed according to logical precedence within the sublist from
the head of the list up to just-before-S.
</p>
<p class="inwebparagraph">To determine whether or not R's phrase is already in B, we compare their
phrases if set, and their I6 equivalents if not.
</p>
<p class="inwebparagraph">Note that we search the entire rulebook for R, not just the valid interval
in the rulebook where R might go (e.g., "after S").
</p>
<p class="inwebparagraph">Case (ii). R's phrase does not occur in B. We insert R into rulebook B
within the position range indicated.
</p>
<p class="inwebparagraph">Each addition leaves the list either the same size or longer by 1.
</p>
<p class="inwebparagraph">If we insert a rule as first-placed rule when there already is a
first-placed rule, the new one displaces it to go first, but both continue
to be labelled as "first-placed", so that subsequent rule insertions of
middle-placed rules will still go after both of them. Symmetrically, a
second last-placed rule is inserted after any existing one, but both are
labelled "last-placed". Because of the range possibility ("after S") we
might find ourselves inserting a rule as middle-placed and yet still after
a last-placed rule, or before a first-placed one: if so we change its
placement to last or first respectively, in order to preserve invariants
</p>
<ul class="items"><li>(b) and (c) above.
</li></ul>
<p class="inwebparagraph">There was a small debate on <code class="display"><span class="extract">rec.arts.int-fiction</span></code> in February 2009 as
to whether a rule placed instead of another rule within the same rulebook
should be duplicated, or moved. In builds from 2008 and earlier, there was
duplication, but this broke the clean principle that a rule appears only
once per rulebook, and made it difficult to place certain rules with tricky
preambles; on the other hand merely moving makes it more difficult to
replace a whole run of rules with a single place-holder. Both sides were
argued for. In March 2009, it was finally decided to go with moving, not
duplication, and to preserve the "only once per rulebook" principle.
</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. </b>We specify the way we want to add a rule to a list of bookings using the
following enumerated values, which handle requirements like "before the
awkward noises rule".
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">BEFORE_SIDE</span><span class="plain"> -1 </span> <span class="comment">before a reference rule</span>
<span class="definitionkeyword">define</span> <span class="constant">IN_SIDE</span><span class="plain"> 0 </span> <span class="comment">without reference to any other rule</span>
<span class="definitionkeyword">define</span> <span class="constant">AFTER_SIDE</span><span class="plain"> 1 </span> <span class="comment">after a reference rule</span>
<span class="definitionkeyword">define</span> <span class="constant">INSTEAD_SIDE</span><span class="plain"> 2 </span> <span class="comment">in place of reference rule</span>
</pre>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::list_add</span><span class="plain">(</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">list_head</span><span class="plain">, </span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">new_rule</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">placing</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">side</span><span class="plain">, </span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">ref_rule</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Make some sanity checks on the addition instructions</span> <span class="cwebmacronumber">14.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Handle the case where the new rule is already in the list</span> <span class="cwebmacronumber">14.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Handle all placements made with the INSTEAD side</span> <span class="cwebmacronumber">14.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Handle all placements made with the FIRST placement</span> <span class="cwebmacronumber">14.4</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Handle all placements made with the LAST placement</span> <span class="cwebmacronumber">14.5</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Handle what's left: MIDDLE placements on the IN, BEFORE or AFTER sides</span> <span class="cwebmacronumber">14.6</span>&gt;<span class="character">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::Bookings::list_add is used in 21/rl2 (<a href="21-rl2.html#SP19">&#167;19</a>).</p>
<p class="inwebparagraph"><a id="SP14_1"></a><b>&#167;14.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Make some sanity checks on the addition instructions</span> <span class="cwebmacronumber">14.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">side</span><span class="plain"> != </span><span class="constant">IN_SIDE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">ref_rule</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">"tried to add before or after or instead of non-rule"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">side</span><span class="plain"> == </span><span class="constant">IN_SIDE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">ref_rule</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">"tried to add in middle but with ref rule"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">side</span><span class="plain"> != </span><span class="constant">IN_SIDE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">placing</span><span class="plain"> != </span><span class="constant">MIDDLE_PLACEMENT</span><span class="plain">))</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to add before or after but with non-middle placement"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">list_head</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">"tried to add rule to null list"</span><span class="plain">);</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">placing</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">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="constant">FIRST_PLACEMENT</span><span class="plain">: </span><span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">RULE_ATTACHMENTS</span><span class="plain">, </span><span class="string">"Placed first\</span><span class="plain">n</span><span class="string">"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">LAST_PLACEMENT</span><span class="plain">: </span><span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">RULE_ATTACHMENTS</span><span class="plain">, </span><span class="string">"Placed last\</span><span class="plain">n</span><span class="string">"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">:</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Invalid placing %d\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">placing</span><span class="plain">);</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"invalid placing of rule"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP14">&#167;14</a>.</p>
<p class="inwebparagraph"><a id="SP14_2"></a><b>&#167;14.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Handle the case where the new rule is already in the list</span> <span class="cwebmacronumber">14.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">pos</span><span class="plain">, *</span><span class="identifier">prev</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">prev</span><span class="plain">=</span><span class="identifier">list_head</span><span class="plain">, </span><span class="identifier">pos</span><span class="plain">=</span><span class="identifier">list_head</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">; </span><span class="identifier">pos</span><span class="plain">; </span><span class="identifier">prev</span><span class="plain">=</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">pos</span><span class="plain">=</span><span class="identifier">pos</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rules::eq</span><span class="plain">(</span><span class="functiontext">Rules::Bookings::get_rule</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">),</span>
<span class="functiontext">Rules::Bookings::get_rule</span><span class="plain">(</span><span class="identifier">new_rule</span><span class="plain">))) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">side</span><span class="plain"> == </span><span class="constant">IN_SIDE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">placing</span><span class="plain"> == </span><span class="constant">MIDDLE_PLACEMENT</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain">; </span> <span class="comment">rule is already in rulebook: do nothing</span>
<span class="identifier">prev</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain"> = </span><span class="identifier">pos</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">;</span>
<span class="identifier">pos</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">RULE_ATTACHMENTS</span><span class="plain">, </span><span class="string">"Removing previous entry from rulebook\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">; </span> <span class="comment">rule can only appear once, so no need to keep checking</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP14">&#167;14</a>.</p>
<p class="inwebparagraph"><a id="SP14_3"></a><b>&#167;14.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Handle all placements made with the INSTEAD side</span> <span class="cwebmacronumber">14.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">side</span><span class="plain"> == </span><span class="constant">INSTEAD_SIDE</span><span class="plain">) {</span>
<span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">pos</span><span class="plain">, *</span><span class="identifier">prev</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">prev</span><span class="plain">=</span><span class="identifier">list_head</span><span class="plain">, </span><span class="identifier">pos</span><span class="plain">=</span><span class="identifier">list_head</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">; </span><span class="identifier">pos</span><span class="plain">; </span><span class="identifier">prev</span><span class="plain">=</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">pos</span><span class="plain">=</span><span class="identifier">pos</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rules::eq</span><span class="plain">(</span><span class="functiontext">Rules::Bookings::get_rule</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">), </span><span class="identifier">ref_rule</span><span class="plain">)) {</span>
<span class="identifier">new_rule</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain"> = </span><span class="identifier">pos</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain">; </span> <span class="comment">replace with same placement</span>
<span class="identifier">new_rule</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain"> = </span><span class="identifier">pos</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">;</span>
<span class="identifier">prev</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain"> = </span><span class="identifier">new_rule</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP14">&#167;14</a>.</p>
<p class="inwebparagraph"><a id="SP14_4"></a><b>&#167;14.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Handle all placements made with the FIRST placement</span> <span class="cwebmacronumber">14.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">placing</span><span class="plain"> == </span><span class="constant">FIRST_PLACEMENT</span><span class="plain">) { </span> <span class="comment">first in valid interval (must be whole list)</span>
<span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">subseq</span><span class="plain"> = </span><span class="identifier">list_head</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">;</span>
<span class="identifier">list_head</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain"> = </span><span class="identifier">new_rule</span><span class="plain">;</span>
<span class="identifier">new_rule</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain"> = </span><span class="identifier">subseq</span><span class="plain">; </span> <span class="comment">pushes any existing first rule forward</span>
<span class="identifier">new_rule</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain"> = </span><span class="identifier">placing</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP14">&#167;14</a>.</p>
<p class="inwebparagraph"><a id="SP14_5"></a><b>&#167;14.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Handle all placements made with the LAST placement</span> <span class="cwebmacronumber">14.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">placing</span><span class="plain"> == </span><span class="constant">LAST_PLACEMENT</span><span class="plain">) { </span> <span class="comment">last in valid interval (must be whole list)</span>
<span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">prev</span><span class="plain"> = </span><span class="identifier">list_head</span><span class="plain">;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">prev</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain"> != </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">prev</span><span class="plain"> = </span><span class="identifier">prev</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">;</span>
<span class="identifier">prev</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain"> = </span><span class="identifier">new_rule</span><span class="plain">; </span> <span class="comment">pushes any existing last rule backward</span>
<span class="identifier">new_rule</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">new_rule</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain"> = </span><span class="identifier">placing</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP14">&#167;14</a>.</p>
<p class="inwebparagraph"><a id="SP14_6"></a><b>&#167;14.6. </b><code class="display">
&lt;<span class="cwebmacrodefn">Handle what's left: MIDDLE placements on the IN, BEFORE or AFTER sides</span> <span class="cwebmacronumber">14.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">start_rule</span><span class="plain"> = </span><span class="identifier">list_head</span><span class="plain">; </span> <span class="comment">valid interval begins after this rule</span>
<span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">end_rule</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">valid interval ends before this rule, or runs to end if <code class="display"><span class="extract">NULL</span></code></span>
&lt;<span class="cwebmacro">Adjust the valid interval to take care of BEFORE and AFTER side requirements</span> <span class="cwebmacronumber">14.6.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Check that the valid interval is indeed as advertised</span> <span class="cwebmacronumber">14.6.2</span>&gt;<span class="plain">;</span>
<span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">insert_after</span><span class="plain"> = </span><span class="identifier">start_rule</span><span class="plain">; </span> <span class="comment">insertion point is after this</span>
&lt;<span class="cwebmacro">Find insertion point, keeping the valid interval in specificity order</span> <span class="cwebmacronumber">14.6.3</span>&gt;<span class="plain">;</span>
<span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">subseq</span><span class="plain"> = </span><span class="identifier">insert_after</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">;</span>
<span class="identifier">insert_after</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain"> = </span><span class="identifier">new_rule</span><span class="plain">;</span>
<span class="identifier">new_rule</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain"> = </span><span class="identifier">subseq</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Set the placement for the new rule booking</span> <span class="cwebmacronumber">14.6.4</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP14">&#167;14</a>.</p>
<p class="inwebparagraph"><a id="SP14_6_1"></a><b>&#167;14.6.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Adjust the valid interval to take care of BEFORE and AFTER side requirements</span> <span class="cwebmacronumber">14.6.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">pos</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">side</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">BEFORE_SIDE</span><span class="plain">:</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">pos</span><span class="plain">=</span><span class="identifier">list_head</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">; </span><span class="identifier">pos</span><span class="plain">; </span><span class="identifier">pos</span><span class="plain">=</span><span class="identifier">pos</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rules::eq</span><span class="plain">(</span><span class="functiontext">Rules::Bookings::get_rule</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">), </span><span class="identifier">ref_rule</span><span class="plain">))</span>
<span class="identifier">end_rule</span><span class="plain"> = </span><span class="identifier">pos</span><span class="plain">; </span> <span class="comment">insert before: so valid interval ends here</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">end_rule</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">"can't find end rule"</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">AFTER_SIDE</span><span class="plain">:</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">pos</span><span class="plain">=</span><span class="identifier">list_head</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">; </span><span class="identifier">pos</span><span class="plain">; </span><span class="identifier">pos</span><span class="plain">=</span><span class="identifier">pos</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rules::eq</span><span class="plain">(</span><span class="functiontext">Rules::Bookings::get_rule</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">), </span><span class="identifier">ref_rule</span><span class="plain">))</span>
<span class="identifier">start_rule</span><span class="plain"> = </span><span class="identifier">pos</span><span class="plain">; </span> <span class="comment">insert after: so valid interval begins here</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">start_rule</span><span class="plain"> == </span><span class="identifier">list_head</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"can't find start rule"</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="#SP14_6">&#167;14.6</a>.</p>
<p class="inwebparagraph"><a id="SP14_6_2"></a><b>&#167;14.6.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Check that the valid interval is indeed as advertised</span> <span class="cwebmacronumber">14.6.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> = 0, </span><span class="identifier">t</span><span class="plain"> = 2;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">end_rule</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">t</span><span class="plain"> = 1;</span>
<span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">pos</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">pos</span><span class="plain"> = </span><span class="identifier">list_head</span><span class="plain">; </span><span class="identifier">pos</span><span class="plain">; </span><span class="identifier">pos</span><span class="plain"> = </span><span class="identifier">pos</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">pos</span><span class="plain"> == </span><span class="identifier">start_rule</span><span class="plain">) &amp;&amp; (</span><span class="identifier">i</span><span class="plain"> == 0)) </span><span class="identifier">i</span><span class="plain"> = 1;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">pos</span><span class="plain"> == </span><span class="identifier">end_rule</span><span class="plain">) &amp;&amp; (</span><span class="identifier">i</span><span class="plain"> == 1)) </span><span class="identifier">i</span><span class="plain"> = 2;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> != </span><span class="identifier">t</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"valid rule interval isn't"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP14_6">&#167;14.6</a>.</p>
<p class="inwebparagraph"><a id="SP14_6_3"></a><b>&#167;14.6.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Find insertion point, keeping the valid interval in specificity order</span> <span class="cwebmacronumber">14.6.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">log</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">Log::aspect_switched_on</span><span class="plain">(</span><span class="constant">SPECIFICITIES_DA</span><span class="plain">)) </span><span class="identifier">log</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="comment">move forward to final valid first rule (if any exist)</span>
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">insert_after</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain"> != </span><span class="identifier">end_rule</span><span class="plain">)</span>
<span class="plain">&amp;&amp; (</span><span class="identifier">insert_after</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain"> == </span><span class="constant">FIRST_PLACEMENT</span><span class="plain">))</span>
<span class="identifier">insert_after</span><span class="plain"> = </span><span class="identifier">insert_after</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">;</span>
<span class="comment">move forward past other middle rules if they are not less specific</span>
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">insert_after</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain"> != </span><span class="identifier">end_rule</span><span class="plain">) </span> <span class="comment">stop before p leaves valid range</span>
<span class="plain">&amp;&amp; (</span><span class="identifier">insert_after</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain"> != </span><span class="constant">LAST_PLACEMENT</span><span class="plain">) </span> <span class="comment">or reaches a last rule</span>
<span class="plain">&amp;&amp; (</span><span class="functiontext">Rules::Bookings::compare_specificity_of_br</span><span class="plain">(</span><span class="identifier">insert_after</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">, </span><span class="identifier">new_rule</span><span class="plain">,</span>
<span class="identifier">log</span><span class="plain">) &gt;= 0)) </span> <span class="comment">or a rule less specific than the new one</span>
<span class="identifier">insert_after</span><span class="plain"> = </span><span class="identifier">insert_after</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP14_6">&#167;14.6</a>.</p>
<p class="inwebparagraph"><a id="SP14_6_4"></a><b>&#167;14.6.4. </b>Since this part of the algorithm is used only when we've requested MIDDLE
placement, it might seem that <code class="display"><span class="extract">new_rule-&gt;placement</span></code> should always be set to
that. This does indeed mostly happen, but not always. To preserve rulebook
invariants (b) and (c), we need to force anything added after a LAST rule
to be LAST as well, and similarly for FIRSTs. (This will only happen in
cases where the source text called for placements AFTER a LAST rule, or
BEFORE a FIRST one.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Set the placement for the new rule booking</span> <span class="cwebmacronumber">14.6.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">new_rule</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain"> = </span><span class="constant">MIDDLE_PLACEMENT</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">insert_after</span><span class="plain"> != </span><span class="identifier">list_head</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">insert_after</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain"> == </span><span class="constant">LAST_PLACEMENT</span><span class="plain">))</span>
<span class="identifier">new_rule</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain"> =</span>
<span class="constant">LAST_PLACEMENT</span><span class="plain">; </span> <span class="comment">happens if valid interval is after a last rule</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">subseq</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">subseq</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain"> == </span><span class="constant">FIRST_PLACEMENT</span><span class="plain">))</span>
<span class="identifier">new_rule</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain"> =</span>
<span class="constant">FIRST_PLACEMENT</span><span class="plain">; </span> <span class="comment">happens if valid interval is before a first rule</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP14_6">&#167;14.6</a>.</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. </b>That leaves only the removal operation, which is much simpler:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::list_remove</span><span class="plain">(</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">list_head</span><span class="plain">, </span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">ref_rule</span><span class="plain">) {</span>
<span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">br</span><span class="plain">, *</span><span class="identifier">pr</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">list_head</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">, </span><span class="identifier">pr</span><span class="plain"> = </span><span class="identifier">list_head</span><span class="plain">; </span><span class="identifier">br</span><span class="plain">; </span><span class="identifier">pr</span><span class="plain"> = </span><span class="identifier">br</span><span class="plain">, </span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rules::eq</span><span class="plain">(</span><span class="functiontext">Rules::Bookings::get_rule</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">), </span><span class="identifier">ref_rule</span><span class="plain">)) {</span>
<span class="identifier">pr</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain"> = </span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::Bookings::list_remove is used in 21/rl2 (<a href="21-rl2.html#SP19">&#167;19</a>).</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. Logging lists. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::list_log</span><span class="plain">(</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">list_head</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">list_head</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) { </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"&lt;null-booked-rule-list&gt;\</span><span class="plain">n</span><span class="string">"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain"> = </span><span class="functiontext">Rules::Bookings::no_rules_in_list</span><span class="plain">(</span><span class="identifier">list_head</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain"> == 0) { </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"&lt;empty-booked-rule-list&gt;\</span><span class="plain">n</span><span class="string">"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">br</span><span class="plain">; </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">s</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">list_head</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">, </span><span class="identifier">s</span><span class="plain"> = 1; </span><span class="identifier">br</span><span class="plain">; </span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">, </span><span class="identifier">s</span><span class="plain">++)</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">" %d/%d. $b\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, ++</span><span class="identifier">s</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">br</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::Bookings::list_log is used in <a href="#SP21_1">&#167;21.1</a>, 21/rl2 (<a href="21-rl2.html#SP15">&#167;15</a>).</p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. Scanning lists for their contents. </b>Strictly speaking a <code class="display"><span class="extract">NULL</span></code> pointer is not valid as a booking list, since it
has no head, but we treat it as if it were the empty list:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::no_rules_in_list</span><span class="plain">(</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">list_head</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">list_head</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> 0;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">n</span><span class="plain"> = 0;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">list_head</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">; </span><span class="identifier">br</span><span class="plain">; </span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">) </span><span class="identifier">n</span><span class="plain">++;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">n</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::list_is_empty</span><span class="plain">(</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">list_head</span><span class="plain">, </span><span class="reserved">rule_context</span><span class="plain"> </span><span class="identifier">rc</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">list_head</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">list_head</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">; </span><span class="identifier">br</span><span class="plain">; </span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</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">Rules::get_I7_definition</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;rule_being_booked</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rulebooks::phrase_fits_rule_context</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">rc</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="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::list_is_empty_of_i7_rules</span><span class="plain">(</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">list_head</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">list_head</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">list_head</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">; </span><span class="identifier">br</span><span class="plain">; </span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rules::get_I7_definition</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;rule_being_booked</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::list_contains</span><span class="plain">(</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">list_head</span><span class="plain">, </span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">to_find</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">list_head</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">list_head</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">; </span><span class="identifier">br</span><span class="plain">; </span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rules::eq</span><span class="plain">(</span><span class="functiontext">Rules::Bookings::get_rule</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">), </span><span class="identifier">to_find</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="reserved">int</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::list_contains_ph</span><span class="plain">(</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">list_head</span><span class="plain">, </span><span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph_to_find</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">list_head</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">list_head</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">; </span><span class="identifier">br</span><span class="plain">; </span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rules::get_I7_definition</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;rule_being_booked</span><span class="plain">) == </span><span class="identifier">ph_to_find</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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::Bookings::no_rules_in_list is used in <a href="#SP16">&#167;16</a>, <a href="#SP22">&#167;22</a>, <a href="#SP24">&#167;24</a>, 21/rl2 (<a href="21-rl2.html#SP12">&#167;12</a>).</p>
<p class="endnote">The function Rules::Bookings::list_is_empty is used in 21/rl2 (<a href="21-rl2.html#SP12">&#167;12</a>, <a href="21-rl2.html#SP15">&#167;15</a>).</p>
<p class="endnote">The function Rules::Bookings::list_is_empty_of_i7_rules is used in 21/rl2 (<a href="21-rl2.html#SP20">&#167;20</a>).</p>
<p class="endnote">The function Rules::Bookings::list_contains is used in 21/rl2 (<a href="21-rl2.html#SP12">&#167;12</a>).</p>
<p class="endnote">The function Rules::Bookings::list_contains_ph is used in 21/rl2 (<a href="21-rl2.html#SP22">&#167;22</a>), 21/fao (<a href="21-fao.html#SP10">&#167;10</a>).</p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. Indexing of lists. </b>There's a division of labour: here we arrange the index of the rules and
show the linkage between them, while the actual content for each rule is
handled in the "Rules" section.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::list_index</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">list_head</span><span class="plain">, </span><span class="reserved">rule_context</span><span class="plain"> </span><span class="identifier">rc</span><span class="plain">,</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">billing</span><span class="plain">, </span><span class="reserved">rulebook</span><span class="plain"> *</span><span class="identifier">owner</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">resp_count</span><span class="plain">) {</span>
<span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">br</span><span class="plain">, *</span><span class="identifier">prev</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">count</span><span class="plain"> = 0;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">list_head</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">, </span><span class="identifier">prev</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">br</span><span class="plain">; </span><span class="identifier">prev</span><span class="plain"> = </span><span class="identifier">br</span><span class="plain">, </span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">) {</span>
<span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;rule_being_booked</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">phrase</span><span class="plain"> *</span><span class="identifier">ph</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</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"> = &amp;(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">&gt;runtime_context_data</span><span class="plain">);</span>
<span class="identifier">scene</span><span class="plain"> *</span><span class="identifier">during_scene</span><span class="plain"> = </span><span class="functiontext">Phrases::Context::get_scene</span><span class="plain">(</span><span class="identifier">phrcd</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">rc</span><span class="element">.scene_context</span><span class="plain">) &amp;&amp; (</span><span class="identifier">during_scene</span><span class="plain"> != </span><span class="identifier">rc</span><span class="element">.scene_context</span><span class="plain">)) </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">rc</span><span class="element">.action_context</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Phrases::Context::within_action_context</span><span class="plain">(</span><span class="identifier">phrcd</span><span class="plain">, </span><span class="identifier">rc</span><span class="element">.action_context</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">))</span>
<span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="identifier">count</span><span class="plain">++;</span>
<span class="functiontext">Rules::Bookings::br_start_index_line</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">prev</span><span class="plain">, </span><span class="identifier">billing</span><span class="plain">);</span>
<span class="plain">*</span><span class="identifier">resp_count</span><span class="plain"> += </span><span class="functiontext">Rules::index</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">, </span><span class="identifier">owner</span><span class="plain">, </span><span class="identifier">rc</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">count</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::Bookings::list_index is used in 21/rl2 (<a href="21-rl2.html#SP15">&#167;15</a>).</p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. </b>The "index links" are not hypertextual: they're the little icons showing
the order of precedence of rules in the list. On some index pages we don't
want this, so:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">show_index_links</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::list_suppress_indexed_links</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">show_index_links</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::list_resume_indexed_links</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">show_index_links</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::br_start_index_line</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">prev</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">billing</span><span class="plain">) {</span>
<span class="identifier">HTMLFiles::open_para</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 2, </span><span class="string">"hanging"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">billing</span><span class="plain">[0]) &amp;&amp; (</span><span class="identifier">show_index_links</span><span class="plain">)) </span><span class="functiontext">Rules::Bookings::br_show_linkage_icon</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">prev</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%s"</span><span class="plain">, </span><span class="identifier">billing</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">billing</span><span class="plain">[0] == 0) &amp;&amp; (</span><span class="identifier">show_index_links</span><span class="plain">)) </span><span class="functiontext">Rules::Bookings::br_show_linkage_icon</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">prev</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::Bookings::list_suppress_indexed_links is used in 21/rl2 (<a href="21-rl2.html#SP15">&#167;15</a>).</p>
<p class="endnote">The function Rules::Bookings::list_resume_indexed_links is used in 21/rl2 (<a href="21-rl2.html#SP15">&#167;15</a>).</p>
<p class="endnote">The function Rules::Bookings::br_start_index_line is used in <a href="#SP18">&#167;18</a>.</p>
<p class="inwebparagraph"><a id="SP20"></a><b>&#167;20. </b>And here's how the index links (if wanted) are chosen and plotted:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::br_show_linkage_icon</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">prev</span><span class="plain">) {</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">icon_name</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">redundant assignment to appease <code class="display"><span class="extract">gcc -O2</span></code></span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">prev</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">prev</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity_law</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) {</span>
<span class="identifier">HTMLFiles::html_icon_with_tooltip</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="string">"rulenone.png"</span><span class="plain">, </span><span class="string">"start of rulebook"</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">prev</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> -1: </span><span class="identifier">icon_name</span><span class="plain"> = </span><span class="string">"ruleless.png"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 0: </span><span class="identifier">icon_name</span><span class="plain"> = </span><span class="string">"ruleequal.png"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 1: </span><span class="identifier">icon_name</span><span class="plain"> = </span><span class="string">"rulemore.png"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">: </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"unknown rule specificity"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">HTMLFiles::html_icon_with_tooltip</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">icon_name</span><span class="plain">, </span><span class="identifier">prev</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity_law</span><span class="plain">,</span>
<span class="identifier">prev</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity_lawname</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::Bookings::br_show_linkage_icon is used in <a href="#SP19">&#167;19</a>.</p>
<p class="inwebparagraph"><a id="SP21"></a><b>&#167;21. Calculating the specificities. </b>And this is where the fields describing how the list was ordered are put
together. They're not a historical record of what was done: they're a
measurement of the final outcome.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::list_judge_ordering</span><span class="plain">(</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">list_head</span><span class="plain">) {</span>
<span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">br</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">list_head</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">list_head</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">; </span><span class="identifier">br</span><span class="plain">; </span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain"> != </span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Calculate specificities when placements differ</span> <span class="cwebmacronumber">21.1</span>&gt;
<span class="reserved">else</span>
&lt;<span class="cwebmacro">Calculate specificities when placements are the same</span> <span class="cwebmacronumber">21.2</span>&gt;<span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity</span><span class="plain"> = 0;</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity_law</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::Bookings::list_judge_ordering is used in 21/rl2 (<a href="21-rl2.html#SP20">&#167;20</a>).</p>
<p class="inwebparagraph"><a id="SP21_1"></a><b>&#167;21.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Calculate specificities when placements differ</span> <span class="cwebmacronumber">21.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity</span><span class="plain"> = 1;</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">FIRST_PLACEMENT</span><span class="plain">:</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">MIDDLE_PLACEMENT</span><span class="plain">:</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity_law</span><span class="plain"> =</span>
<span class="string">"the rule above was listed as 'first' so precedes this "</span>
<span class="string">"one, which wasn't"</span><span class="plain">;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">LAST_PLACEMENT</span><span class="plain">:</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity_law</span><span class="plain"> =</span>
<span class="string">"the rule above was listed as 'first' so precedes this "</span>
<span class="string">"one, which was listed as 'last'"</span><span class="plain">;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">:</span>
<span class="functiontext">Rules::Bookings::list_log</span><span class="plain">(</span><span class="identifier">list_head</span><span class="plain">);</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"booking list invariant broken"</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">MIDDLE_PLACEMENT</span><span class="plain">:</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">LAST_PLACEMENT</span><span class="plain">:</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity_law</span><span class="plain"> =</span>
<span class="string">"the rule below was listed as 'last' so comes after the "</span>
<span class="string">"rule above, which wasn't"</span><span class="plain">;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">:</span>
<span class="functiontext">Rules::Bookings::list_log</span><span class="plain">(</span><span class="identifier">list_head</span><span class="plain">);</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"booking list invariant broken"</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">:</span>
<span class="functiontext">Rules::Bookings::list_log</span><span class="plain">(</span><span class="identifier">list_head</span><span class="plain">);</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"booking list invariant broken"</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">&#167;21</a>.</p>
<p class="inwebparagraph"><a id="SP21_2"></a><b>&#167;21.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Calculate specificities when placements are the same</span> <span class="cwebmacronumber">21.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">r</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">FIRST_PLACEMENT</span><span class="plain">:</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity</span><span class="plain"> = 0;</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity_law</span><span class="plain"> =</span>
<span class="string">"these rules were both listed as 'first', so they appear in "</span>
<span class="string">"reverse order of listing"</span><span class="plain">;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">MIDDLE_PLACEMENT</span><span class="plain">:</span>
<span class="identifier">r</span><span class="plain"> = </span><span class="functiontext">Rules::Bookings::compare_specificity_of_br</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">, </span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity</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">r</span><span class="plain"> == 0) </span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity_law</span><span class="plain"> =</span>
<span class="string">"these rules are equally ranked, so their order is determined by "</span>
<span class="string">"which was defined first (or by explicit 'listed in' sentences)"</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity_law</span><span class="plain"> =</span>
<span class="string">"the arrow points from a more specific rule to a more general one, "</span>
<span class="string">"as decided by Law"</span><span class="plain">;</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity_lawname</span><span class="plain"> = </span><span class="identifier">c_s_stage_law</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">LAST_PLACEMENT</span><span class="plain">:</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity</span><span class="plain"> = 0;</span>
<span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity_law</span><span class="plain"> =</span>
<span class="string">"these rules were both listed as 'last', so they appear in order "</span>
<span class="string">"of listing"</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">&#167;21</a>.</p>
<p class="inwebparagraph"><a id="SP22"></a><b>&#167;22. Compilation of rule definitions for rulebook. </b>There's no real need to do it this way &mdash; but we compile rule definitions
in rulebook order to make the I6 source more legible, and for the same
reason we add plenty of commentary.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::list_compile_rule_phrases</span><span class="plain">(</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">list_head</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> *</span><span class="identifier">i</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">max_i</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">list_head</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">t</span><span class="plain"> = </span><span class="functiontext">Rules::Bookings::no_rules_in_list</span><span class="plain">(</span><span class="identifier">list_head</span><span class="plain">);</span>
<span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">br</span><span class="plain">; </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">s</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">list_head</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">, </span><span class="identifier">s</span><span class="plain"> = 1; </span><span class="identifier">br</span><span class="plain">; </span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">, </span><span class="identifier">s</span><span class="plain">++) {</span>
<span class="functiontext">Rules::compile_comment</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;rule_being_booked</span><span class="plain">, </span><span class="identifier">s</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</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="reserved">if</span><span class="plain"> (</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain"> != </span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">-</span><span class="element">&gt;placement</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">"--- now the "</span><span class="plain">);</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">-</span><span class="element">&gt;placement</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">FIRST_PLACEMENT</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">"first-placed rules"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">MIDDLE_PLACEMENT</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">"mid-placed rules"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">LAST_PLACEMENT</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">"last-placed rules"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</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">" ---"</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="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">law</span><span class="plain"> = </span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity_lawname</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule_specificity</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> -1: </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="string">" &lt;&lt;&lt; %s &lt;&lt;&lt;"</span><span class="plain">, </span><span class="identifier">law</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="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 0: </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="string">" === equally specific with ==="</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="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> 1: </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="string">" &gt;&gt;&gt; %s &gt;&gt;&gt;"</span><span class="plain">, </span><span class="identifier">law</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="reserved">break</span><span class="plain">;</span>
<span class="plain">}</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>
<span class="plain">}</span>
<span class="functiontext">CompiledText::divider_comment</span><span class="plain">();</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::Bookings::list_compile_rule_phrases is used in 21/rl2 (<a href="21-rl2.html#SP20">&#167;20</a>).</p>
<p class="inwebparagraph"><a id="SP23"></a><b>&#167;23. Compilation of I6-format rulebook. </b>The following can generate both old-style array rulebooks and routine rulebooks,
which were introduced in December 2010.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rules::Bookings::start_list_compilation</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">EMPTY_RULEBOOK_INAME_HL</span><span class="plain">);</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">);</span>
<span class="functiontext">LocalVariables::add_named_call</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"forbid_breaks"</span><span class="plain">);</span>
<span class="identifier">Produce::rfalse</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="functiontext">Hierarchy::make_available</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">iname</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::Bookings::start_list_compilation is used in 21/rl2 (<a href="21-rl2.html#SP20">&#167;20</a>).</p>
<p class="inwebparagraph"><a id="SP24"></a><b>&#167;24. </b></p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">ARRAY_RBF</span><span class="plain"> 1 </span> <span class="comment">format as an array simply listing the rules</span>
<span class="definitionkeyword">define</span> <span class="constant">GROUPED_ARRAY_RBF</span><span class="plain"> 2 </span> <span class="comment">format as a grouped array, for quicker action testing</span>
<span class="definitionkeyword">define</span> <span class="constant">ROUTINE_RBF</span><span class="plain"> 3 </span> <span class="comment">format as a routine which runs the rulebook</span>
<span class="definitionkeyword">define</span> <span class="constant">RULE_OPTIMISATION_THRESHOLD</span><span class="plain"> 20 </span> <span class="comment">group arrays when larger than this number of rules</span>
</pre>
<pre class="display">
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Rules::Bookings::list_compile</span><span class="plain">(</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">list_head</span><span class="plain">,</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">identifier</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">action_based</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">parameter_based</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">list_head</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">rb_symb</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">countup</span><span class="plain"> = </span><span class="functiontext">Rules::Bookings::no_rules_in_list</span><span class="plain">(</span><span class="identifier">list_head</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">countup</span><span class="plain"> == 0) {</span>
<span class="identifier">rb_symb</span><span class="plain"> = </span><span class="functiontext">Emit::named_iname_constant</span><span class="plain">(</span><span class="identifier">identifier</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">,</span>
<span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">EMPTY_RULEBOOK_INAME_HL</span><span class="plain">));</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">format</span><span class="plain"> = </span><span class="constant">ROUTINE_RBF</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Compile the rulebook in the given format</span> <span class="cwebmacronumber">24.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">rb_symb</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::Bookings::list_compile is used in 21/rl2 (<a href="21-rl2.html#SP20">&#167;20</a>).</p>
<p class="inwebparagraph"><a id="SP24_1"></a><b>&#167;24.1. </b>Grouping is the practice of gathering together rules which all rely on
the same action going on; it's then efficient to test the action once rather
than once for each rule.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Compile the rulebook in the given format</span> <span class="cwebmacronumber">24.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">grouping</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">group_cap</span><span class="plain"> = 0;</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">format</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">GROUPED_ARRAY_RBF</span><span class="plain">: </span><span class="identifier">grouping</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="identifier">group_cap</span><span class="plain"> = 31; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">ROUTINE_RBF</span><span class="plain">: </span><span class="identifier">grouping</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="identifier">group_cap</span><span class="plain"> = 2000000000; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">action_based</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">grouping</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">forbid_breaks_s</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">rv_s</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">original_deadflag_s</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">p_s</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save_array</span><span class="plain"> = </span><span class="functiontext">Emit::unused_packaging_state</span><span class="plain">();</span>
&lt;<span class="cwebmacro">Open the rulebook compilation</span> <span class="cwebmacronumber">24.1.1</span>&gt;<span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">group_size</span><span class="plain"> = 0, </span><span class="identifier">group_started</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">entry_count</span><span class="plain"> = 0, </span><span class="identifier">action_group_open</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">br</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">list_head</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">; </span><span class="identifier">br</span><span class="plain">; </span><span class="identifier">br</span><span class="plain"> = </span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="functiontext">Rvalues::from_rule</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;rule_being_booked</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">grouping</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">group_size</span><span class="plain"> == 0) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">group_started</span><span class="plain">) </span>&lt;<span class="cwebmacro">End an action group in the rulebook</span> <span class="cwebmacronumber">24.1.4</span>&gt;<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">action_name</span><span class="plain"> *</span><span class="identifier">an</span><span class="plain"> = </span><span class="functiontext">Rules::Bookings::br_required_action</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">);</span>
<span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">brg</span><span class="plain"> = </span><span class="identifier">br</span><span class="plain">;</span>
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">brg</span><span class="plain">) &amp;&amp; (</span><span class="identifier">an</span><span class="plain"> == </span><span class="functiontext">Rules::Bookings::br_required_action</span><span class="plain">(</span><span class="identifier">brg</span><span class="plain">))) {</span>
<span class="identifier">group_size</span><span class="plain">++;</span>
<span class="identifier">brg</span><span class="plain"> = </span><span class="identifier">brg</span><span class="plain">-</span><span class="element">&gt;next_rule</span><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="reserved">booking</span><span class="plain"> *</span><span class="identifier">brg</span><span class="plain"> = </span><span class="identifier">br</span><span class="plain">;</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">brg</span><span class="plain">) {</span>
<span class="identifier">group_size</span><span class="plain">++;</span>
<span class="identifier">brg</span><span class="plain"> = </span><span class="identifier">brg</span><span class="plain">-</span><span class="element">&gt;next_rule</span><span class="plain">;</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">group_size</span><span class="plain"> &gt; </span><span class="identifier">group_cap</span><span class="plain">) </span><span class="identifier">group_size</span><span class="plain"> = </span><span class="identifier">group_cap</span><span class="plain">;</span>
<span class="identifier">group_started</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Begin an action group in the rulebook</span> <span class="cwebmacronumber">24.1.2</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">group_size</span><span class="plain">--;</span>
<span class="plain">}</span>
&lt;<span class="cwebmacro">Compile an entry in the rulebook</span> <span class="cwebmacronumber">24.1.3</span>&gt;<span class="plain">;</span>
<span class="identifier">entry_count</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">group_started</span><span class="plain">) </span>&lt;<span class="cwebmacro">End an action group in the rulebook</span> <span class="cwebmacronumber">24.1.4</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Close the rulebook compilation</span> <span class="cwebmacronumber">24.1.5</span>&gt;<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_1_1"></a><b>&#167;24.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Open the rulebook compilation</span> <span class="cwebmacronumber">24.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">rb_symb</span><span class="plain"> = </span><span class="identifier">identifier</span><span class="plain">;</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">format</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">ARRAY_RBF</span><span class="plain">: </span><span class="identifier">save_array</span><span class="plain"> = </span><span class="functiontext">Emit::named_array_begin</span><span class="plain">(</span><span class="identifier">identifier</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">GROUPED_ARRAY_RBF</span><span class="plain">: </span><span class="identifier">save_array</span><span class="plain"> = </span><span class="functiontext">Emit::named_array_begin</span><span class="plain">(</span><span class="identifier">identifier</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">); </span><span class="functiontext">Emit::array_numeric_entry</span><span class="plain">((</span><span class="identifier">inter_t</span><span class="plain">) -2); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">ROUTINE_RBF</span><span class="plain">: {</span>
<span class="identifier">save_array</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="identifier">identifier</span><span class="plain">);</span>
<span class="identifier">forbid_breaks_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_named_call_as_symbol</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"forbid_breaks"</span><span class="plain">);</span>
<span class="identifier">rv_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_internal_local_c_as_symbol</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"rv"</span><span class="plain">, </span><span class="string">"return value"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">countup</span><span class="plain"> &gt; 1)</span>
<span class="identifier">original_deadflag_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_internal_local_c_as_symbol</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"original_deadflag"</span><span class="plain">, </span><span class="string">"saved state"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parameter_based</span><span class="plain">)</span>
<span class="identifier">p_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_internal_local_c_as_symbol</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"p"</span><span class="plain">, </span><span class="string">"rulebook parameter"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">countup</span><span class="plain"> &gt; 1) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">original_deadflag_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">DEADFLAG_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parameter_based</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">p_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">PARAMETER_VALUE_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="reserved">break</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="#SP24_1">&#167;24.1</a>.</p>
<p class="inwebparagraph"><a id="SP24_1_2"></a><b>&#167;24.1.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Begin an action group in the rulebook</span> <span class="cwebmacronumber">24.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">format</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">GROUPED_ARRAY_RBF</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">an</span><span class="plain">) </span><span class="functiontext">Emit::array_action_entry</span><span class="plain">(</span><span class="identifier">an</span><span class="plain">); </span><span class="reserved">else</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="functiontext">Emit::array_numeric_entry</span><span class="plain">((</span><span class="identifier">inter_t</span><span class="plain">) -2);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">group_size</span><span class="plain"> &gt; 1) </span><span class="functiontext">Emit::array_numeric_entry</span><span class="plain">((</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">group_size</span><span class="plain">);</span>
<span class="identifier">action_group_open</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">ROUTINE_RBF</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">an</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IFELSE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">EQ_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">ACTION_HL</span><span class="plain">));</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">PL::Actions::double_sharp</span><span class="plain">(</span><span class="identifier">an</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">action_group_open</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="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="#SP24_1">&#167;24.1</a>.</p>
<p class="inwebparagraph"><a id="SP24_1_3"></a><b>&#167;24.1.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile an entry in the rulebook</span> <span class="cwebmacronumber">24.1.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">format</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">ARRAY_RBF</span><span class="plain">:</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">GROUPED_ARRAY_RBF</span><span class="plain">:</span>
<span class="functiontext">Specifications::Compiler::emit</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">ROUTINE_RBF</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">entry_count</span><span class="plain"> &gt; 0) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">NE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">original_deadflag_s</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">DEADFLAG_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
&lt;<span class="cwebmacro">Compile an optional mid-rulebook paragraph break</span> <span class="cwebmacronumber">24.1.3.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parameter_based</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">PARAMETER_VALUE_HL</span><span class="plain">));</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">p_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">rv_s</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">INDIRECT0_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">rv_s</span><span class="plain">);</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">EQ_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">rv_s</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 2);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">REASON_THE_ACTION_FAILED_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">LOOKUPREF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">LATEST_RULE_RESULT_HL</span><span class="plain">));</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</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="#SP24_1">&#167;24.1</a>.</p>
<p class="inwebparagraph"><a id="SP24_1_4"></a><b>&#167;24.1.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">End an action group in the rulebook</span> <span class="cwebmacronumber">24.1.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">action_group_open</span><span class="plain">) {</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">format</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">ROUTINE_RBF</span><span class="plain">:</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
&lt;<span class="cwebmacro">Compile an optional mid-rulebook paragraph break</span> <span class="cwebmacronumber">24.1.3.1</span>&gt;<span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">action_group_open</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP24_1">&#167;24.1</a> (twice).</p>
<p class="inwebparagraph"><a id="SP24_1_5"></a><b>&#167;24.1.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Close the rulebook compilation</span> <span class="cwebmacronumber">24.1.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">format</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">ARRAY_RBF</span><span class="plain">:</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">GROUPED_ARRAY_RBF</span><span class="plain">:</span>
<span class="functiontext">Emit::array_null_entry</span><span class="plain">();</span>
<span class="functiontext">Emit::array_end</span><span class="plain">(</span><span class="identifier">save_array</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">ROUTINE_RBF</span><span class="plain">:</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save_array</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="#SP24_1">&#167;24.1</a>.</p>
<p class="inwebparagraph"><a id="SP24_1_3_1"></a><b>&#167;24.1.3.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile an optional mid-rulebook paragraph break</span> <span class="cwebmacronumber">24.1.3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">entry_count</span><span class="plain"> &gt; 0) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">SAY__P_HL</span><span class="plain">));</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">RULEBOOKPARBREAK_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">forbid_breaks_s</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP24_1_3">&#167;24.1.3</a>, <a href="#SP24_1_4">&#167;24.1.4</a>.</p>
<p class="inwebparagraph"><a id="SP25"></a><b>&#167;25. </b>And, finally, here's where a booking is turned into the action (if any) that
its rule requires:
</p>
<pre class="display">
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="identifier">action_name</span><span class="plain"> *</span><span class="functiontext">Rules::Bookings::br_required_action</span><span class="plain">(</span><span class="reserved">booking</span><span class="plain"> *</span><span class="identifier">br</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">Rules::get_I7_definition</span><span class="plain">(</span><span class="identifier">br</span><span class="plain">-</span><span class="element">&gt;rule_being_booked</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="reserved">return</span><span class="plain"> </span><span class="functiontext">Phrases::Context::required_action</span><span class="plain">(&amp;(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">&gt;runtime_context_data</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>
<span class="plain">#</span><span class="identifier">endif</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rules::Bookings::br_required_action is used in <a href="#SP24_1">&#167;24.1</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="21-rl.html">Back to 'Rules'</a></li><li><a href="21-rl2.html">Continue with 'Rulebooks'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>