1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 08:34:22 +03:00
inform7/docs/imperative-module/2-map.html

1303 lines
212 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Matching Action Patterns</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">
<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>
</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 'Matching Action Patterns' 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">imperative</a></li><li><a href="index.html#2">Chapter 2: Values</a></li><li><b>Matching Action Patterns</b></li></ul></div>
<p class="purpose">Testing whether the current action matches an action pattern means compiling a complicated multi-clause condition, which is what this section does.</p>
<ul class="toc"><li><a href="2-map.html#SP1">&#167;1. API</a></li><li><a href="2-map.html#SP2">&#167;2. Compile-Pattern-Match-Clauses</a></li><li><a href="2-map.html#SP3">&#167;3. Matching</a></li><li><a href="2-map.html#SP3_3_1">&#167;3.3.1. In actor-considering mode only</a></li><li><a href="2-map.html#SP3_3_2">&#167;3.3.2. In both modes</a></li><li><a href="2-map.html#SP3_4">&#167;3.4. Compiling the tests</a></li><li><a href="2-map.html#SP3_5_1_1_1_1">&#167;3.5.1.1.1.1. The ACTOR range of CPMCs</a></li><li><a href="2-map.html#SP3_5_1_1_1_6">&#167;3.5.1.1.1.6. The ACTION range of CPMCs</a></li><li><a href="2-map.html#SP3_5_1_1_1_7">&#167;3.5.1.1.1.7. The DETAILS range of CPMCs</a></li><li><a href="2-map.html#SP3_5_1_1_1_24">&#167;3.5.1.1.1.24. The WHEN range of CPMCs</a></li><li><a href="2-map.html#SP4">&#167;4. Matching variables</a></li><li><a href="2-map.html#SP5">&#167;5. Matching values</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. API. </b>We provide two functions to the rest of Inform. "Actorless" mode is the
one less used: it means that we should not make assumptions about who the
actor is in cases where no actor is specified. See below.
</p>
<p class="commentary">The <span class="extract"><span class="extract-syntax">:actions</span></span> test group may be useful here.
</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">RTActionPatterns::compile_pattern_match</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">RTActionPatterns::compile_pattern_match</span></span>:<br/>Compile Rvalues - <a href="2-cr.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">action_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ap</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="2-map.html#SP3" class="function-link"><span class="function-syntax">RTActionPatterns::compile_pattern_match_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ap</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">void</span><span class="plain-syntax"> </span><span class="function-syntax">RTActionPatterns::compile_pattern_match_actorless</span><span class="plain-syntax">(</span><span class="identifier-syntax">action_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ap</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="2-map.html#SP3" class="function-link"><span class="function-syntax">RTActionPatterns::compile_pattern_match_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. Compile-Pattern-Match-Clauses. </b>Matching a typical action pattern involves testing several different things:
for example, "going from the Casino in the presence of Le Chiffre" means
testing that the action is "going", that the origin is the Casino, and that
Le Chiffre is there &mdash; three CPMC clauses.
</p>
<p class="commentary">The basic roster of CPMC clauses is here, but features can add more. In
particular, see <a href="2-mgap.html" class="internal">Matching Going Action Patterns</a>.
</p>
<p class="commentary">Do not rearrange this without first reading the code below: the ordering is
very significant. The CPMCs are grouped into "ranges", and it is intentional
that those ranges are numbered 0, 1, 3, 2; we need the additional CPMCs from
features to fall into range 2.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">ACTOR_CPMCRANGE</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">ACTOR_IS_PLAYER_CPMC</span><span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">ACTOR_IS_NOT_PLAYER_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">REQUESTER_EXISTS_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">REQUESTER_DOES_NOT_EXIST_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">ACTOR_MATCHES_CPMC</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">ACTION_CPMCRANGE</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">ACTION_MATCHES_CPMC</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">WHEN_CPMCRANGE</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">SET_SELF_TO_ACTOR_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">WHEN_CONDITION_HOLDS_CPMC</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">DETAILS_CPMCRANGE</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">NOUN_EXISTS_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">NOUN_IS_INP1_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">SECOND_EXISTS_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">SECOND_IS_INP2_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">NOUN_MATCHES_AS_OBJECT_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">NOUN_MATCHES_AS_VALUE_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">SECOND_MATCHES_AS_OBJECT_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">SECOND_MATCHES_AS_VALUE_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">PLAYER_LOCATION_MATCHES_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">ACTOR_IS_SOMEWHERE_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">ACTOR_LOCATION_MATCHES_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">PARAMETER_MATCHES_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">OPTIONAL_CLAUSE_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">PRESENCE_OF_MATCHES_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">PRESENCE_OF_IN_SCOPE_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">LOOP_OVER_SCOPE_CALLING_CPMC</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">LOOP_OVER_SCOPE_NOT_CALLING_CPMC</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. Matching. </b>When a pattern is written in a way which refers to the past &mdash; "if we are examining
the table for the third time", say &mdash; we divert to the past-tense code, though
in fact the underlying pattern &mdash; "examining the table" &mdash; will eventually come
back here, shorn of its <span class="extract"><span class="extract-syntax">duration</span></span> marker. Anyway, we get rid of that case first.
</p>
<p class="commentary">The strategy is to work out a list of clauses needed, and then compile them.
</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">RTActionPatterns::compile_pattern_match_inner</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">RTActionPatterns::compile_pattern_match_inner</span></span>:<br/><a href="2-map.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">action_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ap</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">actorless</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">ap</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</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">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">ACTION_PATTERN_COMPILATION</span><span class="plain-syntax">, </span><span class="string-syntax">"Compiling action pattern:\n $A\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">ap</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">ap</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">duration</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">ACTION_PATTERN_COMPILATION</span><span class="plain-syntax">, </span><span class="string-syntax">"As past action\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Chronology::compile_action_history_condition</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">duration</span><span class="plain-syntax">, *</span><span class="identifier-syntax">ap</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</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">cpm_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">needed</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_CPM_CLAUSES</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ap_clause</span><span class="plain-syntax"> *</span><span class="identifier-syntax">needed_apoc</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_CPM_CLAUSES</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_of_noun</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_of_second</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_1" class="named-paragraph-link"><span class="named-paragraph">Work out the kind of the noun and second noun</span><span class="named-paragraph-number">3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_3" class="named-paragraph-link"><span class="named-paragraph">Work out what clauses will be needed</span><span class="named-paragraph-number">3.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5" class="named-paragraph-link"><span class="named-paragraph">Compile the condition from these instructions</span><span class="named-paragraph-number">3.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3_1" class="paragraph-anchor"></a><b>&#167;3.1. </b>We can infer the kind which the noun or second noun would need to have
from the action. For example, "dropping something" implies that the "something"
is an object; but "setting the combination to something" might imply that
"something" is a number. (We look at the first action in the list because lists
are not allowed to mix actions with different kinds; so the answer would be
the same for any of the actions in the list.)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Work out the kind of the noun and second noun</span><span class="named-paragraph-number">3.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="identifier-syntax">anl_item</span><span class="plain-syntax"> *</span><span class="identifier-syntax">item</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ActionNameLists::first_item</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">action_list</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">item</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">item</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">action_listed</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind_of_noun</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ActionSemantics::kind_of_noun</span><span class="plain-syntax">(</span><span class="identifier-syntax">item</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">action_listed</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">kind_of_noun</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">kind_of_noun</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind_of_second</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ActionSemantics::kind_of_second</span><span class="plain-syntax">(</span><span class="identifier-syntax">item</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">action_listed</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">kind_of_second</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">kind_of_second</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3">&#167;3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_2" class="paragraph-anchor"></a><b>&#167;3.2. </b>The macro <span class="extract"><span class="extract-syntax">CPMC_NEEDED</span></span> is a shorthand within this function (and in plugin
functions extending it) to specify that this particular pattern match will
need the clause <span class="extract"><span class="extract-syntax">C</span></span>, which should be one of the <span class="extract"><span class="extract-syntax">*_CPMC</span></span> values. <span class="extract"><span class="extract-syntax">A</span></span> is then
the associated <span class="extract"><span class="extract-syntax">ap_clause</span></span>: see <a href="../if-module/4-apc.html" class="internal">Action Pattern Clauses (in if)</a>.
</p>
<p class="commentary">The <span class="extract"><span class="extract-syntax">MAX_CPM_CLAUSES</span></span> is not currently possible to reach, since the same CPMC
is never used twice when matching the same pattern, and there are nowhere near
256 different CPMCs.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_CPM_CLAUSES</span><span class="plain-syntax"> </span><span class="constant-syntax">256</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">A</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">cpm_count</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">MAX_CPM_CLAUSES</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"action pattern grossly overcomplex"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">needed</span><span class="plain-syntax">[</span><span class="identifier-syntax">cpm_count</span><span class="plain-syntax">] = </span><span class="identifier-syntax">C</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">needed_apoc</span><span class="plain-syntax">[</span><span class="identifier-syntax">cpm_count</span><span class="plain-syntax">] = </span><span class="identifier-syntax">A</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cpm_count</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3_3" class="paragraph-anchor"></a><b>&#167;3.3. </b>Some APs have a much simpler parametric form: see <a href="../if-module/4-ap2.html" class="internal">Action Patterns (in if)</a>.
Those have just one parameter and just one clause applies; but most of the
time we deal with action-related APs, which can be very complex.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Work out what clauses will be needed</span><span class="named-paragraph-number">3.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="named-paragraph-container code-font"><a href="2-map.html#SP3_3_2" class="named-paragraph-link"><span class="named-paragraph">Test the parameter</span><span class="named-paragraph-number">3.3.2</span></a></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">actor_is_player</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">actorless</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_3_1" class="named-paragraph-link"><span class="named-paragraph">Test some actor-related considerations</span><span class="named-paragraph-number">3.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_3_3" class="named-paragraph-link"><span class="named-paragraph">Test the choice of action</span><span class="named-paragraph-number">3.3.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_3_4" class="named-paragraph-link"><span class="named-paragraph">Test the noun</span><span class="named-paragraph-number">3.3.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_3_5" class="named-paragraph-link"><span class="named-paragraph">Test the second noun</span><span class="named-paragraph-number">3.3.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_3_6" class="named-paragraph-link"><span class="named-paragraph">Test the location</span><span class="named-paragraph-number">3.3.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_3_7" class="named-paragraph-link"><span class="named-paragraph">Test the presence of something</span><span class="named-paragraph-number">3.3.7</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_3_8" class="named-paragraph-link"><span class="named-paragraph">Test action-specific optional clauses specified by the source text</span><span class="named-paragraph-number">3.3.8</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_3_9" class="named-paragraph-link"><span class="named-paragraph">Ask the plugins if they want other tests added</span><span class="named-paragraph-number">3.3.9</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_3_10" class="named-paragraph-link"><span class="named-paragraph">Test the when condition</span><span class="named-paragraph-number">3.3.10</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3">&#167;3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_3_1" class="paragraph-anchor"></a><b>&#167;3.3.1. In actor-considering mode only. </b>The semantics of who the actor is seem straightforward to authors of Inform
source text, but they are actually quite difficult to explain; the code has
a tendendy to fill up with double-negatives. Still, here goes.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Test some actor-related considerations</span><span class="named-paragraph-number">3.3.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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">test_requester</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">APClauses::actor_is_anyone_except_player</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">actor_is_player</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Detect if the actor is actually the player after all</span><span class="named-paragraph-number">3.3.1.1</span></a></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">actor_is_player</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_3_1_3" class="named-paragraph-link"><span class="named-paragraph">Require actor to be the player</span><span class="named-paragraph-number">3.3.1.3</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_3_1_2" class="named-paragraph-link"><span class="named-paragraph">Require actor to not be the player</span><span class="named-paragraph-number">3.3.1.2</span></a></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">test_requester</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_3_1_4" class="named-paragraph-link"><span class="named-paragraph">Test requester</span><span class="named-paragraph-number">3.3.1.4</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_3">&#167;3.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_3_1_1" class="paragraph-anchor"></a><b>&#167;3.3.1.1. </b>A pattern not mentioning any actor is implicitly assuming the player is the
actor: "painting the watercolour", for example. But, generally speaking, if the
action pattern does specifies an actor, then it will not be the player: "Uncle
Swithin riding the carriage", for example, clearly says that "Uncle Swithin" is
the actor. But we must make an exception for "the player riding the carriage".
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Detect if the actor is actually the player after all</span><span class="named-paragraph-number">3.3.1.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="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">spec</span><span class="plain-syntax"> = </span><span class="identifier-syntax">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">ACTOR_AP_CLAUSE</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">spec</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">actor_is_player</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nonlocal_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lvalues::get_nonlocal_variable_if_any</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</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">var</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">var</span><span class="plain-syntax"> == </span><span class="identifier-syntax">player_VAR</span><span class="plain-syntax">)) </span><span class="identifier-syntax">actor_is_player</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Rvalues::to_object_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</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">) &amp;&amp; (</span><span class="identifier-syntax">I</span><span class="plain-syntax"> == </span><span class="identifier-syntax">I_yourself</span><span class="plain-syntax">)) </span><span class="identifier-syntax">actor_is_player</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_3_1">&#167;3.3.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_3_1_2" class="paragraph-anchor"></a><b>&#167;3.3.1.2. </b>For example, "
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Require actor to not be the player</span><span class="named-paragraph-number">3.3.1.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">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">ACTOR_IS_NOT_PLAYER_CPMC</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">ACTOR_AP_CLAUSE</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">ACTOR_MATCHES_CPMC</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_3_1">&#167;3.3.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_3_1_3" class="paragraph-anchor"></a><b>&#167;3.3.1.3. </b>It would do no harm to leave <span class="extract"><span class="extract-syntax">test_requester</span></span> true, but would lead to a
redundant check being compiled.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Require actor to be the player</span><span class="named-paragraph-number">3.3.1.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="identifier-syntax">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">ACTOR_IS_PLAYER_CPMC</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">test_requester</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_3_1">&#167;3.3.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_3_1_4" class="paragraph-anchor"></a><b>&#167;3.3.1.4. </b>An action pattern such as "Fred asking Barney to look" is a request, and such
patterns are marked as such. Here we test that the current action is a request
if the pattern is, and also that it isn't if the pattern isn't.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Test requester</span><span class="named-paragraph-number">3.3.1.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">APClauses::is_request</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">REQUESTER_EXISTS_CPMC</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">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">REQUESTER_DOES_NOT_EXIST_CPMC</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_3_1">&#167;3.3.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_3_2" class="paragraph-anchor"></a><b>&#167;3.3.2. In both modes. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Test the parameter</span><span class="named-paragraph-number">3.3.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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">PARAMETRIC_AP_CLAUSE</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">PARAMETER_MATCHES_CPMC</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_3">&#167;3.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_3_3" class="paragraph-anchor"></a><b>&#167;3.3.3. </b>There's an optimisation here. Some rules with premisses like "After dropping
something" are auto-filed into rulebooks tied to individual actions &mdash; in this
case, the "after dropping rulebook". When testing that premiss, which is an
action pattern match, it would be redundant to test that the action is "dropping",
because this can be proved from the context; so we skip this test.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Test the choice of action</span><span class="named-paragraph-number">3.3.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">ap</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">action_list</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ActionNameLists::testing</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">action_list</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">ACTION_MATCHES_CPMC</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_3">&#167;3.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_3_4" class="paragraph-anchor"></a><b>&#167;3.3.4. </b>In the case where no action is specified, but the noun is &mdash; for example,
"doing something with a container" &mdash; we need to check that it is an object
which is not "nothing". The slightly odd practice of the command parser is
such that the way to do with is <span class="extract"><span class="extract-syntax">(noun) &amp;&amp; (noun == inp1)</span></span>.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Test the noun</span><span class="named-paragraph-number">3.3.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">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">NOUN_AP_CLAUSE</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">ap</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">action_list</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">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">NOUN_EXISTS_CPMC</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">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">NOUN_IS_INP1_CPMC</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</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">Kinds::Behaviour::is_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_of_noun</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">NOUN_MATCHES_AS_OBJECT_CPMC</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">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">NOUN_MATCHES_AS_VALUE_CPMC</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_3">&#167;3.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_3_5" class="paragraph-anchor"></a><b>&#167;3.3.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Test the second noun</span><span class="named-paragraph-number">3.3.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">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">SECOND_AP_CLAUSE</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">ap</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">action_list</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">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">SECOND_EXISTS_CPMC</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">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">SECOND_IS_INP2_CPMC</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</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">Kinds::Behaviour::is_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_of_second</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">SECOND_MATCHES_AS_OBJECT_CPMC</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">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">SECOND_MATCHES_AS_VALUE_CPMC</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_3">&#167;3.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_3_6" class="paragraph-anchor"></a><b>&#167;3.3.6. </b>The meaning of "...in the Observatory" depends on who the actor is, because
that is the only practical way of finding out where the action is taking place.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Test the location</span><span class="named-paragraph-number">3.3.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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">IN_AP_CLAUSE</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">actor_is_player</span><span class="plain-syntax"> == </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">PLAYER_LOCATION_MATCHES_CPMC</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">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">ACTOR_IS_SOMEWHERE_CPMC</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">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">ACTOR_LOCATION_MATCHES_CPMC</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_3">&#167;3.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_3_7" class="paragraph-anchor"></a><b>&#167;3.3.7. </b>The "...in the presence of X" clause is compiled three different ways, for
efficiency. Examples of these three cases are:
</p>
<ul class="items"><li>&#9679; "drinking the champagne in the presence of Sabrina";
</li><li>&#9679; "drinking the champagne in the presence of a woman (called the ingenue)";
</li><li>&#9679; "drinking the champagne in the presence of a woman".
</li></ul>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Test the presence of something</span><span class="named-paragraph-number">3.3.7</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">whom</span><span class="plain-syntax"> = </span><span class="identifier-syntax">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">IN_THE_PRESENCE_OF_AP_CLAUSE</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">whom</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to_be_present</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Specifications::object_exactly_described_if_any</span><span class="plain-syntax">(</span><span class="identifier-syntax">whom</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">to_be_present</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">PRESENCE_OF_MATCHES_CPMC</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">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">PRESENCE_OF_IN_SCOPE_CPMC</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">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">Descriptions::get_calling</span><span class="plain-syntax">(</span><span class="identifier-syntax">whom</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">LOOP_OVER_SCOPE_CALLING_CPMC</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">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">LOOP_OVER_SCOPE_NOT_CALLING_CPMC</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_3">&#167;3.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_3_8" class="paragraph-anchor"></a><b>&#167;3.3.8. </b>For example, "going from the Dining Room" uses the optional "from ..." clause
attached to the "going" action, so that would be picked up here:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Test action-specific optional clauses specified by the source text</span><span class="named-paragraph-number">3.3.8</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_AP_CLAUSES</span><span class="plain-syntax">(</span><span class="identifier-syntax">apoc</span><span class="plain-syntax">, </span><span class="identifier-syntax">ap</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">apoc</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">stv_to_match</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">apoc</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">clause_spec</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">OPTIONAL_CLAUSE_CPMC</span><span class="plain-syntax">, </span><span class="identifier-syntax">apoc</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_3">&#167;3.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_3_9" class="paragraph-anchor"></a><b>&#167;3.3.9. </b>And this is where, for example, <a href="2-mgap.html" class="internal">Matching Going Action Patterns</a> adds other
tests needed to reconcile the going variables, but which are not explicitly called
for by the source text:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Ask the plugins if they want other tests added</span><span class="named-paragraph-number">3.3.9</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">PluginCalls::set_pattern_match_requirements</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">cpm_count</span><span class="plain-syntax">, </span><span class="identifier-syntax">needed</span><span class="plain-syntax">, </span><span class="identifier-syntax">needed_apoc</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_3">&#167;3.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_3_10" class="paragraph-anchor"></a><b>&#167;3.3.10. </b>And finally, a stipulation that an arbitrary condition must hold.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Test the when condition</span><span class="named-paragraph-number">3.3.10</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">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">WHEN_AP_CLAUSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">SET_SELF_TO_ACTOR_CPMC</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">CPMC_NEEDED</span><span class="plain-syntax">(</span><span class="constant-syntax">WHEN_CONDITION_HOLDS_CPMC</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_3">&#167;3.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_4" class="paragraph-anchor"></a><b>&#167;3.4. Compiling the tests. </b>We group the tests into four "ranges": thus range 0 is all tests with CPMC number
in the range <span class="extract"><span class="extract-syntax">ACTOR_IS_PLAYER_CPMC &lt;= N &lt;= ACTOR_MATCHES_CPMC</span></span>, and so on.
<span class="extract"><span class="extract-syntax">count[R]</span></span> is the number of tests to perform in the range <span class="extract"><span class="extract-syntax">R</span></span>.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">CPMC_RANGE</span><span class="plain-syntax">(</span><span class="identifier-syntax">ix</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ranges_from</span><span class="plain-syntax">[</span><span class="identifier-syntax">ix</span><span class="plain-syntax">] = </span><span class="identifier-syntax">F</span><span class="plain-syntax">; </span><span class="identifier-syntax">ranges_to</span><span class="plain-syntax">[</span><span class="identifier-syntax">ix</span><span class="plain-syntax">] = </span><span class="identifier-syntax">T</span><span class="plain-syntax">; </span><span class="identifier-syntax">count</span><span class="plain-syntax">[</span><span class="identifier-syntax">ix</span><span class="plain-syntax">] = </span><span class="constant-syntax">0</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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">cpm_count</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</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">needed</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] &gt;= </span><span class="identifier-syntax">F</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">needed</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] &lt;= </span><span class="identifier-syntax">T</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">count</span><span class="plain-syntax">[</span><span class="identifier-syntax">ix</span><span class="plain-syntax">]++;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3_5" class="paragraph-anchor"></a><b>&#167;3.5. </b>For what is in these ranges, see the definitions above.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile the condition from these instructions</span><span class="named-paragraph-number">3.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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ranges_from</span><span class="plain-syntax">[4], </span><span class="identifier-syntax">ranges_to</span><span class="plain-syntax">[4], </span><span class="identifier-syntax">count</span><span class="plain-syntax">[4];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_RANGE</span><span class="plain-syntax">(</span><span class="constant-syntax">ACTOR_CPMCRANGE</span><span class="plain-syntax">, </span><span class="constant-syntax">ACTOR_IS_PLAYER_CPMC</span><span class="plain-syntax">, </span><span class="constant-syntax">ACTOR_MATCHES_CPMC</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_RANGE</span><span class="plain-syntax">(</span><span class="constant-syntax">ACTION_CPMCRANGE</span><span class="plain-syntax">, </span><span class="constant-syntax">ACTION_MATCHES_CPMC</span><span class="plain-syntax">, </span><span class="constant-syntax">ACTION_MATCHES_CPMC</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_RANGE</span><span class="plain-syntax">(</span><span class="constant-syntax">DETAILS_CPMCRANGE</span><span class="plain-syntax">, </span><span class="constant-syntax">NOUN_EXISTS_CPMC</span><span class="plain-syntax">, </span><span class="identifier-syntax">NO_DEFINED_CPMC_VALUES</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CPMC_RANGE</span><span class="plain-syntax">(</span><span class="constant-syntax">WHEN_CPMCRANGE</span><span class="plain-syntax">, </span><span class="constant-syntax">SET_SELF_TO_ACTOR_CPMC</span><span class="plain-syntax">, </span><span class="constant-syntax">WHEN_CONDITION_HOLDS_CPMC</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cc.html#SP3" class="function-link"><span class="function-syntax">CompileConditions::begin</span></a><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">ActionNameLists::listwise_negated</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">action_list</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_2" class="named-paragraph-link"><span class="named-paragraph">Listwise negated case</span><span class="named-paragraph-number">3.5.2</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1" class="named-paragraph-link"><span class="named-paragraph">Listwise positive case</span><span class="named-paragraph-number">3.5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="2-cc.html#SP5" class="function-link"><span class="function-syntax">CompileConditions::end</span></a><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3">&#167;3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1" class="paragraph-anchor"></a><b>&#167;3.5.1. </b>This is the easier case: all four ranges of condition must be true, and so
we compile code equivalent to <span class="extract"><span class="extract-syntax">ACTION and ACTOR and DETAILS and WHEN</span></span>. We
do it in that order for two reasons: firstly, wrong actions are the commonest
reason actions fail to match, and the ACTION tests are quick, so it's efficient
to test that first. (The ACTOR tests are also quick, but usually pass.) Secondly,
some DETAILS tests will compile non-typesafe code in cases where ACTION would
not pass, so DETAILS must be compiled after ACTION. Finally, we put WHEN at
the back because it compiles an arbitrary condition, and that could be
something quite slow to perform: so we check it only if we definitely need
to know the result.
</p>
<p class="commentary">Note that we must never compile nothing at all: if there are no clauses
we still have to compile <span class="extract"><span class="extract-syntax">true</span></span>, to ensure that every action will match.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Listwise positive case</span><span class="named-paragraph-number">3.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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">downs</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</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">count</span><span class="plain-syntax">[</span><span class="constant-syntax">ACTION_CPMCRANGE</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</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">count</span><span class="plain-syntax">[</span><span class="constant-syntax">ACTOR_CPMCRANGE</span><span class="plain-syntax">] + </span><span class="identifier-syntax">count</span><span class="plain-syntax">[</span><span class="constant-syntax">DETAILS_CPMCRANGE</span><span class="plain-syntax">] +</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">count</span><span class="plain-syntax">[</span><span class="constant-syntax">WHEN_CPMCRANGE</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">AND_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">(); </span><span class="identifier-syntax">downs</span><span class="plain-syntax">++;</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">range</span><span class="plain-syntax"> = </span><span class="constant-syntax">ACTION_CPMCRANGE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1" class="named-paragraph-link"><span class="named-paragraph">Compile a subcondition for this range</span><span class="named-paragraph-number">3.5.1.1</span></a></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">count</span><span class="plain-syntax">[</span><span class="constant-syntax">ACTOR_CPMCRANGE</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</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">count</span><span class="plain-syntax">[</span><span class="constant-syntax">DETAILS_CPMCRANGE</span><span class="plain-syntax">] + </span><span class="identifier-syntax">count</span><span class="plain-syntax">[</span><span class="constant-syntax">WHEN_CPMCRANGE</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">AND_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">(); </span><span class="identifier-syntax">downs</span><span class="plain-syntax">++;</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">range</span><span class="plain-syntax"> = </span><span class="constant-syntax">ACTOR_CPMCRANGE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1" class="named-paragraph-link"><span class="named-paragraph">Compile a subcondition for this range</span><span class="named-paragraph-number">3.5.1.1</span></a></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">count</span><span class="plain-syntax">[</span><span class="constant-syntax">DETAILS_CPMCRANGE</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</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">count</span><span class="plain-syntax">[</span><span class="constant-syntax">WHEN_CPMCRANGE</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">AND_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">(); </span><span class="identifier-syntax">downs</span><span class="plain-syntax">++;</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">range</span><span class="plain-syntax"> = </span><span class="constant-syntax">DETAILS_CPMCRANGE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1" class="named-paragraph-link"><span class="named-paragraph">Compile a subcondition for this range</span><span class="named-paragraph-number">3.5.1.1</span></a></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">count</span><span class="plain-syntax">[</span><span class="constant-syntax">WHEN_CPMCRANGE</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</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">range</span><span class="plain-syntax"> = </span><span class="constant-syntax">WHEN_CPMCRANGE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1" class="named-paragraph-link"><span class="named-paragraph">Compile a subcondition for this range</span><span class="named-paragraph-number">3.5.1.1</span></a></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">count</span><span class="plain-syntax">[</span><span class="constant-syntax">ACTOR_CPMCRANGE</span><span class="plain-syntax">] + </span><span class="identifier-syntax">count</span><span class="plain-syntax">[</span><span class="constant-syntax">ACTION_CPMCRANGE</span><span class="plain-syntax">] +</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">count</span><span class="plain-syntax">[</span><span class="constant-syntax">DETAILS_CPMCRANGE</span><span class="plain-syntax">] + </span><span class="identifier-syntax">count</span><span class="plain-syntax">[</span><span class="constant-syntax">WHEN_CPMCRANGE</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">EmitCode::val_true</span><span class="plain-syntax">();</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">downs</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">(); </span><span class="identifier-syntax">downs</span><span class="plain-syntax">--; }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5">&#167;3.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_2" class="paragraph-anchor"></a><b>&#167;3.5.2. </b>A listwise negated pattern is something like "doing something other than
examining the box", which matches any action except "examining the box". It
might seem that this could be negated just as the negation of the positive
case, but that overlooks the hidden clauses about who the actor is, whether
the action is a request, and so on &mdash; the <span class="extract"><span class="extract-syntax">ACTOR_CPMCRANGE</span></span> &mdash; and any
condition supplied &mdash; the <span class="extract"><span class="extract-syntax">WHEN_CPMCRANGE</span></span>.
</p>
<p class="commentary">For example, "doing something other than examining the box when the red door is
open" matches "dropping the box" only if the door is open at the time.
</p>
<p class="commentary">So this compiles as <span class="extract"><span class="extract-syntax">ACTOR and (not (ACTION and DETAILS)) and WHEN</span></span>.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Listwise negated case</span><span class="named-paragraph-number">3.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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">count</span><span class="plain-syntax">[</span><span class="constant-syntax">ACTOR_CPMCRANGE</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">AND_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</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">range</span><span class="plain-syntax"> = </span><span class="constant-syntax">ACTOR_CPMCRANGE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1" class="named-paragraph-link"><span class="named-paragraph">Compile a subcondition for this range</span><span class="named-paragraph-number">3.5.1.1</span></a></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">count</span><span class="plain-syntax">[</span><span class="constant-syntax">WHEN_CPMCRANGE</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">AND_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">NOT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</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">count</span><span class="plain-syntax">[</span><span class="constant-syntax">ACTION_CPMCRANGE</span><span class="plain-syntax">] == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">count</span><span class="plain-syntax">[</span><span class="constant-syntax">DETAILS_CPMCRANGE</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">EmitCode::val_false</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</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">count</span><span class="plain-syntax">[</span><span class="constant-syntax">ACTION_CPMCRANGE</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">count</span><span class="plain-syntax">[</span><span class="constant-syntax">DETAILS_CPMCRANGE</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">AND_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</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">count</span><span class="plain-syntax">[</span><span class="constant-syntax">ACTION_CPMCRANGE</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</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">range</span><span class="plain-syntax"> = </span><span class="constant-syntax">ACTION_CPMCRANGE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1" class="named-paragraph-link"><span class="named-paragraph">Compile a subcondition for this range</span><span class="named-paragraph-number">3.5.1.1</span></a></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">count</span><span class="plain-syntax">[</span><span class="constant-syntax">DETAILS_CPMCRANGE</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</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">range</span><span class="plain-syntax"> = </span><span class="constant-syntax">DETAILS_CPMCRANGE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1" class="named-paragraph-link"><span class="named-paragraph">Compile a subcondition for this range</span><span class="named-paragraph-number">3.5.1.1</span></a></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">count</span><span class="plain-syntax">[</span><span class="constant-syntax">ACTION_CPMCRANGE</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">count</span><span class="plain-syntax">[</span><span class="constant-syntax">DETAILS_CPMCRANGE</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</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">count</span><span class="plain-syntax">[</span><span class="constant-syntax">WHEN_CPMCRANGE</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</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">range</span><span class="plain-syntax"> = </span><span class="constant-syntax">WHEN_CPMCRANGE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1" class="named-paragraph-link"><span class="named-paragraph">Compile a subcondition for this range</span><span class="named-paragraph-number">3.5.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</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">count</span><span class="plain-syntax">[</span><span class="constant-syntax">ACTOR_CPMCRANGE</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5">&#167;3.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1" class="paragraph-anchor"></a><b>&#167;3.5.1.1. </b>So here we compile all the clauses in the range <span class="extract"><span class="extract-syntax">range</span></span>. If no tests are needed
then no code would be compiled, which is not in fact a valid condition; but
this never happens, because the code above arranges that we never come here unless
there is at least one test in the range to be performed.
</p>
<p class="commentary">The range is then compiled to a simple conjunction of the tests needed, in
ascending numerical order of CPMC.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile a subcondition for this range</span><span class="named-paragraph-number">3.5.1.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">count</span><span class="plain-syntax">[</span><span class="identifier-syntax">range</span><span class="plain-syntax">] == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"logic error in AP matcher"</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">downs</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0, </span><span class="identifier-syntax">done</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">cpm_count</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</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">cpmc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">needed</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</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">cpmc</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">ranges_from</span><span class="plain-syntax">[</span><span class="identifier-syntax">range</span><span class="plain-syntax">]) &amp;&amp; (</span><span class="identifier-syntax">cpmc</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">ranges_to</span><span class="plain-syntax">[</span><span class="identifier-syntax">range</span><span class="plain-syntax">])) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">done</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">done</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">count</span><span class="plain-syntax">[</span><span class="identifier-syntax">range</span><span class="plain-syntax">]) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">AND_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">(); </span><span class="identifier-syntax">downs</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ap_clause</span><span class="plain-syntax"> *</span><span class="identifier-syntax">apoc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">needed_apoc</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Compile a subcondition for this CPMC</span><span class="named-paragraph-number">3.5.1.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</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">downs</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">(); </span><span class="identifier-syntax">downs</span><span class="plain-syntax">--; }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1">&#167;3.5.1</a> (four times), <a href="2-map.html#SP3_5_2">&#167;3.5.2</a> (four times).</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1. </b>And finally we compile a single clause as a condition. We first ask a plugin
if it wants to do that for us (as it must, for any non-standard CPMCs it has created);
and otherwise we do our own thing.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile a subcondition for this CPMC</span><span class="named-paragraph-number">3.5.1.1.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">PluginCalls::compile_pattern_match_clause</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">cpmc</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">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cpmc</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> The ACTOR range</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">ACTOR_IS_PLAYER_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Compile ACTOR_IS_PLAYER_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.1</span></a></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">ACTOR_IS_NOT_PLAYER_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_2" class="named-paragraph-link"><span class="named-paragraph">Compile ACTOR_IS_NOT_PLAYER_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.2</span></a></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">REQUESTER_EXISTS_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_3" class="named-paragraph-link"><span class="named-paragraph">Compile REQUESTER_EXISTS_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.3</span></a></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">REQUESTER_DOES_NOT_EXIST_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_4" class="named-paragraph-link"><span class="named-paragraph">Compile REQUESTER_DOES_NOT_EXIST_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.4</span></a></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">ACTOR_MATCHES_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_5" class="named-paragraph-link"><span class="named-paragraph">Compile ACTOR_MATCHES_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.5</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> The ACTION range</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">ACTION_MATCHES_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_6" class="named-paragraph-link"><span class="named-paragraph">Compile ACTION_MATCHES_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.6</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> The DETAILS range (but see features for extra ones)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NOUN_EXISTS_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_7" class="named-paragraph-link"><span class="named-paragraph">Compile NOUN_EXISTS_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.7</span></a></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">NOUN_IS_INP1_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_8" class="named-paragraph-link"><span class="named-paragraph">Compile NOUN_IS_INP1_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.8</span></a></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">NOUN_MATCHES_AS_OBJECT_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_9" class="named-paragraph-link"><span class="named-paragraph">Compile NOUN_MATCHES_AS_OBJECT_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.9</span></a></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">NOUN_MATCHES_AS_VALUE_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_10" class="named-paragraph-link"><span class="named-paragraph">Compile NOUN_MATCHES_AS_VALUE_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.10</span></a></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">SECOND_EXISTS_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_11" class="named-paragraph-link"><span class="named-paragraph">Compile SECOND_EXISTS_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.11</span></a></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">SECOND_IS_INP2_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_12" class="named-paragraph-link"><span class="named-paragraph">Compile SECOND_IS_INP2_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.12</span></a></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">SECOND_MATCHES_AS_OBJECT_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_13" class="named-paragraph-link"><span class="named-paragraph">Compile SECOND_MATCHES_AS_OBJECT_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.13</span></a></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">SECOND_MATCHES_AS_VALUE_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_14" class="named-paragraph-link"><span class="named-paragraph">Compile SECOND_MATCHES_AS_VALUE_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.14</span></a></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">PLAYER_LOCATION_MATCHES_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_15" class="named-paragraph-link"><span class="named-paragraph">Compile PLAYER_LOCATION_MATCHES_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.15</span></a></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">ACTOR_IS_SOMEWHERE_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_16" class="named-paragraph-link"><span class="named-paragraph">Compile ACTOR_IS_SOMEWHERE_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.16</span></a></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">ACTOR_LOCATION_MATCHES_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_17" class="named-paragraph-link"><span class="named-paragraph">Compile ACTOR_LOCATION_MATCHES_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.17</span></a></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">PARAMETER_MATCHES_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_22" class="named-paragraph-link"><span class="named-paragraph">Compile PARAMETER_MATCHES_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.22</span></a></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">OPTIONAL_CLAUSE_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_23" class="named-paragraph-link"><span class="named-paragraph">Compile OPTIONAL_CLAUSE_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.23</span></a></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">PRESENCE_OF_MATCHES_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_18" class="named-paragraph-link"><span class="named-paragraph">Compile PRESENCE_OF_MATCHES_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.18</span></a></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">PRESENCE_OF_IN_SCOPE_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_19" class="named-paragraph-link"><span class="named-paragraph">Compile PRESENCE_OF_IN_SCOPE_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.19</span></a></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">LOOP_OVER_SCOPE_CALLING_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_20" class="named-paragraph-link"><span class="named-paragraph">Compile LOOP_OVER_SCOPE_CALLING_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.20</span></a></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">LOOP_OVER_SCOPE_NOT_CALLING_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_21" class="named-paragraph-link"><span class="named-paragraph">Compile LOOP_OVER_SCOPE_NOT_CALLING_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.21</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> The WHEN range</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SET_SELF_TO_ACTOR_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_24" class="named-paragraph-link"><span class="named-paragraph">Compile SET_SELF_TO_ACTOR_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.24</span></a></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">WHEN_CONDITION_HOLDS_CPMC:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP3_5_1_1_1_25" class="named-paragraph-link"><span class="named-paragraph">Compile WHEN_CONDITION_HOLDS_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.25</span></a></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="2-map.html#SP3_5_1_1">&#167;3.5.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_1" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.1. The ACTOR range of CPMCs. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile ACTOR_IS_PLAYER_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.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="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">EQ_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">ACTOR_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">PLAYER_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_2" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile ACTOR_IS_NOT_PLAYER_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.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">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">NE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">ACTOR_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">PLAYER_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_3" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile REQUESTER_EXISTS_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.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="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">ACT_REQUESTER_HL</span><span class="plain-syntax">));</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_4" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile REQUESTER_DOES_NOT_EXIST_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.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">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">EQ_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">ACT_REQUESTER_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_5" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile ACTOR_MATCHES_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="2-map.html#SP4" class="function-link"><span class="function-syntax">RTActionPatterns::variable_matches_specification</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Inter_actor_VAR</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">ACTOR_AP_CLAUSE</span><span class="plain-syntax">), </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_6" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.6. The ACTION range of CPMCs. </b>Just one of these, but it's a doozy. Note that an action name list is essentially
a disjunction, i.e., a list of alternatives: "taking or dropping the box", for
example, features an action name list with <span class="extract"><span class="extract-syntax">C == 2</span></span>.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile ACTION_MATCHES_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.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="identifier-syntax">action_name_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">head</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ap</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">action_list</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">C</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ActionNameLists::length</span><span class="plain-syntax">(</span><span class="identifier-syntax">head</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">C</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</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">ACTION_PATTERN_COMPILATION</span><span class="plain-syntax">, </span><span class="string-syntax">"Emitting action name list: $L"</span><span class="plain-syntax">, </span><span class="identifier-syntax">head</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">neg</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ActionNameLists::itemwise_negated</span><span class="plain-syntax">(</span><span class="identifier-syntax">head</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">neg</span><span class="plain-syntax">) { </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">NOT_BIP</span><span class="plain-syntax">); </span><span class="identifier-syntax">EmitCode::down</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="identifier-syntax">downs</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_THROUGH_ANL</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">head</span><span class="plain-syntax">) {</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">N</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">C</span><span class="plain-syntax">) { </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">OR_BIP</span><span class="plain-syntax">); </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">(); </span><span class="identifier-syntax">downs</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">-&gt;</span><span class="identifier-syntax">item</span><span class="plain-syntax">.</span><span class="identifier-syntax">nap_listed</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">INDIRECT0_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">RTNamedActionPatterns::test_fn_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">item</span><span class="plain-syntax">.</span><span class="identifier-syntax">nap_listed</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">EQ_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">ACTION_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">RTActions::double_sharp</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">item</span><span class="plain-syntax">.</span><span class="identifier-syntax">action_listed</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</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">downs</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">(); </span><span class="identifier-syntax">downs</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">neg</span><span class="plain-syntax">) </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_true</span><span class="plain-syntax">(); </span><span class="comment-syntax"> should never happen, but would be correct if it did</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_7" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.7. The DETAILS range of CPMCs. </b>For the frankly oddball way that the runtime variables <span class="extract"><span class="extract-syntax">noun</span></span>, <span class="extract"><span class="extract-syntax">inp1</span></span> and
<span class="extract"><span class="extract-syntax">parsed_number</span></span> are juggled inside the parser, see <a href="../CommandParserKit/index.html" class="internal">CommandParserKit</a>. Here
it's enough to know that
</p>
<ul class="items"><li>(a) for EXAMINE BOX, <span class="extract"><span class="extract-syntax">noun</span></span> and <span class="extract"><span class="extract-syntax">inp1</span></span> would be the box, and <span class="extract"><span class="extract-syntax">parsed_number</span></span>
would have no meaning, but
</li><li>(b) for TYPE 246, <span class="extract"><span class="extract-syntax">inp1</span></span> would be 1, <span class="extract"><span class="extract-syntax">parsed_number</span></span> would be 246, and <span class="extract"><span class="extract-syntax">noun</span></span>
would be <span class="extract"><span class="extract-syntax">nothing</span></span>.
</li></ul>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile NOUN_EXISTS_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.7</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">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">NOUN_HL</span><span class="plain-syntax">));</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_8" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.8. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile NOUN_IS_INP1_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.8</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">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">EQ_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">NOUN_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">INP1_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_9" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.9. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile NOUN_MATCHES_AS_OBJECT_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.9</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="2-map.html#SP4" class="function-link"><span class="function-syntax">RTActionPatterns::variable_matches_specification</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Inter_noun_VAR</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">NOUN_AP_CLAUSE</span><span class="plain-syntax">), </span><span class="identifier-syntax">kind_of_noun</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_10" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.10. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile NOUN_MATCHES_AS_VALUE_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.10</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="2-map.html#SP4" class="function-link"><span class="function-syntax">RTActionPatterns::variable_matches_specification</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><a href="3-tv.html#SP1" class="function-link"><span class="function-syntax">TemporaryVariables::from_iname</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">PARSED_NUMBER_HL</span><span class="plain-syntax">), </span><span class="identifier-syntax">kind_of_noun</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">NOUN_AP_CLAUSE</span><span class="plain-syntax">), </span><span class="identifier-syntax">kind_of_noun</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_11" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.11. </b>And similarly for the second noun, but with <span class="extract"><span class="extract-syntax">second</span></span> and <span class="extract"><span class="extract-syntax">inp2</span></span> in place of
<span class="extract"><span class="extract-syntax">noun</span></span> and <span class="extract"><span class="extract-syntax">inp1</span></span>.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile SECOND_EXISTS_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.11</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">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">SECOND_HL</span><span class="plain-syntax">));</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_12" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.12. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile SECOND_IS_INP2_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.12</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">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">EQ_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">SECOND_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">INP2_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_13" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.13. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile SECOND_MATCHES_AS_OBJECT_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.13</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="2-map.html#SP4" class="function-link"><span class="function-syntax">RTActionPatterns::variable_matches_specification</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Inter_second_noun_VAR</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">SECOND_AP_CLAUSE</span><span class="plain-syntax">), </span><span class="identifier-syntax">kind_of_second</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_14" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.14. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile SECOND_MATCHES_AS_VALUE_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.14</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="2-map.html#SP4" class="function-link"><span class="function-syntax">RTActionPatterns::variable_matches_specification</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><a href="3-tv.html#SP1" class="function-link"><span class="function-syntax">TemporaryVariables::from_iname</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">PARSED_NUMBER_HL</span><span class="plain-syntax">), </span><span class="identifier-syntax">kind_of_second</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">SECOND_AP_CLAUSE</span><span class="plain-syntax">), </span><span class="identifier-syntax">kind_of_second</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_15" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.15. </b>An action takes place in the location of the actor: we will have no spooky
action at a distance here. If the actor can be proved to be the player, then
this test is sufficient:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile PLAYER_LOCATION_MATCHES_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.15</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="2-map.html#SP4" class="function-link"><span class="function-syntax">RTActionPatterns::variable_matches_specification</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">real_location_VAR</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">IN_AP_CLAUSE</span><span class="plain-syntax">), </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_16" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.16. </b>But if the actor might not be the player, we first test this condition,
which is true if and only if the actor is somewhere in play. (In particular,
an actor removed from the object tree because the character has, say, died,
can never have a location. But such an actor cannot be acting anyway.) Note
the side-effect of setting the <span class="extract"><span class="extract-syntax">actor_location</span></span> variable...
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile ACTOR_IS_SOMEWHERE_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.16</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">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">ACTOR_LOCATION_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOCATIONOF_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">ACTOR_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_17" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.17. </b>...when is then used in this pattern match:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile ACTOR_LOCATION_MATCHES_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.17</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="2-map.html#SP4" class="function-link"><span class="function-syntax">RTActionPatterns::variable_matches_specification</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">actor_location_VAR</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">IN_AP_CLAUSE</span><span class="plain-syntax">), </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_18" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.18. </b>With "in the presence of" clauses, it is always the player's presence that
is meant, not the actor's: i.e., "in the presence of X" means that the player
must be near to X, not that the actor must be. This is questionable, but is
needed because the command parser is unable to calculate scope properly for
actors other than the player.
</p>
<p class="commentary">Even so, there are three cases. The easy one is when we know exactly who or
what we are to be in the presence of. Even so, that comes in two stages;
first, any conditions must be met. So "in the presence of an angry Mrs Sprout"
would test for the anger here.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile PRESENCE_OF_MATCHES_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.18</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">whom</span><span class="plain-syntax"> = </span><span class="identifier-syntax">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">IN_THE_PRESENCE_OF_AP_CLAUSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to_be_present</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Specifications::object_exactly_described_if_any</span><span class="plain-syntax">(</span><span class="identifier-syntax">whom</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-map.html#SP4" class="function-link"><span class="function-syntax">RTActionPatterns::variable_matches_specification</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><a href="3-tv.html#SP1" class="function-link"><span class="function-syntax">TemporaryVariables::from_iname</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">RTInstances::value_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">to_be_present</span><span class="plain-syntax">), </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">whom</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_19" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.19. </b>And secondly, we test whether Mrs Sprout is nearby.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile PRESENCE_OF_IN_SCOPE_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.19</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">whom</span><span class="plain-syntax"> = </span><span class="identifier-syntax">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">IN_THE_PRESENCE_OF_AP_CLAUSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to_be_present</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Specifications::object_exactly_described_if_any</span><span class="plain-syntax">(</span><span class="identifier-syntax">whom</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">TESTSCOPE_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">RTInstances::value_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">to_be_present</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">ACTOR_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_20" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.20. </b>The second case is the hardest: "in the presence of an angry person (called
the wrathful one)" must not only test if anyone nearby is angry, but also set
a new variable, "the wrathful one", to that person.
</p>
<p class="commentary">Note that we call <a href="../runtime-module/4-los.html" class="internal">Looping Over Scope (in runtime)</a> to trigger the compilation of
a helper function, which will be placed in the same enclosure as the function
we are currently compiling.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile LOOP_OVER_SCOPE_CALLING_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.20</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">whom</span><span class="plain-syntax"> = </span><span class="identifier-syntax">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">IN_THE_PRESENCE_OF_AP_CLAUSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">loop_over_scope</span><span class="plain-syntax"> *</span><span class="identifier-syntax">los</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LoopingOverScope::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">whom</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">PC</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Descriptions::get_calling</span><span class="plain-syntax">(</span><span class="identifier-syntax">whom</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP20" class="function-link"><span class="function-syntax">LocalVariables::ensure_calling</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PC</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Specifications::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">whom</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP1" class="function-link"><span class="function-syntax">LocalVariables::declare</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">SEQUENTIAL_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOS_RV_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">SEQUENTIAL_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOOPOVERSCOPE_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">los</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">los_iname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">ACTOR_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">lvar_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOS_RV_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_21" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.21. </b>The third case is slightly easier: "in the presence of an angry person", say,
with no variable to set.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile LOOP_OVER_SCOPE_NOT_CALLING_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.21</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">whom</span><span class="plain-syntax"> = </span><span class="identifier-syntax">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">IN_THE_PRESENCE_OF_AP_CLAUSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">loop_over_scope</span><span class="plain-syntax"> *</span><span class="identifier-syntax">los</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LoopingOverScope::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">whom</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">SEQUENTIAL_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOS_RV_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_number</span><span class="plain-syntax">(0);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">SEQUENTIAL_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOOPOVERSCOPE_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">los</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">los_iname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">ACTOR_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOS_RV_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_22" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.22. </b>The shenanigans here are because the "parameter object" variable, which is
used only when we are really parsing the premiss of an activity-based rule and
does not arise in genuine action patterns, is typeless at runtime: or rather,
it has a different meaning depending on the activity currently being processed,
and that means it is only typesafe within activity processing.
</p>
<p class="commentary">That makes it tricky to represent with a <span class="extract"><span class="extract-syntax">nonlocal_variable</span></span>, which in principle
has a single kind for its whole existence. So here we temporarily amend the kind
of that variable to the kind we have deduced from the activity context.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile PARAMETER_MATCHES_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.22</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">nonlocal_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">par_var</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NonlocalVariables::parameter_object_variable</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">saved_kind</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NonlocalVariables::kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">par_var</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NonlocalVariables::set_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">par_var</span><span class="plain-syntax">, </span><span class="identifier-syntax">ap</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">parameter_kind</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-map.html#SP4" class="function-link"><span class="function-syntax">RTActionPatterns::variable_matches_specification</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">par_var</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">PARAMETRIC_AP_CLAUSE</span><span class="plain-syntax">), </span><span class="identifier-syntax">ap</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">parameter_kind</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NonlocalVariables::set_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">par_var</span><span class="plain-syntax">, </span><span class="identifier-syntax">saved_kind</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_23" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.23. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile OPTIONAL_CLAUSE_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.23</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">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SharedVariables::get_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">apoc</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">stv_to_match</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-map.html#SP4" class="function-link"><span class="function-syntax">RTActionPatterns::variable_matches_specification</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><a href="3-tv.html#SP1" class="function-link"><span class="function-syntax">TemporaryVariables::from_existing_variable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">apoc</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">stv_to_match</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">underlying_var</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">apoc</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">clause_spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">APClauses::opt</span><span class="plain-syntax">(</span><span class="identifier-syntax">apoc</span><span class="plain-syntax">, </span><span class="identifier-syntax">ALLOW_REGION_AS_ROOM_APCOPT</span><span class="plain-syntax">));</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_24" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.24. The WHEN range of CPMCs. </b>This test is always true (even if <span class="extract"><span class="extract-syntax">actor</span></span> is 0), but is executed for its side-effect
of setting the <span class="extract"><span class="extract-syntax">self</span></span> pseudovariable, so that it will have the right contents when
the WHEN condition is evaluated.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile SET_SELF_TO_ACTOR_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.24</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">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">SEQUENTIAL_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">SELF_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_object</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">ACTOR_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_true</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_5_1_1_1_25" class="paragraph-anchor"></a><b>&#167;3.5.1.1.1.25. </b>And last but not least, despite its brief look, the test which may be the
slowest of all, and is therefore performed last:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile WHEN_CONDITION_HOLDS_CPMC test</span><span class="named-paragraph-number">3.5.1.1.1.25</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="2-cv.html#SP5" class="function-link"><span class="function-syntax">CompileValues::to_code_val</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">APClauses::spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="identifier-syntax">WHEN_AP_CLAUSE</span><span class="plain-syntax">));</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP3_5_1_1_1">&#167;3.5.1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. Matching variables. </b>Many of the clauses above amount to testing whether a given variable holds
an object (or other value) matching some specification: the following function
compiles code to test whether or not it does.
</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">RTActionPatterns::variable_matches_specification</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">RTActionPatterns::variable_matches_specification</span></span>:<br/><a href="2-map.html#SP3_5_1_1_1_5">&#167;3.5.1.1.1.5</a>, <a href="2-map.html#SP3_5_1_1_1_9">&#167;3.5.1.1.1.9</a>, <a href="2-map.html#SP3_5_1_1_1_10">&#167;3.5.1.1.1.10</a>, <a href="2-map.html#SP3_5_1_1_1_13">&#167;3.5.1.1.1.13</a>, <a href="2-map.html#SP3_5_1_1_1_14">&#167;3.5.1.1.1.14</a>, <a href="2-map.html#SP3_5_1_1_1_15">&#167;3.5.1.1.1.15</a>, <a href="2-map.html#SP3_5_1_1_1_17">&#167;3.5.1.1.1.17</a>, <a href="2-map.html#SP3_5_1_1_1_18">&#167;3.5.1.1.1.18</a>, <a href="2-map.html#SP3_5_1_1_1_22">&#167;3.5.1.1.1.22</a>, <a href="2-map.html#SP3_5_1_1_1_23">&#167;3.5.1.1.1.23</a><br/>Matching Going Action Patterns - <a href="2-mgap.html#SP2_3">&#167;2.3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">nonlocal_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I6_global_variable</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">verify_as_kind</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">adapt_region</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">I6_global_variable</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">"no variable"</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">spec</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">"no specification"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">val</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lvalues::new_actual_NONLOCAL_VARIABLE</span><span class="plain-syntax">(</span><span class="identifier-syntax">I6_global_variable</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">is_parameter</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">I6_global_variable</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NonlocalVariables::parameter_object_variable</span><span class="plain-syntax">())</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">is_parameter</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="2-map.html#SP5" class="function-link"><span class="function-syntax">RTActionPatterns::value_matches_specification</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">val</span><span class="plain-syntax">, </span><span class="identifier-syntax">is_parameter</span><span class="plain-syntax">, </span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">verify_as_kind</span><span class="plain-syntax">, </span><span class="identifier-syntax">adapt_region</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. Matching values. </b>The serious work is done here. Note that this function is also called from
<a href="../runtime-module/4-los.html" class="internal">Looping Over Scope (in runtime)</a>, because that essentially was a way to
defer the same matching process into a helper function.
</p>
<p class="commentary">The value <span class="extract"><span class="extract-syntax">val</span></span> will in practice always be a local or global variable.
</p>
<p class="commentary">If the match makes a calling, as in "an open door (called the way out)", the
following compiles to the equivalent of <span class="extract"><span class="extract-syntax">(way out = V, open-door(V))</span></span>; the first
clause has side effect of setting the "way out" variable, the second actually
performs the condition. It would then be unsafe to use the value of "way out"
if the condition were false, but Inform manages the scope of this variable so
that it cannot be referred to in that case.
</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">RTActionPatterns::value_matches_specification</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">RTActionPatterns::value_matches_specification</span></span>:<br/><a href="2-map.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">val</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">is_parameter</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">verify_as_kind</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">adapt_region</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">val</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">"no variable"</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">ACTION_PATTERN_COMPILATION</span><span class="plain-syntax">, </span><span class="string-syntax">"[Value $P matches $P]\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">val</span><span class="plain-syntax">, </span><span class="identifier-syntax">spec</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP5_1" class="named-paragraph-link"><span class="named-paragraph">Make sure the specification is known and definite</span><span class="named-paragraph-number">5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">C</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Descriptions::get_calling</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</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">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><a href="3-lv.html#SP20" class="function-link"><span class="function-syntax">LocalVariables::ensure_calling</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">Specifications::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="2-cc.html#SP4" class="function-link"><span class="function-syntax">CompileConditions::add_calling</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">SEQUENTIAL_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP1" class="function-link"><span class="function-syntax">LocalVariables::declare</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">lvar_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cv.html#SP5" class="function-link"><span class="function-syntax">CompileValues::to_code_val</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">val</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP5_2" class="named-paragraph-link"><span class="named-paragraph">Match the value</span><span class="named-paragraph-number">5.2</span></a></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">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</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 sure the specification is known and definite</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">spec</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">"no specification"</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">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">UNKNOWN_NT</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">problem_count</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"AP clause specification unknown"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">; </span><span class="comment-syntax"> for error recovery only</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">Kinds::Behaviour::definite</span><span class="plain-syntax">(</span><span class="identifier-syntax">Specifications::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_APClauseIndefinite</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"that action seems to involve a value which is unclear about its kind"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and that's not allowed. For example, you're not allowed to just say 'Instead "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"of taking a value: ...' because the taking action applies to objects; the "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"vaguest you're allowed to be is 'Instead of taking an object: ...'."</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="2-map.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2" class="paragraph-anchor"></a><b>&#167;5.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Match the value</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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">compiled_ad_hoc</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lvalues::is_lvalue</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</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">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">TABLE_ENTRY_NT</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP5_2_1" class="named-paragraph-link"><span class="named-paragraph">Handle table entries ad-hoc</span><span class="named-paragraph-number">5.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">compiled_ad_hoc</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">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Rvalues::is_rvalue</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</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">K_understanding</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Rvalues::is_CONSTANT_of_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_understanding</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP5_2_2" class="named-paragraph-link"><span class="named-paragraph">Handle a constant snippet ad-hoc</span><span class="named-paragraph-number">5.2.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">compiled_ad_hoc</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">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">is_parameter</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Rvalues::is_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Specifications::object_exactly_described_if_any</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</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">) &amp;&amp; (</span><span class="identifier-syntax">Instances::of_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_region</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">adapt_region</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP5_2_3" class="named-paragraph-link"><span class="named-paragraph">Handle a regional containment test ad-hoc</span><span class="named-paragraph-number">5.2.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">compiled_ad_hoc</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="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Specifications::is_description</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</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">is_parameter</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Descriptions::to_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">adapt_region</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Instances::of_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">Descriptions::to_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">), </span><span class="identifier-syntax">K_region</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP5_2_3" class="named-paragraph-link"><span class="named-paragraph">Handle a regional containment test ad-hoc</span><span class="named-paragraph-number">5.2.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">compiled_ad_hoc</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="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">compiled_ad_hoc</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">ACTION_PATTERN_COMPILATION</span><span class="plain-syntax">, </span><span class="string-syntax">"[Value-matcher compiles ad-hoc code]\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-map.html#SP5_2_4" class="named-paragraph-link"><span class="named-paragraph">Match as a proposition</span><span class="named-paragraph-number">5.2.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP5">&#167;5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2_1" class="paragraph-anchor"></a><b>&#167;5.2.1. </b>So there are four different implementations &mdash; three exceptions, then one
general case.
</p>
<p class="commentary">The first handles, say, "a Queen listed in the Table of Monarchs".
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Handle table entries ad-hoc</span><span class="named-paragraph-number">5.2.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">Node::no_children</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">) != </span><span class="constant-syntax">2</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"MPE with bad no of args"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lv.html#SP10" class="function-link"><span class="function-syntax">LocalVariables::add_table_lookup</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ct_0_lv</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP12" class="function-link"><span class="function-syntax">LocalVariables::find_internal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"ct_0"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ct_0_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP1" class="function-link"><span class="function-syntax">LocalVariables::declare</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ct_0_lv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ct_1_lv</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP12" class="function-link"><span class="function-syntax">LocalVariables::find_internal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"ct_1"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ct_1_s</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP1" class="function-link"><span class="function-syntax">LocalVariables::declare</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ct_1_lv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">ct_1_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">EXISTSTABLEROWCORR_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">STORE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::ref_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">ct_0_s</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cv.html#SP5" class="function-link"><span class="function-syntax">CompileValues::to_code_val</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><a href="2-cv.html#SP5" class="function-link"><span class="function-syntax">CompileValues::to_code_val</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cv.html#SP5" class="function-link"><span class="function-syntax">CompileValues::to_code_val</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">val</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP5_2">&#167;5.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2_2" class="paragraph-anchor"></a><b>&#167;5.2.2. </b>The first case here might handle the "anything" in "asking Fred about anything"
or the it in "asking Fred about it"; the second, "asking Fred about "scooby snacks"".
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Handle a constant snippet ad-hoc</span><span class="named-paragraph-number">5.2.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">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;understanding-action-irregular-operand&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;&lt;r&gt;&gt;</span><span class="plain-syntax"> == </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) </span><span class="identifier-syntax">EmitCode::val_true</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;&lt;r&gt;&gt;</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">EmitCode::val_false</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">NE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">INDIRECT2_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><a href="2-cv.html#SP5" class="function-link"><span class="function-syntax">CompileValues::to_code_val</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">CONSULT_FROM_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">CONSULT_WORDS_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::val_iname</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">GPR_FAIL_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP5_2">&#167;5.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2_3" class="paragraph-anchor"></a><b>&#167;5.2.3. </b>For some clauses, such as "going from R" or "in R", we want to allow for "R"
to be allowed to be a region and not just a room. But only for certain clauses,
so this is used only when the function was called with <span class="extract"><span class="extract-syntax">adapt_region</span></span> set.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Handle a regional containment test ad-hoc</span><span class="named-paragraph-number">5.2.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="identifier-syntax">EmitCode::call</span><span class="plain-syntax">(</span><span class="identifier-syntax">Hierarchy::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">TESTREGIONALCONTAINMENT_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::down</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><a href="2-cv.html#SP5" class="function-link"><span class="function-syntax">CompileValues::to_code_val</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">val</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-cv.html#SP5" class="function-link"><span class="function-syntax">CompileValues::to_code_val</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">EmitCode::up</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP5_2">&#167;5.2</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP5_2_4" class="paragraph-anchor"></a><b>&#167;5.2.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Match as a proposition</span><span class="named-paragraph-number">5.2.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">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prop</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Specifications::is_description</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">)) </span><span class="identifier-syntax">prop</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Descriptions::to_proposition</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</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">prop</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">prop</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SentencePropositions::from_spec</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</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">prop</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">"unable to force proposition"</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">verify_as_kind</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">prop</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Propositions::concatenate</span><span class="plain-syntax">(</span><span class="identifier-syntax">prop</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">KindPredicates::new_atom</span><span class="plain-syntax">(</span><span class="identifier-syntax">verify_as_kind</span><span class="plain-syntax">, </span><span class="identifier-syntax">Terms::new_variable</span><span class="plain-syntax">(0)));</span>
<span class="plain-syntax"> </span><a href="4-cp.html#SP7" class="function-link"><span class="function-syntax">CompilePropositions::verify_descriptive</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">prop</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"an action or activity to apply to things matching a given description"</span><span class="plain-syntax">, </span><span class="identifier-syntax">spec</span><span class="plain-syntax">);</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">ACTION_PATTERN_COMPILATION</span><span class="plain-syntax">, </span><span class="string-syntax">"[Value-matcher faces proposition: $D]\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">prop</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TypecheckPropositions::type_check</span><span class="plain-syntax">(</span><span class="identifier-syntax">prop</span><span class="plain-syntax">, </span><span class="identifier-syntax">TypecheckPropositions::tc_no_problem_reporting</span><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><a href="4-cp.html#SP1" class="function-link"><span class="function-syntax">CompilePropositions::to_test_as_condition</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">val</span><span class="plain-syntax">, </span><span class="identifier-syntax">prop</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-map.html#SP5_2">&#167;5.2</a>.</li></ul>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="2-cc.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-im.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresssection"><a href="2-cv.html">cv</a></li><li class="progresssection"><a href="2-cr.html">cr</a></li><li class="progresssection"><a href="2-cl.html">cl</a></li><li class="progresssection"><a href="2-cc.html">cc</a></li><li class="progresscurrent">map</li><li class="progresssection"><a href="2-mgap.html">mgap</a></li><li class="progresschapter"><a href="3-sf.html">3</a></li><li class="progresschapter"><a href="4-cs.html">4</a></li><li class="progresschapter"><a href="5-cbal.html">5</a></li><li class="progressnext"><a href="2-mgap.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>