1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 08:34:22 +03:00
inform7/docs/assertions-module/6-bl.html
2022-10-23 22:51:46 +01:00

428 lines
71 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Booking Lists</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
MathJax = {
tex: {
inlineMath: '$', '$'], ['\\(', '\\)'
},
svg: {
fontCache: 'global'
}
};
</script>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Inform.png" height=72">
</a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../indocn.html">indoc</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
<li><a href="../inrtpsn.html">inrtps</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=18> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="../../../inweb/index.html">inweb</a></li>
<li><a href="../../../intest/index.html">intest</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Booking Lists' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inform7n.html">Inform7</a></li><li><a href="index.html">assertions</a></li><li><a href="index.html#6">Chapter 6: Rules, Rulebooks and Activities</a></li><li><b>Booking Lists</b></li></ul></div>
<p class="purpose">Booking lists are linked lists of rule bookings. The content of a rulebook is a booking list.</p>
<ul class="toc"><li><a href="6-bl.html#SP1">&#167;1. Introduction</a></li><li><a href="6-bl.html#SP4">&#167;4. Creation</a></li><li><a href="6-bl.html#SP5">&#167;5. Addition</a></li><li><a href="6-bl.html#SP6">&#167;6. Removal</a></li><li><a href="6-bl.html#SP7">&#167;7. Scanning lists for their contents</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Introduction. </b>Bookings are intended to be bound together in linked lists, each of which
represents the interior pages of a single rulebook.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">booking_list</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">booking</span><span class="plain-syntax"> *</span><span class="identifier-syntax">list_head</span><span class="plain-syntax">; </span><span class="comment-syntax"> the dummy entry at the front</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">booking_list</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure booking_list is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>There are only three operations on lists: creation, addition of a booking,
and removal of a booking. The following invariants are preserved:
</p>
<ul class="items"><li>(a) The list head is a dummy, i.e., meaningless, booking which has never been
the subject of any addition operation and has never moved.
</li><li>(b) The only <span class="extract"><span class="extract-syntax">FIRST_PLACEMENT</span></span> 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><li>(c) The only <span class="extract"><span class="extract-syntax">LAST_PLACEMENT</span></span> 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><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><li>(e) The list never contains duplicates, that is, never contains two bookings
whose rules are equal, in the sense of <a href="6-rls.html#SP13" class="internal">Rules::eq</a>.
</li></ul>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>These macros are useful for iterating through the contents in sequence;
note that <span class="extract"><span class="extract-syntax">br</span></span> is never equal to the dummy head, and that <span class="extract"><span class="extract-syntax">pr</span></span> is never <span class="extract"><span class="extract-syntax">NULL</span></span> &mdash;
though it is initially equal to the dummy, which of course is the point of
having the dummy.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_OVER_BOOKINGS</span><span class="plain-syntax">(</span><span class="identifier-syntax">br</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">booking</span><span class="plain-syntax"> *</span><span class="identifier-syntax">br</span><span class="plain-syntax">=(</span><span class="identifier-syntax">L</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">list_head</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax">):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">br</span><span class="plain-syntax">; </span><span class="identifier-syntax">br</span><span class="plain-syntax">=</span><span class="identifier-syntax">br</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax">)</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_OVER_BOOKINGS_WITH_PREV</span><span class="plain-syntax">(</span><span class="identifier-syntax">br</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">booking</span><span class="plain-syntax"> *</span><span class="identifier-syntax">br</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">list_head</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax">, *</span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">list_head</span><span class="plain-syntax">; </span><span class="identifier-syntax">br</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">br</span><span class="plain-syntax">, </span><span class="identifier-syntax">br</span><span class="plain-syntax"> = </span><span class="identifier-syntax">br</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax">)</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">BookingLists::log</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">BookingLists::log</span></span>:<br/>Rule Bookings - <a href="6-rb.html#SP8_1">&#167;8.1</a><br/>Rulebooks - <a href="6-rlb.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">booking_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;null-booked-rule-list&gt;\n"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax"> = </span><a href="6-bl.html#SP7" class="function-link"><span class="function-syntax">BookingLists::length</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">t</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;empty-booked-rule-list&gt;\n"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">s</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BOOKINGS</span><span class="plain-syntax">(</span><span class="identifier-syntax">br</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" %d/%d. $b\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">s</span><span class="plain-syntax">++, </span><span class="identifier-syntax">t</span><span class="plain-syntax">, </span><span class="identifier-syntax">br</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. Creation. </b>A new list is a dummy header (see (a) above):
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">booking_list</span><span class="plain-syntax"> *</span><span class="function-syntax">BookingLists::new</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">BookingLists::new</span></span>:<br/>Rulebooks - <a href="6-rlb.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">booking_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">booking_list</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">list_head</span><span class="plain-syntax"> = </span><a href="6-rb.html#SP3" class="function-link"><span class="function-syntax">RuleBookings::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. Addition. </b>The following is called when a booking <span class="extract"><span class="extract-syntax">br</span></span> for the rule R needs to be placed
into list <span class="extract"><span class="extract-syntax">L</span></span>, which is the contents of a rulebook we will call B. This happens,
for example, in response to an an assertion like "R is listed after S in B";
in that cast the <span class="extract"><span class="extract-syntax">side</span></span> would be <span class="extract"><span class="extract-syntax">AFTER_SIDE</span></span>, and the <span class="extract"><span class="extract-syntax">ref_rule</span></span> would be S.
</p>
<p class="commentary">It is also possible to specify a <span class="extract"><span class="extract-syntax">placing</span></span>. For example, for a rule described
as "First every turn rule: ...", this would be added to the every turn rulebook
with placing <span class="extract"><span class="extract-syntax">FIRST_PLACEMENT</span></span>. There are three possible placings: see <a href="6-rb.html#SP1" class="internal">booking</a>
for what they are.
</p>
<p class="commentary">And since there are four possible sides, the following function effectively has
12 different modes to get right.
</p>
<p class="commentary">Each "addition" leaves the list either the same size or longer by 1.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">BEFORE_SIDE</span><span class="plain-syntax"> -1 </span><span class="comment-syntax"> before the reference rule</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">IN_SIDE</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax"> </span><span class="comment-syntax"> if no mention is made of where to put the new booking</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">AFTER_SIDE</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax"> </span><span class="comment-syntax"> after the reference rule</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">INSTEAD_SIDE</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax"> </span><span class="comment-syntax"> in place of the reference rule</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">BookingLists::add</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">BookingLists::add</span></span>:<br/>Rulebooks - <a href="6-rlb.html#SP13">&#167;13</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">booking_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">booking</span><span class="plain-syntax"> *</span><span class="identifier-syntax">new_br</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">placing</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">side</span><span class="plain-syntax">, </span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ref_rule</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bl.html#SP5_1" class="named-paragraph-link"><span class="named-paragraph">Make some sanity checks on the addition instructions</span><span class="named-paragraph-number">5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bl.html#SP5_2" class="named-paragraph-link"><span class="named-paragraph">Handle the case where the new rule is already in the list</span><span class="named-paragraph-number">5.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bl.html#SP5_3" class="named-paragraph-link"><span class="named-paragraph">Handle all placements made with the INSTEAD side</span><span class="named-paragraph-number">5.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bl.html#SP5_4" class="named-paragraph-link"><span class="named-paragraph">Handle all placements made with the FIRST placement</span><span class="named-paragraph-number">5.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bl.html#SP5_5" class="named-paragraph-link"><span class="named-paragraph">Handle all placements made with the LAST placement</span><span class="named-paragraph-number">5.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bl.html#SP5_6" class="named-paragraph-link"><span class="named-paragraph">Handle what's left: MIDDLE placements on the IN, BEFORE or AFTER sides</span><span class="named-paragraph-number">5.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5_1" class="paragraph-anchor"></a><b>&#167;5.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Make some sanity checks on the addition instructions</span><span class="named-paragraph-number">5.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">side</span><span class="plain-syntax"> != </span><span class="constant-syntax">IN_SIDE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ref_rule</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to add before or after or instead of non-rule"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">side</span><span class="plain-syntax"> == </span><span class="constant-syntax">IN_SIDE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ref_rule</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to add in middle but with ref rule"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">side</span><span class="plain-syntax"> != </span><span class="constant-syntax">IN_SIDE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">placing</span><span class="plain-syntax"> != </span><span class="constant-syntax">MIDDLE_PLACEMENT</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to add before or after but with non-middle placement"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to add rule to null list"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">placing</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">MIDDLE_PLACEMENT:</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">FIRST_PLACEMENT:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">RULE_ATTACHMENTS</span><span class="plain-syntax">, </span><span class="string-syntax">"Placed first\n"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LAST_PLACEMENT:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">RULE_ATTACHMENTS</span><span class="plain-syntax">, </span><span class="string-syntax">"Placed last\n"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"invalid placing of rule"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-bl.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2" class="paragraph-anchor"></a><b>&#167;5.2. </b>If R is already in B, the assertion may still have an effect.
</p>
<p class="commentary">If our instructions specify no particular position for R to take, we return
because nothing need be done: the rule's there already, so be happy. Otherwise,
we remove R's existing booking in order that it can be rebooked in a new position.
</p>
<p class="commentary">This is a change in semantics from the original Inform 7 design for rulebooks,
under which a rule could be booked multiple times in the same rulebook &mdash; which
was then called "duplication". Following debate on the Usenet newsgroup
<span class="extract"><span class="extract-syntax">rec.arts.int-fiction</span></span> in February and March 2009, it was decided to abolish
duplication in favour of the clean principle that a rule can only be in a
single rulebook once. This makes it easier to place rules with tricky preambles,
though there were arguments on both sides.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Handle the case where the new rule is already in the list</span><span class="named-paragraph-number">5.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BOOKINGS_WITH_PREV</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">prev</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="6-rls.html#SP13" class="function-link"><span class="function-syntax">Rules::eq</span></a><span class="plain-syntax">(</span><a href="6-rb.html#SP4" class="function-link"><span class="function-syntax">RuleBookings::get_rule</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">), </span><a href="6-rb.html#SP4" class="function-link"><span class="function-syntax">RuleBookings::get_rule</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new_br</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">side</span><span class="plain-syntax"> == </span><span class="constant-syntax">IN_SIDE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">placing</span><span class="plain-syntax"> == </span><span class="constant-syntax">MIDDLE_PLACEMENT</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pos</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pos</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">RULE_ATTACHMENTS</span><span class="plain-syntax">, </span><span class="string-syntax">"Removing previous entry from rulebook\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> rule can only appear once, so no need to keep checking</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-bl.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_3" class="paragraph-anchor"></a><b>&#167;5.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Handle all placements made with the INSTEAD side</span><span class="named-paragraph-number">5.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">side</span><span class="plain-syntax"> == </span><span class="constant-syntax">INSTEAD_SIDE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BOOKINGS_WITH_PREV</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">prev</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="6-rls.html#SP13" class="function-link"><span class="function-syntax">Rules::eq</span></a><span class="plain-syntax">(</span><a href="6-rb.html#SP4" class="function-link"><span class="function-syntax">RuleBookings::get_rule</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">), </span><span class="identifier-syntax">ref_rule</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_br</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">placement</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pos</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">placement</span><span class="plain-syntax">; </span><span class="comment-syntax"> replace with same placement</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_br</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pos</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_br</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-bl.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_4" class="paragraph-anchor"></a><b>&#167;5.4. </b>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
having <span class="extract"><span class="extract-syntax">FIRST_PLACEMENT</span></span>, so that subsequent rule insertions of middle-placed rules
will still go after both of them.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Handle all placements made with the FIRST placement</span><span class="named-paragraph-number">5.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">placing</span><span class="plain-syntax"> == </span><span class="constant-syntax">FIRST_PLACEMENT</span><span class="plain-syntax">) { </span><span class="comment-syntax"> first in valid interval (must be whole list)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">booking</span><span class="plain-syntax"> *</span><span class="identifier-syntax">previously_first</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">list_head</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">list_head</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_br</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_br</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax"> = </span><span class="identifier-syntax">previously_first</span><span class="plain-syntax">; </span><span class="comment-syntax"> pushes any existing first rule forward</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_br</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">placement</span><span class="plain-syntax"> = </span><span class="identifier-syntax">placing</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-bl.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_5" class="paragraph-anchor"></a><b>&#167;5.5. </b>Symmetrically, a second last-placed rule is inserted after any existing one, but
both are labelled as having <span class="extract"><span class="extract-syntax">LAST_PLACEMENT</span></span>.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Handle all placements made with the LAST placement</span><span class="named-paragraph-number">5.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">placing</span><span class="plain-syntax"> == </span><span class="constant-syntax">LAST_PLACEMENT</span><span class="plain-syntax">) { </span><span class="comment-syntax"> last in valid interval (must be whole list)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">booking</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">list_head</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">prev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_br</span><span class="plain-syntax">; </span><span class="comment-syntax"> pushes any existing last rule backward</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_br</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_br</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">placement</span><span class="plain-syntax"> = </span><span class="identifier-syntax">placing</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-bl.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6" class="paragraph-anchor"></a><b>&#167;5.6. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Handle what's left: MIDDLE placements on the IN, BEFORE or AFTER sides</span><span class="named-paragraph-number">5.6</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">booking</span><span class="plain-syntax"> *</span><span class="identifier-syntax">start_rule</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">list_head</span><span class="plain-syntax">; </span><span class="comment-syntax"> valid interval begins after this rule</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">booking</span><span class="plain-syntax"> *</span><span class="identifier-syntax">end_rule</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> valid interval ends before this rule, or runs to end if </span><span class="extract"><span class="extract-syntax">NULL</span></span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bl.html#SP5_6_1" class="named-paragraph-link"><span class="named-paragraph">Adjust the valid interval to take care of BEFORE and AFTER side requirements</span><span class="named-paragraph-number">5.6.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bl.html#SP5_6_2" class="named-paragraph-link"><span class="named-paragraph">Check that the valid interval is indeed as advertised</span><span class="named-paragraph-number">5.6.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">booking</span><span class="plain-syntax"> *</span><span class="identifier-syntax">insert_after</span><span class="plain-syntax"> = </span><span class="identifier-syntax">start_rule</span><span class="plain-syntax">; </span><span class="comment-syntax"> insertion point is after this</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bl.html#SP5_6_3" class="named-paragraph-link"><span class="named-paragraph">Find insertion point, keeping the valid interval in specificity order</span><span class="named-paragraph-number">5.6.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">booking</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subseq</span><span class="plain-syntax"> = </span><span class="identifier-syntax">insert_after</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">insert_after</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_br</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_br</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax"> = </span><span class="identifier-syntax">subseq</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-bl.html#SP5_6_4" class="named-paragraph-link"><span class="named-paragraph">Set the placement for the new rule booking</span><span class="named-paragraph-number">5.6.4</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-bl.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_1" class="paragraph-anchor"></a><b>&#167;5.6.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Adjust the valid interval to take care of BEFORE and AFTER side requirements</span><span class="named-paragraph-number">5.6.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">side</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">BEFORE_SIDE:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BOOKINGS</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="6-rls.html#SP13" class="function-link"><span class="function-syntax">Rules::eq</span></a><span class="plain-syntax">(</span><a href="6-rb.html#SP4" class="function-link"><span class="function-syntax">RuleBookings::get_rule</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">), </span><span class="identifier-syntax">ref_rule</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">end_rule</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pos</span><span class="plain-syntax">; </span><span class="comment-syntax"> insert before: so valid interval ends here</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">end_rule</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"can't find end rule"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">AFTER_SIDE:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BOOKINGS</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="6-rls.html#SP13" class="function-link"><span class="function-syntax">Rules::eq</span></a><span class="plain-syntax">(</span><a href="6-rb.html#SP4" class="function-link"><span class="function-syntax">RuleBookings::get_rule</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">), </span><span class="identifier-syntax">ref_rule</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">start_rule</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pos</span><span class="plain-syntax">; </span><span class="comment-syntax"> insert after: so valid interval begins here</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">start_rule</span><span class="plain-syntax"> == </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">list_head</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"can't find start rule"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-bl.html#SP5_6">&#167;5.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_2" class="paragraph-anchor"></a><b>&#167;5.6.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check that the valid interval is indeed as advertised</span><span class="named-paragraph-number">5.6.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">t</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">end_rule</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">t</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">booking</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pos</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pos</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">list_head</span><span class="plain-syntax">; </span><span class="identifier-syntax">pos</span><span class="plain-syntax">; </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pos</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pos</span><span class="plain-syntax"> == </span><span class="identifier-syntax">start_rule</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pos</span><span class="plain-syntax"> == </span><span class="identifier-syntax">end_rule</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">)) </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> != </span><span class="identifier-syntax">t</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"valid rule interval isn't"</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-bl.html#SP5_6">&#167;5.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_3" class="paragraph-anchor"></a><b>&#167;5.6.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Find insertion point, keeping the valid interval in specificity order</span><span class="named-paragraph-number">5.6.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">log</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Log::aspect_switched_on</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPECIFICITIES_DA</span><span class="plain-syntax">)) </span><span class="identifier-syntax">log</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> move forward to final valid first rule (if any exist)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">insert_after</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax"> != </span><span class="identifier-syntax">end_rule</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> &amp;&amp; (</span><span class="identifier-syntax">insert_after</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">placement</span><span class="plain-syntax"> == </span><span class="constant-syntax">FIRST_PLACEMENT</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">insert_after</span><span class="plain-syntax"> = </span><span class="identifier-syntax">insert_after</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> move forward past other middle rules if they are not less specific</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">insert_after</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax"> != </span><span class="identifier-syntax">end_rule</span><span class="plain-syntax">) </span><span class="comment-syntax"> stop before </span>\(p\)<span class="comment-syntax"> leaves valid range</span>
<span class="plain-syntax"> &amp;&amp; (</span><span class="identifier-syntax">insert_after</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">placement</span><span class="plain-syntax"> != </span><span class="constant-syntax">LAST_PLACEMENT</span><span class="plain-syntax">) </span><span class="comment-syntax"> or reaches a last rule</span>
<span class="plain-syntax"> &amp;&amp; (</span><a href="6-rb.html#SP7" class="function-link"><span class="function-syntax">RuleBookings::cmp</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">insert_after</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax">, </span><span class="identifier-syntax">new_br</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">log</span><span class="plain-syntax">) &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="comment-syntax"> or a rule less specific than the new one</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">insert_after</span><span class="plain-syntax"> = </span><span class="identifier-syntax">insert_after</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-bl.html#SP5_6">&#167;5.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_6_4" class="paragraph-anchor"></a><b>&#167;5.6.4. </b>Since this part of the algorithm is used only when we've requested MIDDLE
placement, it might seem that <span class="extract"><span class="extract-syntax">new_br-&gt;placement</span></span> 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="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Set the placement for the new rule booking</span><span class="named-paragraph-number">5.6.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">new_br</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">placement</span><span class="plain-syntax"> = </span><span class="constant-syntax">MIDDLE_PLACEMENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">insert_after</span><span class="plain-syntax"> != </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">list_head</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">insert_after</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">placement</span><span class="plain-syntax"> == </span><span class="constant-syntax">LAST_PLACEMENT</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_br</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">placement</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="constant-syntax">LAST_PLACEMENT</span><span class="plain-syntax">; </span><span class="comment-syntax"> happens if valid interval is after a last rule</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">subseq</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">subseq</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">placement</span><span class="plain-syntax"> == </span><span class="constant-syntax">FIRST_PLACEMENT</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_br</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">placement</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="constant-syntax">FIRST_PLACEMENT</span><span class="plain-syntax">; </span><span class="comment-syntax"> happens if valid interval is before a first rule</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-bl.html#SP5_6">&#167;5.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. Removal. </b>This is much simpler, since it doesn't disturb the ordering:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">BookingLists::remove</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">BookingLists::remove</span></span>:<br/>Rulebooks - <a href="6-rlb.html#SP14">&#167;14</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">booking_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BOOKINGS_WITH_PREV</span><span class="plain-syntax">(</span><span class="identifier-syntax">br</span><span class="plain-syntax">, </span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="6-rls.html#SP13" class="function-link"><span class="function-syntax">Rules::eq</span></a><span class="plain-syntax">(</span><a href="6-rb.html#SP4" class="function-link"><span class="function-syntax">RuleBookings::get_rule</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">br</span><span class="plain-syntax">), </span><span class="identifier-syntax">R</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax"> = </span><span class="identifier-syntax">br</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_booking</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. Scanning lists for their contents. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">BookingLists::length</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">BookingLists::length</span></span>:<br/><a href="6-bl.html#SP3">&#167;3</a><br/>Rulebooks - <a href="6-rlb.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">booking_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BOOKINGS</span><span class="plain-syntax">(</span><span class="identifier-syntax">br</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">) </span><span class="identifier-syntax">n</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">booking</span><span class="plain-syntax"> *</span><span class="function-syntax">BookingLists::first</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">BookingLists::first</span></span>:<br/>Rulebooks - <a href="6-rlb.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">booking_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BOOKINGS</span><span class="plain-syntax">(</span><span class="identifier-syntax">br</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">br</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">BookingLists::is_empty_of_i7_rules</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">BookingLists::is_empty_of_i7_rules</span></span>:<br/>Rulebooks - <a href="6-rlb.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">booking_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BOOKINGS</span><span class="plain-syntax">(</span><span class="identifier-syntax">br</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="6-rls.html#SP9" class="function-link"><span class="function-syntax">Rules::get_imperative_definition</span></a><span class="plain-syntax">(</span><a href="6-rb.html#SP4" class="function-link"><span class="function-syntax">RuleBookings::get_rule</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">br</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">BookingLists::contains</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">BookingLists::contains</span></span>:<br/>Rulebooks - <a href="6-rlb.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">booking_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to_find</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BOOKINGS</span><span class="plain-syntax">(</span><span class="identifier-syntax">br</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="6-rls.html#SP13" class="function-link"><span class="function-syntax">Rules::eq</span></a><span class="plain-syntax">(</span><a href="6-rb.html#SP4" class="function-link"><span class="function-syntax">RuleBookings::get_rule</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">br</span><span class="plain-syntax">), </span><span class="identifier-syntax">to_find</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">BookingLists::contains_ph</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">BookingLists::contains_ph</span></span>:<br/>Rulebooks - <a href="6-rlb.html#SP2_3">&#167;2.3</a><br/>Focus and Outcome - <a href="6-fao.html#SP5">&#167;5</a>, <a href="6-fao.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">booking_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">id_body</span><span class="plain-syntax"> *</span><span class="identifier-syntax">idb_to_find</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BOOKINGS</span><span class="plain-syntax">(</span><span class="identifier-syntax">br</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">imperative_defn</span><span class="plain-syntax"> *</span><span class="identifier-syntax">id</span><span class="plain-syntax"> = </span><a href="6-rls.html#SP9" class="function-link"><span class="function-syntax">Rules::get_imperative_definition</span></a><span class="plain-syntax">(</span><a href="6-rb.html#SP4" class="function-link"><span class="function-syntax">RuleBookings::get_rule</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">br</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">id</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">id</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">body_of_defn</span><span class="plain-syntax"> == </span><span class="identifier-syntax">idb_to_find</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="6-rb.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-am.html">1</a></li><li class="progresschapter"><a href="2-bv.html">2</a></li><li class="progresschapter"><a href="3-dlr.html">3</a></li><li class="progresschapter"><a href="4-nr.html">4</a></li><li class="progresschapter"><a href="5-id.html">5</a></li><li class="progresscurrentchapter">6</li><li class="progresssection"><a href="6-rls.html">rls</a></li><li class="progresssection"><a href="6-rb.html">rb</a></li><li class="progresscurrent">bl</li><li class="progresssection"><a href="6-rlb.html">rlb</a></li><li class="progresssection"><a href="6-fao.html">fao</a></li><li class="progresssection"><a href="6-act.html">act</a></li><li class="progresssection"><a href="6-sv.html">sv</a></li><li class="progresschapter"><a href="7-tc.html">7</a></li><li class="progresschapter"><a href="8-kpr.html">8</a></li><li class="progressnext"><a href="6-rlb.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>