1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 10:04:21 +03:00
inform7/docs/core-module/25-ci.html
2020-08-25 21:47:14 +01:00

836 lines
145 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Compile Invocations</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="../compiler.html">compiler tools</a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul><h2>Compiler Webs</h2><ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
</ul><h2>Inbuild Modules</h2><ul>
<li><a href="../supervisor-module/index.html">supervisor</a></li>
</ul><h2>Inform7 Modules</h2><ul>
<li><a href="index.html"><span class="selectedlink">core</span></a></li>
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="../index-module/index.html">index</a></li>
</ul><h2>Inter Modules</h2><ul>
<li><a href="../bytecode-module/index.html">bytecode</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul><h2>Services</h2><ul>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../calculus-module/index.html">calculus</a></li>
<li><a href="../html-module/index.html">html</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Compile Invocations' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7 Modules</a></li><li><a href="index.html">core</a></li><li><a href="index.html#25">Chapter 25: Compilation</a></li><li><b>Compile Invocations</b></li></ul></div>
<p class="purpose">Here we generate Inform 6 code to execute the phrase(s) called for by an invocation list.</p>
<ul class="toc"><li><a href="25-ci.html#SP2">&#167;2. Top level: compiling lists</a></li><li><a href="25-ci.html#SP3">&#167;3. Lower level: compiling single invocations</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>This represents the tokens being used when invoking a phrase:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">tokens_packet</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">tokens_count</span><span class="plain-syntax">; </span><span class="comment-syntax"> number of arguments to phrase</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">args</span><span class="plain-syntax">[32]; </span><span class="comment-syntax"> what they are</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_required</span><span class="plain-syntax">[32]; </span><span class="comment-syntax"> what pointer kinds of value, if they are</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">as_requested</span><span class="plain-syntax">; </span><span class="comment-syntax"> kind for the function call</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">tokens_packet</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure tokens_packet is accessed in 25/ciac, 25/cii and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. Top level: compiling lists. </b>The invocation list will consist of at least one invocation, and all of these
except possibly the last one will be "unproven" by the type-checking
apparatus &mdash; that is, will not be safe to execute without run-time checking.
We must execute exactly one invocation in the list &mdash; the first one which
is found to be type-safe &mdash; or else produce a run-time error message.
</p>
<p class="commentary">It follows that there is only one case where no checking is needed: when
the list consists of a single proven invocation. This we compile directly
to the I6 stream. In all other cases, we compile a function call to a
"resolver routine" to the I6 stream, delegating the choice to an
external routine: and we will probably have to compile this routine, too,
unless the decision on this block is one that we recognise from an
earlier invocation list (in what may be another setting entirely).
</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">Invocations::Compiler::compile_invocation_list</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">Invocations::Compiler::compile_invocation_list</span></span>:<br/>RValues - <a href="14-rv.html#SP24">&#167;24</a><br/>Compile Phrases - <a href="25-cp.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">value_holster</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VH</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">invl</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</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">VH</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">vhmode_wanted</span><span class="plain-syntax"> == </span><span class="identifier-syntax">INTER_VAL_VHMODE</span><span class="plain-syntax">) </span><span class="identifier-syntax">VH</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">vhmode_provided</span><span class="plain-syntax"> = </span><span class="identifier-syntax">INTER_VAL_VHMODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">VH</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">vhmode_provided</span><span class="plain-syntax"> = </span><span class="identifier-syntax">INTER_VOID_VHMODE</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">wn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="25-in.html#SP23" class="function-link"><span class="function-syntax">Invocations::length_of_list</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">invl</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">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Compiling from %d invocations\n"</span><span class="plain-syntax">, </span><a href="25-in.html#SP23" class="function-link"><span class="function-syntax">Invocations::length_of_list</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">invl</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">source_location</span><span class="plain-syntax"> </span><span class="identifier-syntax">sl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexer::word_location</span><span class="plain-syntax">(</span><span class="identifier-syntax">wn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="25-in.html#SP10" class="function-link"><span class="function-syntax">Invocations::is_marked_to_save_self</span></a><span class="plain-syntax">(</span><a href="25-in.html#SP24" class="function-link"><span class="function-syntax">Invocations::first_in_list</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">invl</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">PUSH_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_iname</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><a href="27-hr.html#SP4" class="function-link"><span class="function-syntax">Hierarchy::find</span></a><span class="plain-syntax">(</span><span class="constant-syntax">SELF_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><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><a href="25-in.html#SP10" class="function-link"><span class="function-syntax">Invocations::is_marked_unproven</span></a><span class="plain-syntax">(</span><a href="25-in.html#SP24" class="function-link"><span class="function-syntax">Invocations::first_in_list</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">invl</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2" class="named-paragraph-link"><span class="named-paragraph">Compile using run-time resolution to choose between invocations</span><span class="named-paragraph-number">2.2</span></a></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="25-ci.html#SP2_1" class="named-paragraph-link"><span class="named-paragraph">Compile as a series of invocations all of which run</span><span class="named-paragraph-number">2.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><a href="25-in.html#SP10" class="function-link"><span class="function-syntax">Invocations::is_marked_to_save_self</span></a><span class="plain-syntax">(</span><a href="25-in.html#SP24" class="function-link"><span class="function-syntax">Invocations::first_in_list</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">invl</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">PULL_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_iname</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><a href="27-hr.html#SP4" class="function-link"><span class="function-syntax">Hierarchy::find</span></a><span class="plain-syntax">(</span><span class="constant-syntax">SELF_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2_1" class="paragraph-anchor"></a><b>&#167;2.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile as a series of invocations all of which run</span><span class="named-paragraph-number">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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pos</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_INVOCATION_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">invl</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">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"C%d: $e\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">inv</span><span class="plain-syntax">); </span><span class="identifier-syntax">pos</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_say_verb</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><a href="7-vart.html#SP3" class="function-link"><span class="function-syntax">VerbsAtRunTime::ConjugateVerb_invoke_emit</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::get_say_verb</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::get_modal_verb</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="constant-syntax">say_verb_negated_ANNOT</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">Node::get_say_adjective</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><a href="7-am.html#SP44" class="function-link"><span class="function-syntax">Adjectives::Meanings::emit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_say_adjective</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</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="25-ci.html#SP2_1_1" class="named-paragraph-link"><span class="named-paragraph">Otherwise, use the standard way to compile an invoked phrase</span><span class="named-paragraph-number">2.1.1</span></a></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="25-ci.html#SP2">&#167;2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_1_1" class="paragraph-anchor"></a><b>&#167;2.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Otherwise, use the standard way to compile an invoked phrase</span><span class="named-paragraph-number">2.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">phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ph</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_phrase_invoked</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">tokens_packet</span><span class="plain-syntax"> </span><span class="identifier-syntax">tokens</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_1_1_1" class="named-paragraph-link"><span class="named-paragraph">First construct an arguments packet</span><span class="named-paragraph-number">2.1.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">value_holster</span><span class="plain-syntax"> </span><span class="identifier-syntax">VH2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Holsters::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">VH</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">vhmode_wanted</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">returned_in_manner</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><a href="25-ci.html#SP3" class="function-link"><span class="function-syntax">Invocations::Compiler::compile_single_invocation</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">VH2</span><span class="plain-syntax">, </span><span class="identifier-syntax">inv</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">sl</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">tokens</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">phrase_being_compiled</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">returned_in_manner</span><span class="plain-syntax"> != </span><span class="constant-syntax">DONT_KNOW_MOR</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_1_1_2" class="named-paragraph-link"><span class="named-paragraph">If the invocation compiled to a return from a function, check this is allowed</span><span class="named-paragraph-number">2.1.1.2</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="25-ci.html#SP2_1">&#167;2.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_1_1_1" class="paragraph-anchor"></a><b>&#167;2.1.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">First construct an arguments packet</span><span class="named-paragraph-number">2.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">tokens</span><span class="plain-syntax">.</span><span class="identifier-syntax">tokens_count</span><span class="plain-syntax"> = </span><a href="25-in.html#SP17" class="function-link"><span class="function-syntax">Invocations::get_no_tokens_needed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</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">tokens</span><span class="plain-syntax">.</span><span class="element-syntax">tokens_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="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">val</span><span class="plain-syntax"> = </span><a href="25-in.html#SP16" class="function-link"><span class="function-syntax">Invocations::get_token_as_parsed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</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">K</span><span class="plain-syntax"> = </span><a href="14-sp.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ph</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">type_data</span><span class="plain-syntax">.</span><span class="element-syntax">token_sequence</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">to_match</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="22-ptd.html#SP25" class="function-link"><span class="function-syntax">Phrases::TypeData::invoked_inline</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ph</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">Kinds::Behaviour::definite</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</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">tokens</span><span class="plain-syntax">.</span><span class="element-syntax">kind_required</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><a href="14-sp.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</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="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">tokens</span><span class="plain-syntax">.</span><span class="element-syntax">kind_required</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">K</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">ph</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">type_data</span><span class="plain-syntax">.</span><span class="element-syntax">token_sequence</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">construct</span><span class="plain-syntax"> == </span><span class="constant-syntax">KIND_NAME_PT_CONSTRUCT</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">tokens</span><span class="plain-syntax">.</span><span class="element-syntax">args</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><a href="14-rv.html#SP6" class="function-link"><span class="function-syntax">Rvalues::new_nothing_object_constant</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">tokens</span><span class="plain-syntax">.</span><span class="element-syntax">args</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">val</span><span class="plain-syntax">;</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">return_kind</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_kind_resulting</span><span class="plain-syntax">(</span><a href="25-in.html#SP24" class="function-link"><span class="function-syntax">Invocations::first_in_list</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">invl</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">return_kind</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">ph</span><span class="plain-syntax">)) </span><span class="identifier-syntax">return_kind</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ph</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">type_data</span><span class="plain-syntax">.</span><span class="element-syntax">return_kind</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">tokens</span><span class="plain-syntax">.</span><span class="identifier-syntax">as_requested</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::function_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">tokens</span><span class="plain-syntax">.</span><span class="element-syntax">tokens_count</span><span class="plain-syntax">, </span><span class="identifier-syntax">tokens</span><span class="plain-syntax">.</span><span class="element-syntax">kind_required</span><span class="plain-syntax">, </span><span class="identifier-syntax">return_kind</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="25-ci.html#SP2_1_1">&#167;2.1.1</a>, <a href="25-ci.html#SP2_2_3_3_1">&#167;2.2.3.3.1</a>, <a href="25-ci.html#SP2_2_3_4_1">&#167;2.2.3.4.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_1_1_2" class="paragraph-anchor"></a><b>&#167;2.1.1.2. </b>For example, a standard "To..." phrase isn't allowed to contain the invocation
</p>
<blockquote>
<p>decide on 178;</p>
</blockquote>
<p class="commentary">since it isn't a phrase to decide anything. This is where that's checked:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">If the invocation compiled to a return from a function, check this is allowed</span><span class="named-paragraph-number">2.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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">manner_expected</span><span class="plain-syntax"> = </span><span class="identifier-syntax">phrase_being_compiled</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">type_data</span><span class="plain-syntax">.</span><span class="element-syntax">manner_of_return</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">returned_in_manner</span><span class="plain-syntax"> != </span><span class="identifier-syntax">manner_expected</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">manner_expected</span><span class="plain-syntax"> != </span><span class="constant-syntax">DECIDES_NOTHING_AND_RETURNS_MOR</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"C%d: $e: returned in manner %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">returned_in_manner</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"vs Phrase being compiled: %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">manner_expected</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(2,</span>
<span class="plain-syntax"> </span><a href="22-ptd.html#SP11" class="function-link"><span class="function-syntax">Phrases::TypeData::describe_manner_of_return</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">returned_in_manner</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</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">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</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">Problems::quote_text</span><span class="plain-syntax">(3,</span>
<span class="plain-syntax"> </span><a href="22-ptd.html#SP11" class="function-link"><span class="function-syntax">Phrases::TypeData::describe_manner_of_return</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">manner_expected</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> &amp;(</span><span class="identifier-syntax">phrase_being_compiled</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">type_data</span><span class="plain-syntax">), &amp;</span><span class="identifier-syntax">K</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</span><span class="plain-syntax">) </span><a href="2-sq.html#SP3" class="function-link"><span class="function-syntax">Problems::quote_kind</span></a><span class="plain-syntax">(4, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><a href="1-wtc.html#SP6" class="function-link"><span class="function-syntax">Task::syntax_tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_WrongEndToPhrase</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</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The line %1 seems to be a way that the phrase you're defining can come "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"to an end, with %2, but it should always end up with a phrase to "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"decide %4."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The line %1 seems to be a way that the phrase you're defining can come "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"to an end, with %2, but it should always end up with %3."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</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="25-ci.html#SP2_1_1">&#167;2.1.1</a>, <a href="25-ci.html#SP2_2_3_3_1_3">&#167;2.2.3.3.1.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2" class="paragraph-anchor"></a><b>&#167;2.2. </b>We get to here if the first invocation is unproven, meaning that at compile
time it was impossible to determine whether it was type-safe to execute. We must
therefore compile code to determine this at run-time.
</p>
<p class="commentary">There are two basic forms of this: "void mode", where the phrases are going to
be Inform 6 statements in a void context, and "value mode", where the phrases
will be expressions being evaluated.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile using run-time resolution to choose between invocations</span><span class="named-paragraph-number">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">phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ph</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_phrase_invoked</span><span class="plain-syntax">(</span><a href="25-in.html#SP24" class="function-link"><span class="function-syntax">Invocations::first_in_list</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">invl</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><a href="25-in.html#SP16" class="function-link"><span class="function-syntax">Invocations::get_no_tokens</span></a><span class="plain-syntax">(</span><a href="25-in.html#SP24" class="function-link"><span class="function-syntax">Invocations::first_in_list</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">invl</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="24-sf.html#SP13" class="function-link"><span class="function-syntax">Frames::need_at_least_this_many_formals</span></a><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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">void_mode</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">ph</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">type_data</span><span class="plain-syntax">.</span><span class="element-syntax">manner_of_return</span><span class="plain-syntax"> == </span><span class="constant-syntax">DECIDES_NOTHING_MOR</span><span class="plain-syntax">) </span><span class="identifier-syntax">void_mode</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="25-ci.html#SP2_2_3" class="named-paragraph-link"><span class="named-paragraph">Compile the resolution</span><span class="named-paragraph-number">2.2.3</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="25-ci.html#SP2">&#167;2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2_1" class="paragraph-anchor"></a><b>&#167;2.2.1. </b>Our basic idea is best explained in void mode, where it's much simpler to
carry out. Suppose we have invocations I1, ..., In, and tokens T1, ..., Tm.
(In a group like this, every invocation will have the same number of tokens.)
We want each invocation in turn to try to handle the situation, and to stop
as soon as one of them does. The first thought is this:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> if (condition for I1 to be valid) invoke I1(T1, ..., Tm);</span>
<span class="plain-syntax"> else if (condition for I2 to be valid) invoke I2(T1, ..., Tm);</span>
<span class="plain-syntax"> ...</span>
<span class="plain-syntax"> else run-time-error-message();</span>
</pre>
<p class="commentary">where the chain of execution runs into the error message code only if none
of I1, ..., In can be applied. In fact, it will sometimes happen that the
final invocation can be proved applicable at compile time, and then we'll
compile this instead:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> if (condition for I1 to be valid) invoke I1(T1, ..., Tm);</span>
<span class="plain-syntax"> else if (condition for I2 to be valid) invoke I2(T1, ..., Tm);</span>
<span class="plain-syntax"> else invoke In(T1, ..., Tm);</span>
</pre>
<p class="commentary">Note that it's not possible for an intermediate invocation in the group to
be provably correct, because if it is then we wouldn't have collected any
further possibilities.
</p>
<p class="commentary firstcommentary"><a id="SP2_2_2" class="paragraph-anchor"></a><b>&#167;2.2.2. </b>That's almost what we do, but not quite. The problem lies in the fact that
the tokens T1, ..., Tm are evaluated multiple times - not in the invocations
(since only one is reached in execution) but in the condition tests. This
multiple evaluation would be incorrect if token evaluation had side-effects,
as it easily might (for example if T1 were a call to some phrase to decide
something, and that phrase had side-effects). So in fact we modify our
scheme like so:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> formal_par1 = T1;</span>
<span class="plain-syntax"> formal_par2 = T2;</span>
<span class="plain-syntax"> ...</span>
<span class="plain-syntax"> if (condition for I1 to be valid) invoke I1(formal_par1, ..., formal_parm);</span>
<span class="plain-syntax"> else if (condition for I2 to be valid) invoke I2(formal_par1, ..., formal_parm);</span>
<span class="plain-syntax"> ...</span>
<span class="plain-syntax"> else run-time-error-message();</span>
</pre>
<p class="commentary">This fixes the side-effect problem, provided we compile the conditions so
that they measure the "formal parameters" instead of the original T1, T2, ...
But another possible trap is that the <span class="extract"><span class="extract-syntax">formal_par1</span></span>, ..., variables need
to be local to the current I6 stack frame, since evaluation of T2, say,
might itself involve a call to another phrase which recursively needs to
make a resolution itself.
</p>
<p class="commentary">Finding local storage here is more problematic than it looks. I6 has an
absolute limit on the number of local variables, imposed by the virtual
machines it runs on. We can't create any local stack space, because the
stack isn't memory-accessible on either of the VMs Inform compiles to. It's
not reliable to create an auxiliary stack in main memory, because this
couldn't resize on the Z-machine, and we want to avoid use of the heap,
because we want Inform to carry on working even in cramped Z-machine cases
where there's no memory for any heap at all. What we do, then, is to store
<span class="extract"><span class="extract-syntax">formal_par1</span></span> et seq as global I6 variables, and to use an outer shell
routine to push and pull their values, thus in effect making them additional
locals, albeit at a small performance hit.
</p>
<p class="commentary firstcommentary"><a id="SP2_2_3" class="paragraph-anchor"></a><b>&#167;2.2.3. </b>In value mode we want the same strategy and code paths, but all in
the context of a value.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile the resolution</span><span class="named-paragraph-number">2.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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">void_mode</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2_3_1" class="named-paragraph-link"><span class="named-paragraph">Compile code to set the formal parameters in void mode</span><span class="named-paragraph-number">2.2.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2_3_3" class="named-paragraph-link"><span class="named-paragraph">Compile code to apply the first invocation which is applicable</span><span class="named-paragraph-number">2.2.3.3</span></a></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">Produce::inv_primitive</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">TERNARYSEQUENTIAL_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><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">no_conditions_tested</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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Produce::level</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2_3_2" class="named-paragraph-link"><span class="named-paragraph">Emit code to set the formal parameters in expression mode</span><span class="named-paragraph-number">2.2.3.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">L</span><span class="plain-syntax"> != </span><span class="identifier-syntax">Produce::level</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">())) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"formal parameter expression error"</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">NC</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">unprov</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">prov</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2_3_5" class="named-paragraph-link"><span class="named-paragraph">Count the applicability conditions</span><span class="named-paragraph-number">2.2.3.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="string-syntax">"Think %d unprov %d prov %d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">NC</span><span class="plain-syntax">, </span><span class="identifier-syntax">unprov</span><span class="plain-syntax">, </span><span class="identifier-syntax">prov</span><span class="plain-syntax">); </span><a href="27-em.html#SP3" class="function-link"><span class="function-syntax">Emit::code_comment</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">); </span><span class="identifier-syntax">DISCARD_TEXT</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">unprov</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">OR_BIP</span><span class="plain-syntax">); </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">()); }</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2_3_4" class="named-paragraph-link"><span class="named-paragraph">Compile code to apply the first invocation which is applicable, as expression</span><span class="named-paragraph-number">2.2.3.4</span></a></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"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">NC</span><span class="plain-syntax">-1; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</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">prov</span><span class="plain-syntax">) </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</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">unprov</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2_3_6" class="named-paragraph-link"><span class="named-paragraph">Compile code for the execution path where no invocations were applicable</span><span class="named-paragraph-number">2.2.3.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><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">L</span><span class="plain-syntax"> != </span><span class="identifier-syntax">Produce::level</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">())) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"applicability expression error"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_iname</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><a href="27-hr.html#SP4" class="function-link"><span class="function-syntax">Hierarchy::find</span></a><span class="plain-syntax">(</span><span class="constant-syntax">FORMAL_RV_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="25-ci.html#SP2_2">&#167;2.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2_3_1" class="paragraph-anchor"></a><b>&#167;2.2.3.1. </b>In void mode, this code is simple: it just produces a list of assignments:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> formal_par1 = T1;</span>
<span class="plain-syntax"> formal_par2 = T2;</span>
<span class="plain-syntax"> ...</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile code to set the formal parameters in void mode</span><span class="named-paragraph-number">2.2.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">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">N</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="25-ci.html#SP2_2_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Compile the actual assignment</span><span class="named-paragraph-number">2.2.3.1.1</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="25-ci.html#SP2_2_3">&#167;2.2.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2_3_2" class="paragraph-anchor"></a><b>&#167;2.2.3.2. </b>In value mode, we exploit the fact that, as in C, assignments return a value
and are therefore legal in an expression context; but, again avoiding the
serial comma at the cost of a fruitless addition,
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> (formal_parn = Tn) + ... + (formal_par1 = T1)</span>
</pre>
<p class="commentary">Again, this is written in reverse order because I6 will evaluate this from
right to left: we want T1 to evaluate first, then T2, and so on.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Emit code to set the formal parameters in expression mode</span><span class="named-paragraph-number">2.2.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">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">=</span><span class="identifier-syntax">N</span><span class="plain-syntax">-1; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&gt;=0; </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">i</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">PLUS_BIP</span><span class="plain-syntax">); </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">()); }</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Compile the actual assignment</span><span class="named-paragraph-number">2.2.3.1.1</span></a></span><span class="plain-syntax">;</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">=</span><span class="identifier-syntax">N</span><span class="plain-syntax">-1; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&gt;0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">--) </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="25-ci.html#SP2_2_3">&#167;2.2.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2_3_1_1" class="paragraph-anchor"></a><b>&#167;2.2.3.1.1. </b>A parameter corresponding to the name of a kind has no meaningful value
at run-time; we assign 0 to it for the sake of tidiness.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile the actual assignment</span><span class="named-paragraph-number">2.2.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><a href="6-nv.html#SP19" class="function-link"><span class="function-syntax">NonlocalVariables::temporary_formal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><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">Produce::down</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_iname</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><a href="6-nv.html#SP19" class="function-link"><span class="function-syntax">NonlocalVariables::formal_par</span></a><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">ph</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">type_data</span><span class="plain-syntax">.</span><span class="element-syntax">token_sequence</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">construct</span><span class="plain-syntax"> == </span><span class="constant-syntax">KIND_NAME_PT_CONSTRUCT</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</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">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">BEGIN_COMPILATION_MODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">COMPILATION_MODE_ENTER</span><span class="plain-syntax">(</span><span class="constant-syntax">DEREFERENCE_POINTERS_CMODE</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">value</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><a href="25-in.html#SP16" class="function-link"><span class="function-syntax">Invocations::get_token_as_parsed</span></a><span class="plain-syntax">(</span><a href="25-in.html#SP24" class="function-link"><span class="function-syntax">Invocations::first_in_list</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">invl</span><span class="plain-syntax">), </span><span class="identifier-syntax">i</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">to_be_used_as</span><span class="plain-syntax"> = </span><a href="14-sp.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ph</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">type_data</span><span class="plain-syntax">.</span><span class="element-syntax">token_sequence</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">to_match</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="14-cfs.html#SP7" class="function-link"><span class="function-syntax">Specifications::Compiler::emit_to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">, </span><span class="identifier-syntax">to_be_used_as</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="constant-syntax">END_COMPILATION_MODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="25-ci.html#SP2_2_3_1">&#167;2.2.3.1</a>, <a href="25-ci.html#SP2_2_3_2">&#167;2.2.3.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2_3_3" class="paragraph-anchor"></a><b>&#167;2.2.3.3. </b>So now we come to the part which switches the execution stream. In void mode,
it will look like so:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> if (condition for I1 to be valid) invoke I1;</span>
<span class="plain-syntax"> else if (condition for I2 to be valid) invoke I2;</span>
<span class="plain-syntax"> ...</span>
<span class="plain-syntax"> else run-time-error-message();</span>
</pre>
<p class="commentary">but in value mode, where invocations return values,
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> ((condition for I1 to be valid) &amp;&amp; ((formal_rv = I1) bitwise-or 1))</span>
<span class="plain-syntax"> logical-or ((condition for I2 to be valid) &amp;&amp; ((formal_rv = I2) bitwise-or 1))</span>
<span class="plain-syntax"> ...</span>
</pre>
<p class="commentary">The key here is that I6, like C, evaluates operands of <span class="extract"><span class="extract-syntax">&amp;&amp;</span></span> left to right
and short-circuits: if the left operand is false, the right is never evaluated,
and its side-effect (of invoking a phrase and setting <span class="extract"><span class="extract-syntax">formal_rv</span></span>) never
happens; and similarly for logical-or. Bitwise or doesn't have that property,
and the ridiculous trick of bitwise-or-ing with 1 ensures that any value is
made non-zero, so that the assignment is always regarded by I6 as "true".
This in turn means that if any invocation is reached in this expression,
no subsequent lines are looked at.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile code to apply the first invocation which is applicable</span><span class="named-paragraph-number">2.2.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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_conditions_tested</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">if_depth</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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pos</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">last_inv</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_INVOCATION_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">invl</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">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"RC%d: $e\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">inv</span><span class="plain-syntax">); </span><span class="identifier-syntax">pos</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_inv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inv</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">no_conditions_tested</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">void_mode</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</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="25-ci.html#SP2_2_3_3_1" class="named-paragraph-link"><span class="named-paragraph">Compile code to apply this invocation if it's applicable</span><span class="named-paragraph-number">2.2.3.3.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><a href="25-in.html#SP10" class="function-link"><span class="function-syntax">Invocations::is_marked_unproven</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">last_inv</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2_3_6" class="named-paragraph-link"><span class="named-paragraph">Compile code for the execution path where no invocations were applicable</span><span class="named-paragraph-number">2.2.3.6</span></a></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">if_depth</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">()); </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">()); </span><span class="identifier-syntax">if_depth</span><span class="plain-syntax">--; }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="25-ci.html#SP2_2_3">&#167;2.2.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2_3_4" class="paragraph-anchor"></a><b>&#167;2.2.3.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile code to apply the first invocation which is applicable, as expression</span><span class="named-paragraph-number">2.2.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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pos</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">last_inv</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_INVOCATION_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">invl</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">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"RC%d: $e\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">inv</span><span class="plain-syntax">); </span><span class="identifier-syntax">pos</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_inv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2_3_4_1" class="named-paragraph-link"><span class="named-paragraph">Compile code to apply this invocation if it's applicable, expression version</span><span class="named-paragraph-number">2.2.3.4.1</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="25-ci.html#SP2_2_3">&#167;2.2.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2_3_5" class="paragraph-anchor"></a><b>&#167;2.2.3.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Count the applicability conditions</span><span class="named-paragraph-number">2.2.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="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">last_inv</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_INVOCATION_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">invl</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">checks_needed</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">last_inv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inv</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><a href="25-in.html#SP16" class="function-link"><span class="function-syntax">Invocations::get_no_tokens</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</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">check_against</span><span class="plain-syntax"> = </span><a href="25-in.html#SP16" class="function-link"><span class="function-syntax">Invocations::get_token_check_to_do</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</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">check_against</span><span class="plain-syntax">) </span><span class="identifier-syntax">checks_needed</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">checks_needed</span><span class="plain-syntax">) </span><span class="identifier-syntax">NC</span><span class="plain-syntax">++; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">prov</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><a href="25-in.html#SP10" class="function-link"><span class="function-syntax">Invocations::is_marked_unproven</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">last_inv</span><span class="plain-syntax">)) </span><span class="identifier-syntax">unprov</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="25-ci.html#SP2_2_3">&#167;2.2.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2_3_6" class="paragraph-anchor"></a><b>&#167;2.2.3.6. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile code for the execution path where no invocations were applicable</span><span class="named-paragraph-number">2.2.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">no_conditions_tested</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">"condition proof error"</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">void_mode</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_call_iname</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><a href="27-hr.html#SP4" class="function-link"><span class="function-syntax">Hierarchy::find</span></a><span class="plain-syntax">(</span><span class="constant-syntax">ARGUMENTTYPEFAILED_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) </span><span class="identifier-syntax">sl</span><span class="plain-syntax">.</span><span class="identifier-syntax">line_number</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inform_extension</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Extensions::corresponding_to</span><span class="plain-syntax">(</span><span class="identifier-syntax">sl</span><span class="plain-syntax">.</span><span class="identifier-syntax">file_of_origin</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">E</span><span class="plain-syntax">) </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="25-ci.html#SP2_2_3">&#167;2.2.3</a>, <a href="25-ci.html#SP2_2_3_3">&#167;2.2.3.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2_3_3_1" class="paragraph-anchor"></a><b>&#167;2.2.3.3.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile code to apply this invocation if it's applicable</span><span class="named-paragraph-number">2.2.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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_say_verb</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="7-vart.html#SP3" class="function-link"><span class="function-syntax">VerbsAtRunTime::ConjugateVerb_invoke_emit</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::get_say_verb</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::get_modal_verb</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="constant-syntax">say_verb_negated_ANNOT</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">Node::get_say_adjective</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="7-am.html#SP44" class="function-link"><span class="function-syntax">Adjectives::Meanings::emit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_say_adjective</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</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">phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ph</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_phrase_invoked</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">tokens_packet</span><span class="plain-syntax"> </span><span class="identifier-syntax">tokens</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_1_1_1" class="named-paragraph-link"><span class="named-paragraph">First construct an arguments packet</span><span class="named-paragraph-number">2.1.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2_3_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Substitute the formal parameter variables into the tokens</span><span class="named-paragraph-number">2.2.3.3.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2_3_3_1_2" class="named-paragraph-link"><span class="named-paragraph">Compile the check on invocation applicability, emission version</span><span class="named-paragraph-number">2.2.3.3.1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2_3_3_1_3" class="named-paragraph-link"><span class="named-paragraph">Compile the invocation part, emission version</span><span class="named-paragraph-number">2.2.3.3.1.3</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="25-ci.html#SP2_2_3_3">&#167;2.2.3.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2_3_4_1" class="paragraph-anchor"></a><b>&#167;2.2.3.4.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile code to apply this invocation if it's applicable, expression version</span><span class="named-paragraph-number">2.2.3.4.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::get_say_verb</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="7-vart.html#SP3" class="function-link"><span class="function-syntax">VerbsAtRunTime::ConjugateVerb_invoke_emit</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::get_say_verb</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::get_modal_verb</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="constant-syntax">say_verb_negated_ANNOT</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">Node::get_say_adjective</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="7-am.html#SP44" class="function-link"><span class="function-syntax">Adjectives::Meanings::emit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_say_adjective</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</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">phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ph</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_phrase_invoked</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">tokens_packet</span><span class="plain-syntax"> </span><span class="identifier-syntax">tokens</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_1_1_1" class="named-paragraph-link"><span class="named-paragraph">First construct an arguments packet</span><span class="named-paragraph-number">2.1.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2_3_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Substitute the formal parameter variables into the tokens</span><span class="named-paragraph-number">2.2.3.3.1.1</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">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Produce::level</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">()), </span><span class="identifier-syntax">or_made</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">ands_made</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2_3_4_1_1" class="named-paragraph-link"><span class="named-paragraph">Compile the check on invocation applicability, expression version</span><span class="named-paragraph-number">2.2.3.4.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2_3_3_1_3" class="named-paragraph-link"><span class="named-paragraph">Compile the invocation part, emission version</span><span class="named-paragraph-number">2.2.3.3.1.3</span></a></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">ands_made</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><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">target</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">or_made</span><span class="plain-syntax">) </span><span class="identifier-syntax">target</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">target</span><span class="plain-syntax"> != </span><span class="identifier-syntax">Produce::level</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">())) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"levels wrong"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="25-ci.html#SP2_2_3_4">&#167;2.2.3.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2_3_3_1_1" class="paragraph-anchor"></a><b>&#167;2.2.3.3.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Substitute the formal parameter variables into the tokens</span><span class="named-paragraph-number">2.2.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="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">tokens</span><span class="plain-syntax">.</span><span class="element-syntax">tokens_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">nonlocal_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nlv</span><span class="plain-syntax"> = </span><a href="6-nv.html#SP19" class="function-link"><span class="function-syntax">NonlocalVariables::temporary_formal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="6-nv.html#SP18" class="function-link"><span class="function-syntax">NonlocalVariables::set_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nlv</span><span class="plain-syntax">, </span><span class="identifier-syntax">tokens</span><span class="plain-syntax">.</span><span class="element-syntax">kind_required</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">tokens</span><span class="plain-syntax">.</span><span class="element-syntax">args</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><a href="14-lv.html#SP2" class="function-link"><span class="function-syntax">Lvalues::new_actual_NONLOCAL_VARIABLE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nlv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="25-ci.html#SP2_2_3_3_1">&#167;2.2.3.3.1</a>, <a href="25-ci.html#SP2_2_3_4_1">&#167;2.2.3.4.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2_3_3_1_2" class="paragraph-anchor"></a><b>&#167;2.2.3.3.1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile the check on invocation applicability, emission version</span><span class="named-paragraph-number">2.2.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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">check_needed</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><a href="25-in.html#SP16" class="function-link"><span class="function-syntax">Invocations::get_no_tokens</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</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">check_against</span><span class="plain-syntax"> = </span><a href="25-in.html#SP16" class="function-link"><span class="function-syntax">Invocations::get_token_check_to_do</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</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">check_against</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">check_needed</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">check_needed</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">void_mode</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">IFELSE_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2_3_3_1_2_1" class="named-paragraph-link"><span class="named-paragraph">Put the condition check here, emission version</span><span class="named-paragraph-number">2.2.3.3.1.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::code</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">if_depth</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">Produce::inv_primitive</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><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">Produce::down</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2_3_3_1_2_1" class="named-paragraph-link"><span class="named-paragraph">Put the condition check here, emission version</span><span class="named-paragraph-number">2.2.3.3.1.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">no_conditions_tested</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><a href="25-in.html#SP10" class="function-link"><span class="function-syntax">Invocations::is_marked_unproven</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"unable to compile a run-time kind check"</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="25-ci.html#SP2_2_3_3_1">&#167;2.2.3.3.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2_3_4_1_1" class="paragraph-anchor"></a><b>&#167;2.2.3.4.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile the check on invocation applicability, expression version</span><span class="named-paragraph-number">2.2.3.4.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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">check_needed</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><a href="25-in.html#SP16" class="function-link"><span class="function-syntax">Invocations::get_no_tokens</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</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">check_against</span><span class="plain-syntax"> = </span><a href="25-in.html#SP16" class="function-link"><span class="function-syntax">Invocations::get_token_check_to_do</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</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">check_against</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">check_needed</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">check_needed</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">no_conditions_tested</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">no_conditions_tested</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">NC</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">prov</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">OR_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">()); </span><span class="identifier-syntax">or_made</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">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><a href="25-in.html#SP16" class="function-link"><span class="function-syntax">Invocations::get_no_tokens</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</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">check_against</span><span class="plain-syntax"> = </span><a href="25-in.html#SP16" class="function-link"><span class="function-syntax">Invocations::get_token_check_to_do</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</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">check_against</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><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">Produce::down</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">()); </span><span class="identifier-syntax">ands_made</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="constant-syntax">BEGIN_COMPILATION_MODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">COMPILATION_MODE_EXIT</span><span class="plain-syntax">(</span><span class="constant-syntax">DEREFERENCE_POINTERS_CMODE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">nonlocal_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nlv</span><span class="plain-syntax"> = </span><a href="6-nv.html#SP19" class="function-link"><span class="function-syntax">NonlocalVariables::temporary_formal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</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><a href="14-lv.html#SP2" class="function-link"><span class="function-syntax">Lvalues::new_actual_NONLOCAL_VARIABLE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nlv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2_3_4_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Compile a check that this formal variable matches the token, emission version</span><span class="named-paragraph-number">2.2.3.4.1.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="constant-syntax">END_COMPILATION_MODE</span><span class="plain-syntax">;</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="25-ci.html#SP2_2_3_4_1">&#167;2.2.3.4.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2_3_3_1_2_1" class="paragraph-anchor"></a><b>&#167;2.2.3.3.1.2.1. </b>There may be checks needed on several tokens, so we accumulate these into
a list divided by logical-and <span class="extract"><span class="extract-syntax">&amp;&amp;</span></span> operators.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Put the condition check here, emission version</span><span class="named-paragraph-number">2.2.3.3.1.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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">and_depth</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="constant-syntax">BEGIN_COMPILATION_MODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">COMPILATION_MODE_EXIT</span><span class="plain-syntax">(</span><span class="constant-syntax">DEREFERENCE_POINTERS_CMODE</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">check_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><a href="25-in.html#SP16" class="function-link"><span class="function-syntax">Invocations::get_no_tokens</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</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">check_against</span><span class="plain-syntax"> = </span><a href="25-in.html#SP16" class="function-link"><span class="function-syntax">Invocations::get_token_check_to_do</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</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">check_against</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">check_count</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">check_count</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">check_needed</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><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">Produce::down</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">and_depth</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">nonlocal_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nlv</span><span class="plain-syntax"> = </span><a href="6-nv.html#SP19" class="function-link"><span class="function-syntax">NonlocalVariables::temporary_formal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</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><a href="14-lv.html#SP2" class="function-link"><span class="function-syntax">Lvalues::new_actual_NONLOCAL_VARIABLE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">nlv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_2_3_4_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Compile a check that this formal variable matches the token, emission version</span><span class="named-paragraph-number">2.2.3.4.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">and_depth</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">()); </span><span class="identifier-syntax">and_depth</span><span class="plain-syntax">--; }</span>
<span class="plain-syntax"> </span><span class="constant-syntax">END_COMPILATION_MODE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="25-ci.html#SP2_2_3_3_1_2">&#167;2.2.3.3.1.2</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2_3_4_1_1_1" class="paragraph-anchor"></a><b>&#167;2.2.3.4.1.1.1. </b>There are two things we might want to check, exemplified by what happens
in this situation:
</p>
<blockquote>
<p>To collate (N - an even number): ...</p>
</blockquote>
<blockquote>
<p>To collate (N - 10): ...</p>
</blockquote>
<blockquote>
<p>collate X;</p>
</blockquote>
<p class="commentary">To compile "collate X", we need to test at run-time which invocation applies.
(We actually check the second of these first, because it's more specific.)
In case we test if X is 10, in the other that X matches the description
"even number".
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile a check that this formal variable matches the token, emission version</span><span class="named-paragraph-number">2.2.3.4.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><a href="14-sp.html#SP3" class="function-link"><span class="function-syntax">Specifications::is_description</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">check_against</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><a href="12-dtd.html#SP9" class="function-link"><span class="function-syntax">Calculus::Deferrals::emit_test_if_var_matches_description</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">check_against</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><a href="8-ptu.html#SP12" class="function-link"><span class="function-syntax">ParseTreeUsage::is_value</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">check_against</span><span class="plain-syntax">)) {</span>
<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><a href="5-tc2.html#SP3" class="function-link"><span class="function-syntax">Propositions::Abstract::to_set_relation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R_equality</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NULL</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">check_against</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="12-dtd.html#SP6" class="function-link"><span class="function-syntax">Calculus::Deferrals::emit_test_of_proposition</span></a><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="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Error on: $T"</span><span class="plain-syntax">, </span><span class="identifier-syntax">check_against</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"bad check-against in run-time type check"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="25-ci.html#SP2_2_3_4_1_1">&#167;2.2.3.4.1.1</a>, <a href="25-ci.html#SP2_2_3_3_1_2_1">&#167;2.2.3.3.1.2.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2_3_3_1_3" class="paragraph-anchor"></a><b>&#167;2.2.3.3.1.3. </b>...and the actual invocation is now simple. In void mode, simply:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> invoke(formal-vars)</span>
</pre>
<p class="commentary">whereas in value mode,
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> ((formal_rv = invoke(formal-vars)) bitwise-or 1)</span>
</pre>
<p class="commentary">As noted above, the bitwise-or is a clumsy way to force the condition to
evaluate to "true" with a minimum of branches in the compiled code.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile the invocation part, emission version</span><span class="named-paragraph-number">2.2.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="reserved-syntax">if</span><span class="plain-syntax"> (!</span><span class="identifier-syntax">void_mode</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">BITWISEOR_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><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">Produce::down</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::ref_iname</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">, </span><a href="27-hr.html#SP4" class="function-link"><span class="function-syntax">Hierarchy::find</span></a><span class="plain-syntax">(</span><span class="constant-syntax">FORMAL_RV_HL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">value_holster</span><span class="plain-syntax"> </span><span class="identifier-syntax">VH2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Holsters::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">VH</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">vhmode_wanted</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">returned_in_manner</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><a href="25-ci.html#SP3" class="function-link"><span class="function-syntax">Invocations::Compiler::compile_single_invocation</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">VH2</span><span class="plain-syntax">, </span><span class="identifier-syntax">inv</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">sl</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">tokens</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">void_mode</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><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">returned_in_manner</span><span class="plain-syntax"> != </span><span class="constant-syntax">DONT_KNOW_MOR</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP2_1_1_2" class="named-paragraph-link"><span class="named-paragraph">If the invocation compiled to a return from a function, check this is allowed</span><span class="named-paragraph-number">2.1.1.2</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="25-ci.html#SP2_2_3_3_1">&#167;2.2.3.3.1</a>, <a href="25-ci.html#SP2_2_3_4_1">&#167;2.2.3.4.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. Lower level: compiling single invocations. </b></p>
<p class="commentary">Phrases to decide a condition must compile to valid I6 conditions, which
we need to ensure there are round brackets around.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Invocations::Compiler::compile_single_invocation</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">Invocations::Compiler::compile_single_invocation</span></span>:<br/><a href="25-ci.html#SP2_1_1">&#167;2.1.1</a>, <a href="25-ci.html#SP2_2_3_3_1_3">&#167;2.2.3.3.1.3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">value_holster</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VH</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inv</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">source_location</span><span class="plain-syntax"> *</span><span class="identifier-syntax">where_from</span><span class="plain-syntax">, </span><span class="reserved-syntax">tokens_packet</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tokens</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">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Compiling single invocation: $e\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="constant-syntax">BEGIN_COMPILATION_MODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ph</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_phrase_invoked</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</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">manner_of_return</span><span class="plain-syntax"> = </span><span class="constant-syntax">DONT_KNOW_MOR</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="25-ci.html#SP3_1" class="named-paragraph-link"><span class="named-paragraph">The art of invocation is delegation</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="25-ci.html#SP3_2" class="named-paragraph-link"><span class="named-paragraph">Compile a newline if the phrase implicitly requires one</span><span class="named-paragraph-number">3.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="constant-syntax">END_COMPILATION_MODE</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">manner_of_return</span><span class="plain-syntax"> != </span><span class="constant-syntax">DONT_KNOW_MOR</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">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Single invocation return manner: %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">manner_of_return</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">manner_of_return</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>The real work is done by one of the two sections following this one. Note that
only inline invocations are allowed to produce an exotic manner of return &mdash; it's
not possible to define a high-level I7 phrase which effects, say, an immediate
end to the rule it's used in. Similarly, only inline invocations are allowed
to be followed by blocks of other phrases &mdash; that is, are allowed to define
control structures.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">The art of invocation is delegation</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="22-ptd.html#SP25" class="function-link"><span class="function-syntax">Phrases::TypeData::invoked_inline</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ph</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">manner_of_return</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><a href="25-cii.html#SP1" class="function-link"><span class="function-syntax">Invocations::Inline::csi_inline_outer</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VH</span><span class="plain-syntax">, </span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">where_from</span><span class="plain-syntax">, </span><span class="identifier-syntax">tokens</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><a href="25-ciac.html#SP1" class="function-link"><span class="function-syntax">Invocations::AsCalls::csi_by_call</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VH</span><span class="plain-syntax">, </span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">where_from</span><span class="plain-syntax">, </span><span class="identifier-syntax">tokens</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="25-ci.html#SP3">&#167;3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_2" class="paragraph-anchor"></a><b>&#167;3.2. </b>This is where we implement the convention that saying text ending with a full
stop automatically generates a newline:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compile a newline if the phrase implicitly requires one</span><span class="named-paragraph-number">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><a href="25-in.html#SP21" class="function-link"><span class="function-syntax">Invocations::implies_newline</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">tokens</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">tokens_count</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="14-rv.html#SP20" class="function-link"><span class="function-syntax">Rvalues::is_CONSTANT_of_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">tokens</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">args</span><span class="plain-syntax">[0], </span><span class="identifier-syntax">K_text</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Word::text_ending_sentence</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">tokens</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">args</span><span class="plain-syntax">[0]))))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">PRINT_BIP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::val_text</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">I</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><a href="27-em.html#SP2" class="function-link"><span class="function-syntax">Emit::tree</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="25-ci.html#SP3">&#167;3</a>.</li></ul>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="25-pi.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-cm.html">1</a></li><li class="progresschapter"><a href="2-up.html">2</a></li><li class="progresschapter"><a href="3-bv.html">3</a></li><li class="progresschapter"><a href="4-dlr.html">4</a></li><li class="progresschapter"><a href="5-rpt.html">5</a></li><li class="progresschapter"><a href="6-lp.html">6</a></li><li class="progresschapter"><a href="7-am.html">7</a></li><li class="progresschapter"><a href="8-ptu.html">8</a></li><li class="progresschapter"><a href="9-ef.html">9</a></li><li class="progresschapter"><a href="10-its.html">10</a></li><li class="progresschapter"></li><li class="progresschapter"><a href="12-terr.html">12</a></li><li class="progresschapter"><a href="13-kak.html">13</a></li><li class="progresschapter"><a href="14-sp.html">14</a></li><li class="progresschapter"><a href="15-pr.html">15</a></li><li class="progresschapter"><a href="16-is.html">16</a></li><li class="progresschapter"><a href="17-tl.html">17</a></li><li class="progresschapter"><a href="18-lc.html">18</a></li><li class="progresschapter"><a href="19-tc.html">19</a></li><li class="progresschapter"><a href="20-eq.html">20</a></li><li class="progresschapter"><a href="21-rl.html">21</a></li><li class="progresschapter"><a href="22-itp.html">22</a></li><li class="progresschapter"><a href="23-ad.html">23</a></li><li class="progresschapter"><a href="24-lv.html">24</a></li><li class="progresscurrentchapter">25</li><li class="progresssection"><a href="25-in.html">in</a></li><li class="progresssection"><a href="25-pi.html">pi</a></li><li class="progresscurrent">ci</li><li class="progresssection"><a href="25-ciac.html">ciac</a></li><li class="progresssection"><a href="25-cii.html">cii</a></li><li class="progresssection"><a href="25-cp.html">cp</a></li><li class="progresschapter"><a href="26-fc.html">26</a></li><li class="progresschapter"><a href="27-hr.html">27</a></li><li class="progressnext"><a href="25-ciac.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>