mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 22:14:23 +03:00
836 lines
145 KiB
HTML
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">§2. Top level: compiling lists</a></li><li><a href="25-ci.html#SP3">§3. Lower level: compiling single invocations</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§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>§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 — that is, will not be safe to execute without run-time checking.
|
|
We must execute exactly one invocation in the list — the first one which
|
|
is found to be type-safe — 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#SP23">§23</a><br/>Compile Phrases - <a href="25-cp.html#SP5">§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">-></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">-></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">-></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">) > </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>§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">§2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_1" class="paragraph-anchor"></a><b>§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">-></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">(&</span><span class="identifier-syntax">VH2</span><span class="plain-syntax">, </span><span class="identifier-syntax">inv</span><span class="plain-syntax">, &</span><span class="identifier-syntax">sl</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">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">phrase_being_compiled</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_1">§2.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_1_1" class="paragraph-anchor"></a><b>§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"><</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">-></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">) &&</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">-></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#SP5" 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">) && (</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">-></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">§2.1.1</a>, <a href="25-ci.html#SP2_2_3_3_1">§2.2.3.3.1</a>, <a href="25-ci.html#SP2_2_3_4_1">§2.2.3.4.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_1_1_2" class="paragraph-anchor"></a><b>§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">-></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">) &&</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"> &(</span><span class="identifier-syntax">phrase_being_compiled</span><span class="plain-syntax">-></span><span class="element-syntax">type_data</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">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">§2.1.1</a>, <a href="25-ci.html#SP2_2_3_3_1_3">§2.2.3.3.1.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_2" class="paragraph-anchor"></a><b>§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">-></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">§2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_2_1" class="paragraph-anchor"></a><b>§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>§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>§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"><</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">§2.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_2_3_1" class="paragraph-anchor"></a><b>§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"><</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">§2.2.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_2_3_2" class="paragraph-anchor"></a><b>§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">>=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"> > </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">>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">§2.2.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_2_3_1_1" class="paragraph-anchor"></a><b>§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">-></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">-></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">§2.2.3.1</a>, <a href="25-ci.html#SP2_2_3_2">§2.2.3.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_2_3_3" class="paragraph-anchor"></a><b>§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) && ((formal_rv = I1) bitwise-or 1))</span>
|
|
<span class="plain-syntax"> logical-or ((condition for I2 to be valid) && ((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">&&</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"> > </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"> > </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">§2.2.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_2_3_4" class="paragraph-anchor"></a><b>§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">§2.2.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_2_3_5" class="paragraph-anchor"></a><b>§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"><</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">§2.2.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_2_3_6" class="paragraph-anchor"></a><b>§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">-></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">§2.2.3</a>, <a href="25-ci.html#SP2_2_3_3">§2.2.3.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_2_3_3_1" class="paragraph-anchor"></a><b>§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">§2.2.3.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_2_3_4_1" class="paragraph-anchor"></a><b>§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"><</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">§2.2.3.4</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2_2_3_3_1_1" class="paragraph-anchor"></a><b>§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"><</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">§2.2.3.3.1</a>, <a href="25-ci.html#SP2_2_3_4_1">§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>§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"><</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"> > </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">§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>§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"><</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"> > </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"> < </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"><</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">§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>§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">&&</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"><</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"> < </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"> > </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">§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>§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="11-tc.html#SP3" class="function-link"><span class="function-syntax">Calculus::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">§2.2.3.4.1.1</a>, <a href="25-ci.html#SP2_2_3_3_1_2_1">§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>§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">-></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">(&</span><span class="identifier-syntax">VH2</span><span class="plain-syntax">, </span><span class="identifier-syntax">inv</span><span class="plain-syntax">, &</span><span class="identifier-syntax">sl</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">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">§2.2.3.3.1</a>, <a href="25-ci.html#SP2_2_3_4_1">§2.2.3.4.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>§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">§2.1.1</a>, <a href="25-ci.html#SP2_2_3_3_1_3">§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>§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 — 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 — 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">§3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_2" class="paragraph-anchor"></a><b>§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">)) &&</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="constant-syntax">0</span><span class="plain-syntax">) &&</span>
|
|
<span class="plain-syntax"> (</span><a href="14-rv.html#SP19" 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">-></span><span class="element-syntax">args</span><span class="plain-syntax">[0], </span><span class="identifier-syntax">K_text</span><span class="plain-syntax">)) &&</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">-></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">§3</a>.</li></ul>
|
|
<nav role="progress"><div class="progresscontainer">
|
|
<ul class="progressbar"><li class="progressprev"><a href="25-pi.html">❮</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"><a href="11-pr.html">11</a></li><li class="progresschapter"><a href="12-ter.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">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|