mirror of
https://github.com/ganelson/inform.git
synced 2024-07-05 16:44:21 +03:00
1399 lines
176 KiB
HTML
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">★</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">§1. Definitions</a></li><li><a href="#SP4">§4. Creation</a></li><li><a href="#SP7">§7. Automatic placement into rulebooks</a></li><li><a href="#SP10">§10. Specificity of bookings</a></li><li><a href="#SP11">§11. Lists of bookings</a></li><li><a href="#SP16">§16. Logging lists</a></li><li><a href="#SP17">§17. Scanning lists for their contents</a></li><li><a href="#SP18">§18. Indexing of lists</a></li><li><a href="#SP21">§21. Calculating the specificities</a></li><li><a href="#SP22">§22. Compilation of rule definitions for rulebook</a></li><li><a href="#SP23">§23. Compilation of I6-format rulebook</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. Definitions. </b></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP2"></a><b>§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>§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>§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">>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">>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">>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">>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">>next_rule_specificity</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">br</span><span class="plain">-</span><span class="element">>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">>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">§12</a>, 21/rl (<a href="21-rl.html#SP17">§17</a>), 21/rps (<a href="21-rps.html#SP18">§18</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§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:<null-booked-rule>"</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">-></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">>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">>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">§5</a>, <a href="1-cm.html#SP6_6">§6.6</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§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">>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">§9</a>, <a href="#SP14_2">§14.2</a>, <a href="#SP14_3">§14.3</a>, <a href="#SP14_6_1">§14.6.1</a>, <a href="#SP15">§15</a>, <a href="#SP17">§17</a>, 21/rl2 (<a href="21-rl2.html#SP19">§19</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§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">>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">§17</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§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">>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">>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">>declaration_node</span><span class="plain">;</span>
|
|
<span class="functiontext">Rules::Bookings::place</span><span class="plain">(&(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">>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">>rule_being_booked</span><span class="plain">,</span>
|
|
<span class="functiontext">Phrases::Usage::get_rulebook</span><span class="plain">(&(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">>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">§8</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9"></a><b>§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">) && (</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">, &</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">) && (</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">§8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10"></a><b>§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">>rule_being_booked</span><span class="plain">, </span><span class="identifier">br2</span><span class="plain">-</span><span class="element">>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">§14.6.3</a>, <a href="#SP21_2">§21.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11"></a><b>§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>§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">§10</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP13"></a><b>§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>§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>
|
|
<<span class="cwebmacro">Make some sanity checks on the addition instructions</span> <span class="cwebmacronumber">14.1</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Handle the case where the new rule is already in the list</span> <span class="cwebmacronumber">14.2</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Handle all placements made with the INSTEAD side</span> <span class="cwebmacronumber">14.3</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Handle all placements made with the FIRST placement</span> <span class="cwebmacronumber">14.4</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Handle all placements made with the LAST placement</span> <span class="cwebmacronumber">14.5</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Handle what's left: MIDDLE placements on the IN, BEFORE or AFTER sides</span> <span class="cwebmacronumber">14.6</span>><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">§19</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14_1"></a><b>§14.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Make some sanity checks on the addition instructions</span> <span class="cwebmacronumber">14.1</span>> =
|
|
</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">) && (</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">) && (</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">) && (</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">§14</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14_2"></a><b>§14.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Handle the case where the new rule is already in the list</span> <span class="cwebmacronumber">14.2</span>> =
|
|
</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">>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">>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">) && (</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">>next_rule</span><span class="plain"> = </span><span class="identifier">pos</span><span class="plain">-</span><span class="element">>next_rule</span><span class="plain">;</span>
|
|
<span class="identifier">pos</span><span class="plain">-</span><span class="element">>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">§14</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14_3"></a><b>§14.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Handle all placements made with the INSTEAD side</span> <span class="cwebmacronumber">14.3</span>> =
|
|
</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">>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">>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">>placement</span><span class="plain"> = </span><span class="identifier">pos</span><span class="plain">-</span><span class="element">>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">>next_rule</span><span class="plain"> = </span><span class="identifier">pos</span><span class="plain">-</span><span class="element">>next_rule</span><span class="plain">;</span>
|
|
<span class="identifier">prev</span><span class="plain">-</span><span class="element">>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">§14</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14_4"></a><b>§14.4. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Handle all placements made with the FIRST placement</span> <span class="cwebmacronumber">14.4</span>> =
|
|
</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">>next_rule</span><span class="plain">;</span>
|
|
<span class="identifier">list_head</span><span class="plain">-</span><span class="element">>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">>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">>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">§14</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14_5"></a><b>§14.5. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Handle all placements made with the LAST placement</span> <span class="cwebmacronumber">14.5</span>> =
|
|
</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">>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">>next_rule</span><span class="plain">;</span>
|
|
<span class="identifier">prev</span><span class="plain">-</span><span class="element">>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">>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">>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">§14</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14_6"></a><b>§14.6. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Handle what's left: MIDDLE placements on the IN, BEFORE or AFTER sides</span> <span class="cwebmacronumber">14.6</span>> =
|
|
</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>
|
|
<<span class="cwebmacro">Adjust the valid interval to take care of BEFORE and AFTER side requirements</span> <span class="cwebmacronumber">14.6.1</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Check that the valid interval is indeed as advertised</span> <span class="cwebmacronumber">14.6.2</span>><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>
|
|
<<span class="cwebmacro">Find insertion point, keeping the valid interval in specificity order</span> <span class="cwebmacronumber">14.6.3</span>><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">>next_rule</span><span class="plain">;</span>
|
|
<span class="identifier">insert_after</span><span class="plain">-</span><span class="element">>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">>next_rule</span><span class="plain"> = </span><span class="identifier">subseq</span><span class="plain">;</span>
|
|
<<span class="cwebmacro">Set the placement for the new rule booking</span> <span class="cwebmacronumber">14.6.4</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP14">§14</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14_6_1"></a><b>§14.6.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Adjust the valid interval to take care of BEFORE and AFTER side requirements</span> <span class="cwebmacronumber">14.6.1</span>> =
|
|
</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">>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">>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">>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">>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">§14.6</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14_6_2"></a><b>§14.6.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Check that the valid interval is indeed as advertised</span> <span class="cwebmacronumber">14.6.2</span>> =
|
|
</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">>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">) && (</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">) && (</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">§14.6</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14_6_3"></a><b>§14.6.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Find insertion point, keeping the valid interval in specificity order</span> <span class="cwebmacronumber">14.6.3</span>> =
|
|
</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">>next_rule</span><span class="plain"> != </span><span class="identifier">end_rule</span><span class="plain">)</span>
|
|
<span class="plain">&& (</span><span class="identifier">insert_after</span><span class="plain">-</span><span class="element">>next_rule</span><span class="plain">-</span><span class="element">>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">>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">>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">&& (</span><span class="identifier">insert_after</span><span class="plain">-</span><span class="element">>next_rule</span><span class="plain">-</span><span class="element">>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">&& (</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">>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">) >= 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">>next_rule</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP14_6">§14.6</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14_6_4"></a><b>§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->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">
|
|
<<span class="cwebmacrodefn">Set the placement for the new rule booking</span> <span class="cwebmacronumber">14.6.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">new_rule</span><span class="plain">-</span><span class="element">>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">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">insert_after</span><span class="plain">-</span><span class="element">>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">>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">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">subseq</span><span class="plain">-</span><span class="element">>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">>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">§14.6</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15"></a><b>§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">>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">>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">>next_rule</span><span class="plain"> = </span><span class="identifier">br</span><span class="plain">-</span><span class="element">>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">§19</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP16"></a><b>§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">"<null-booked-rule-list>\</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">"<empty-booked-rule-list>\</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">>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">>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">§21.1</a>, 21/rl2 (<a href="21-rl2.html#SP15">§15</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP17"></a><b>§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">>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">>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">>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">>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">>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">>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">>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">>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">>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">>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">>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">>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">>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">§16</a>, <a href="#SP22">§22</a>, <a href="#SP24">§24</a>, 21/rl2 (<a href="21-rl2.html#SP12">§12</a>).</p>
|
|
|
|
<p class="endnote">The function Rules::Bookings::list_is_empty is used in 21/rl2 (<a href="21-rl2.html#SP12">§12</a>, <a href="21-rl2.html#SP15">§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">§20</a>).</p>
|
|
|
|
<p class="endnote">The function Rules::Bookings::list_contains is used in 21/rl2 (<a href="21-rl2.html#SP12">§12</a>).</p>
|
|
|
|
<p class="endnote">The function Rules::Bookings::list_contains_ph is used in 21/rl2 (<a href="21-rl2.html#SP22">§22</a>), 21/fao (<a href="21-fao.html#SP10">§10</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP18"></a><b>§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">>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">>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">>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"> = &(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">>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">) && (</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">) &&</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">§15</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP19"></a><b>§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]) && (</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">"&nbsp;&nbsp;&nbsp;&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) && (</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">§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">§15</a>).</p>
|
|
|
|
<p class="endnote">The function Rules::Bookings::br_start_index_line is used in <a href="#SP18">§18</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20"></a><b>§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">>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">>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">>next_rule_specificity_law</span><span class="plain">,</span>
|
|
<span class="identifier">prev</span><span class="plain">-</span><span class="element">>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">§19</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP21"></a><b>§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">>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">>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">>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">>placement</span><span class="plain"> != </span><span class="identifier">br</span><span class="plain">-</span><span class="element">>next_rule</span><span class="plain">-</span><span class="element">>placement</span><span class="plain">)</span>
|
|
<<span class="cwebmacro">Calculate specificities when placements differ</span> <span class="cwebmacronumber">21.1</span>>
|
|
<span class="reserved">else</span>
|
|
<<span class="cwebmacro">Calculate specificities when placements are the same</span> <span class="cwebmacronumber">21.2</span>><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">>next_rule_specificity</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">br</span><span class="plain">-</span><span class="element">>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">§20</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP21_1"></a><b>§21.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Calculate specificities when placements differ</span> <span class="cwebmacronumber">21.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">br</span><span class="plain">-</span><span class="element">>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">>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">>next_rule</span><span class="plain">-</span><span class="element">>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">>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">>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">>next_rule</span><span class="plain">-</span><span class="element">>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">>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">§21</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP21_2"></a><b>§21.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Calculate specificities when placements are the same</span> <span class="cwebmacronumber">21.2</span>> =
|
|
</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">>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">>next_rule_specificity</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">br</span><span class="plain">-</span><span class="element">>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">>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">>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">>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">>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">>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">>next_rule_specificity</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">br</span><span class="plain">-</span><span class="element">>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">§21</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP22"></a><b>§22. Compilation of rule definitions for rulebook. </b>There's no real need to do it this way — 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">>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">>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">>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">>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">>placement</span><span class="plain"> != </span><span class="identifier">br</span><span class="plain">-</span><span class="element">>next_rule</span><span class="plain">-</span><span class="element">>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">>next_rule</span><span class="plain">-</span><span class="element">>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">>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">>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">" <<< %s <<<"</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">" >>> %s >>>"</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">§20</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP23"></a><b>§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">§20</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24"></a><b>§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>
|
|
|
|
<<span class="cwebmacro">Compile the rulebook in the given format</span> <span class="cwebmacronumber">24.1</span>><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">§20</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24_1"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Compile the rulebook in the given format</span> <span class="cwebmacronumber">24.1</span>> =
|
|
</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>
|
|
|
|
<<span class="cwebmacro">Open the rulebook compilation</span> <span class="cwebmacronumber">24.1.1</span>><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">>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">>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">>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><<span class="cwebmacro">End an action group in the rulebook</span> <span class="cwebmacronumber">24.1.4</span>><span class="plain">;</span>
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
|
|
<span class="identifier">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">) && (</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">>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">>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"> > </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>
|
|
<<span class="cwebmacro">Begin an action group in the rulebook</span> <span class="cwebmacronumber">24.1.2</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">group_size</span><span class="plain">--;</span>
|
|
<span class="plain">}</span>
|
|
<<span class="cwebmacro">Compile an entry in the rulebook</span> <span class="cwebmacronumber">24.1.3</span>><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><<span class="cwebmacro">End an action group in the rulebook</span> <span class="cwebmacronumber">24.1.4</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Close the rulebook compilation</span> <span class="cwebmacronumber">24.1.5</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP24">§24</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24_1_1"></a><b>§24.1.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Open the rulebook compilation</span> <span class="cwebmacronumber">24.1.1</span>> =
|
|
</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"> > 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"> > 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">§24.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24_1_2"></a><b>§24.1.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Begin an action group in the rulebook</span> <span class="cwebmacronumber">24.1.2</span>> =
|
|
</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"> > 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">§24.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24_1_3"></a><b>§24.1.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Compile an entry in the rulebook</span> <span class="cwebmacronumber">24.1.3</span>> =
|
|
</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"> > 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>
|
|
<<span class="cwebmacro">Compile an optional mid-rulebook paragraph break</span> <span class="cwebmacronumber">24.1.3.1</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_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">§24.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24_1_4"></a><b>§24.1.4. </b><code class="display">
|
|
<<span class="cwebmacrodefn">End an action group in the rulebook</span> <span class="cwebmacronumber">24.1.4</span>> =
|
|
</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>
|
|
<<span class="cwebmacro">Compile an optional mid-rulebook paragraph break</span> <span class="cwebmacronumber">24.1.3.1</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="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">§24.1</a> (twice).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24_1_5"></a><b>§24.1.5. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Close the rulebook compilation</span> <span class="cwebmacronumber">24.1.5</span>> =
|
|
</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">§24.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24_1_3_1"></a><b>§24.1.3.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Compile an optional mid-rulebook paragraph break</span> <span class="cwebmacronumber">24.1.3.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">entry_count</span><span class="plain"> > 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">§24.1.3</a>, <a href="#SP24_1_4">§24.1.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP25"></a><b>§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">>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">(&(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">>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">§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>
|
|
|