1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 16:44:21 +03:00
inform7/docs/core-module/25-cp.html
2020-04-07 01:06:09 +01:00

1526 lines
166 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>25/cii</title>
<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="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<nav role="navigation">
<h1><a href="../webs.html">Sources</a></h1>
<ul>
<li><a href="../compiler.html"><b>compiler tools</b></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="../inbuild-module/index.html">inbuild</a></li>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../html-module/index.html">html</a></li>
</ul>
<h2>Inform7 Modules</h2>
<ul>
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../kinds-module/index.html">kinds</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="../inter-module/index.html">inter</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul>
<h2>Foundation</h2>
<ul>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of '25/cp' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler 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 Phrases</b></li></ul><p class="purpose">Phrases defined with a list of invocations, rather than inline, have to be compiled to I6 routines, and this is where we organise that.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li><li><a href="#SP8">&#167;8. Validation of invocations</a></li><li><a href="#SP9">&#167;9. Problem messages for complex say constructions</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>The nature of the phrase currently being compiled provides a sort of
context for how we read the definition &mdash; for example, that it makes no
sense to write "end the action" in a phrase which isn't an action-based
rule. So we keep track of this. Note that one phrase definition cannot
contain another, so there is never any need to recursively compile phrases.
</p>
<pre class="display">
<span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">phrase_being_compiled</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="comment">phrase whose definition is being compiled</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>This routine sits at the summit of a mountain of code: it compiles a
non-line phrase definition into a routine. Note once again that a single
phrase can be compiled multiple times, with different kinds. For example,
</p>
<blockquote>
<p>To grasp (V - a value): say "I see, [V]."</p>
</blockquote>
<p class="inwebparagraph">might be compiled once in a form where V was a text, and another time where
it was a number. The form needed is included in the request <code class="display"><span class="extract">req</span></code>, which
should always be supplied for "To..." phrases, but left null for rules.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Routines::Compile::routine</span><span class="plain">(</span><span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain">,</span>
<span class="reserved">stacked_variable_owner_list</span><span class="plain"> *</span><span class="identifier">legible</span><span class="plain">, </span><span class="reserved">to_phrase_request</span><span class="plain"> *</span><span class="identifier">req</span><span class="plain">,</span>
<span class="reserved">applicability_condition</span><span class="plain"> *</span><span class="identifier">acl</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">declaration_node</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">declaration_node</span><span class="plain">) != </span><span class="identifier">ROUTINE_NT</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">Wordings::empty</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">declaration_node</span><span class="plain">))))</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to compile phrase with bad ROUTINE node"</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">PHRASE_COMPILATION</span><span class="plain">, </span><span class="string">"Compiling phrase:\n$T"</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">declaration_node</span><span class="plain">);</span>
<span class="functiontext">Modules::set_current</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">declaration_node</span><span class="plain">);</span>
<span class="identifier">phrase_being_compiled</span><span class="plain"> = </span><span class="identifier">ph</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Set up the stack frame for this compilation request</span> <span class="cwebmacronumber">3.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Compile some commentary about the routine to follow</span> <span class="cwebmacronumber">3.1</span>&gt;<span class="plain">;</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin_framed</span><span class="plain">(</span><span class="functiontext">Routines::Compile::iname</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">req</span><span class="plain">), &amp;(</span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">stack_frame</span><span class="plain">));</span>
&lt;<span class="cwebmacro">Compile the body of the routine</span> <span class="cwebmacronumber">3.3</span>&gt;<span class="plain">;</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="identifier">phrase_being_compiled</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="functiontext">Modules::set_current</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Routines::Compile::routine is used in 22/ph (<a href="22-ph.html#SP12">&#167;12</a>).</p>
<p class="inwebparagraph"><a id="SP3_1"></a><b>&#167;3.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile some commentary about the routine to follow</span> <span class="cwebmacronumber">3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Routines::ToPhrases::comment_on_request</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">);</span>
<span class="functiontext">Phrases::Usage::write_I6_comment_describing</span><span class="plain">(&amp;(</span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">usage_data</span><span class="plain">));</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_2"></a><b>&#167;3.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Set up the stack frame for this compilation request</span> <span class="cwebmacronumber">3.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = &amp;(</span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">stack_frame</span><span class="plain">);</span>
<span class="reserved">ph_type_data</span><span class="plain"> *</span><span class="identifier">phtd</span><span class="plain"> = &amp;(</span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">type_data</span><span class="plain">);</span>
<span class="functiontext">Frames::make_current</span><span class="plain">(</span><span class="identifier">phsf</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">version_kind</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">req</span><span class="plain">) </span><span class="identifier">version_kind</span><span class="plain"> = </span><span class="functiontext">Routines::ToPhrases::kind_of_request</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">version_kind</span><span class="plain"> = </span><span class="functiontext">Phrases::TypeData::kind</span><span class="plain">(</span><span class="identifier">phtd</span><span class="plain">);</span>
<span class="functiontext">Phrases::TypeData::into_stack_frame</span><span class="plain">(</span><span class="identifier">phsf</span><span class="plain">, </span><span class="identifier">phtd</span><span class="plain">, </span><span class="identifier">version_kind</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">req</span><span class="plain">) </span><span class="functiontext">Frames::set_kind_variables</span><span class="plain">(</span><span class="identifier">phsf</span><span class="plain">,</span>
<span class="functiontext">Routines::ToPhrases::kind_variables_for_request</span><span class="plain">(</span><span class="identifier">req</span><span class="plain">));</span>
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Frames::set_kind_variables</span><span class="plain">(</span><span class="identifier">phsf</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="functiontext">Frames::set_stvol</span><span class="plain">(</span><span class="identifier">phsf</span><span class="plain">, </span><span class="identifier">legible</span><span class="plain">);</span>
<span class="functiontext">LocalVariables::deallocate_all</span><span class="plain">(</span><span class="identifier">phsf</span><span class="plain">); </span><span class="comment">in case any are left from an earlier compile</span>
<span class="functiontext">ExParser::warn_expression_cache</span><span class="plain">(); </span><span class="comment">that local variables may have changed</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_3"></a><b>&#167;3.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile the body of the routine</span> <span class="cwebmacronumber">3.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">declaration_node</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Phrases::Context::compile_test_head</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">acl</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">declaration_node</span><span class="plain">) {</span>
<span class="identifier">ParseTree::verify_structure</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">declaration_node</span><span class="plain">);</span>
<span class="functiontext">Routines::Compile::code_block_outer</span><span class="plain">(1, </span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">declaration_node</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">);</span>
<span class="identifier">ParseTree::verify_structure</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">declaration_node</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">declaration_node</span><span class="plain">;</span>
<span class="functiontext">Phrases::Context::compile_test_tail</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">acl</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Compile a terminal return statement</span> <span class="cwebmacronumber">3.3.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_3_1"></a><b>&#167;3.3.1. </b>In I6, all routines return a value, and if execution runs into the <code class="display"><span class="extract">]</span></code> end
marker without any return being made then the routine returns <code class="display"><span class="extract">false</span></code> if the
routine is a property value, <code class="display"><span class="extract">true</span></code> otherwise. That convention is unhelpful
to us, so we end our routine with code which certainly performs a return.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Compile a terminal return statement</span> <span class="cwebmacronumber">3.3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Frames::get_kind_returned</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::RunTime::emit_default_value_as_val</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">EMPTY_WORDING</span><span class="plain">,</span>
<span class="string">"value decided by this phrase"</span><span class="plain">) != </span><span class="identifier">TRUE</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_DefaultDecideFails</span><span class="plain">),</span>
<span class="string">"it's not possible to decide such a value"</span><span class="plain">,</span>
<span class="string">"so this can't be allowed."</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">0</span><span class="plain">); </span><span class="comment">that is, return "false"</span>
<span class="plain">}</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_3">&#167;3.3</a>.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>The name of our I6 routine depends not only on the phrase but also on the
request made for its compilation &mdash; this enables the text version of a
phrase to be different from the number version, and so on.
</p>
<pre class="display">
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Routines::Compile::iname</span><span class="plain">(</span><span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain">, </span><span class="reserved">to_phrase_request</span><span class="plain"> *</span><span class="identifier">req</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">req</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">req</span><span class="plain">-&gt;</span><span class="element">req_iname</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Phrases::iname</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Routines::Compile::iname is used in <a href="#SP3">&#167;3</a>, 22/ph (<a href="22-ph.html#SP13">&#167;13</a>), 22/tp (<a href="22-tp.html#SP8">&#167;8</a>), 25/ciac (<a href="25-ciac.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">disallow_let_assignments</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Routines::Compile::disallow_let</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">disallow_let_assignments</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Routines::Compile::code_block_outer</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">statement_count</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pn</span><span class="plain">) {</span>
<span class="functiontext">Routines::Compile::code_block</span><span class="plain">(</span><span class="identifier">statement_count</span><span class="plain">, </span><span class="identifier">pn</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Routines::Compile::code_block</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">statement_count</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pn</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">top_level</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pn</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">m</span><span class="plain"> = &lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">-</span><span class="identifier">uncached</span><span class="plain">&gt;-&gt;</span><span class="identifier">multiplicitous</span><span class="plain">;</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">-</span><span class="identifier">uncached</span><span class="plain">&gt;-&gt;</span><span class="identifier">multiplicitous</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">) != </span><span class="constant">CODE_BLOCK_NT</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"not a code block"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">top_level</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">pn</span><span class="plain">-&gt;</span><span class="identifier">down</span><span class="plain">) &amp;&amp; (</span><span class="identifier">pn</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) &amp;&amp; (</span><span class="identifier">pn</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">))</span>
<span class="identifier">disallow_let_assignments</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">pn</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">; </span><span class="identifier">p</span><span class="plain">; </span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">) {</span>
<span class="identifier">statement_count</span><span class="plain"> = </span><span class="functiontext">Routines::Compile::code_line</span><span class="plain">(</span><span class="identifier">statement_count</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">disallow_let_assignments</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">-</span><span class="identifier">uncached</span><span class="plain">&gt;-&gt;</span><span class="identifier">multiplicitous</span><span class="plain"> = </span><span class="identifier">m</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">statement_count</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Routines::Compile::code_line</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">statement_count</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="identifier">control_structure_phrase</span><span class="plain"> *</span><span class="identifier">csp</span><span class="plain"> = </span><span class="identifier">ParseTree::get_control_structure_used</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">to_compile</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ControlStructures::opens_block</span><span class="plain">(</span><span class="identifier">csp</span><span class="plain">)) {</span>
<span class="functiontext">Frames::Blocks::beginning_block_phrase</span><span class="plain">(</span><span class="identifier">csp</span><span class="plain">);</span>
<span class="identifier">to_compile</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">statement_count</span><span class="plain">++;</span>
&lt;<span class="cwebmacro">Compile a comment about this line</span> <span class="cwebmacronumber">5.1</span>&gt;<span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">L</span><span class="plain"> = </span><span class="identifier">Produce::level</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
&lt;<span class="cwebmacro">Compile the head</span> <span class="cwebmacronumber">5.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Compile the midriff</span> <span class="cwebmacronumber">5.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Compile the tail</span> <span class="cwebmacronumber">5.4</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">statement_count</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Routines::Compile::disallow_let is used in 14/ds2 (<a href="14-ds2.html#SP11_9_1_1_3_1">&#167;11.9.1.1.3.1</a>).</p>
<p class="endnote">The function Routines::Compile::code_block_outer is used in <a href="#SP3_3">&#167;3.3</a>, 17/ts (<a href="17-ts.html#SP11_1">&#167;11.1</a>).</p>
<p class="endnote">The function Routines::Compile::code_block is used in <a href="#SP5_3_4">&#167;5.3.4</a>, <a href="#SP5_3_5_1">&#167;5.3.5.1</a>, <a href="#SP5_3_5_2">&#167;5.3.5.2</a>, <a href="#SP5_3_5_3">&#167;5.3.5.3</a>, <a href="#SP5_3_5_4">&#167;5.3.5.4</a>, <a href="#SP5_4_3">&#167;5.4.3</a>, <a href="#SP5_4_5">&#167;5.4.5</a>.</p>
<p class="endnote">The function Routines::Compile::code_line appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP5_1"></a><b>&#167;5.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile a comment about this line</span> <span class="cwebmacronumber">5.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">to_compile</span><span class="plain">))) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="string">"[%d: "</span><span class="plain">, </span><span class="identifier">statement_count</span><span class="plain">);</span>
<span class="functiontext">CompiledText::comment</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">to_compile</span><span class="plain">));</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="string">"]"</span><span class="plain">);</span>
<span class="functiontext">Emit::code_comment</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_2"></a><b>&#167;5.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile the head</span> <span class="cwebmacronumber">5.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">csp</span><span class="plain"> == </span><span class="identifier">say_CSP</span><span class="plain">) {</span>
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">to_compile</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Compile a say head</span> <span class="cwebmacronumber">5.2.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_2_1"></a><b>&#167;5.2.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile a say head</span> <span class="cwebmacronumber">5.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">say_node</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">, *</span><span class="identifier">prev_sn</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">say_node</span><span class="plain">; </span><span class="identifier">prev_sn</span><span class="plain"> = </span><span class="identifier">say_node</span><span class="plain">, </span><span class="identifier">say_node</span><span class="plain"> = </span><span class="identifier">say_node</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">) {</span>
<span class="functiontext">ExParser::parse_say_term</span><span class="plain">(</span><span class="identifier">say_node</span><span class="plain">);</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain"> = </span><span class="functiontext">Invocations::first_in_list</span><span class="plain">(</span><span class="identifier">say_node</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inv</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prev_sn</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ParseTree::get_say_verb</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">ParseTree::get_say_adjective</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">)) ||</span>
<span class="plain">((</span><span class="functiontext">Phrases::TypeData::is_a_say_phrase</span><span class="plain">(</span><span class="identifier">ParseTree::get_phrase_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">))) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">ParseTree::get_phrase_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">)-&gt;</span><span class="element">type_data</span><span class="plain">.</span><span class="element">as_say</span><span class="plain">.</span><span class="element">say_phrase_running_on</span><span class="plain">)))</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">prev_sn</span><span class="plain">, </span><span class="constant">suppress_newlines_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">); </span><span class="comment">warn the paragraph breaker: this will print</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">SAY__P_HL</span><span class="plain">));</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">1</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Routines::Compile::verify_say_node_list</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_2">&#167;5.2</a>.</p>
<p class="inwebparagraph"><a id="SP5_3"></a><b>&#167;5.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile the midriff</span> <span class="cwebmacronumber">5.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">to_compile</span><span class="plain">) == </span><span class="constant">INVOCATION_LIST_SAY_NT</span><span class="plain">) </span>&lt;<span class="cwebmacro">Compile a say term midriff</span> <span class="cwebmacronumber">5.3.1</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">csp</span><span class="plain"> == </span><span class="identifier">now_CSP</span><span class="plain">) </span>&lt;<span class="cwebmacro">Compile a now midriff</span> <span class="cwebmacronumber">5.3.2</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">csp</span><span class="plain"> == </span><span class="identifier">if_CSP</span><span class="plain">) </span>&lt;<span class="cwebmacro">Compile an if midriff</span> <span class="cwebmacronumber">5.3.4</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">csp</span><span class="plain"> == </span><span class="identifier">switch_CSP</span><span class="plain">) </span>&lt;<span class="cwebmacro">Compile a switch midriff</span> <span class="cwebmacronumber">5.3.5</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">csp</span><span class="plain"> != </span><span class="identifier">say_CSP</span><span class="plain">) &amp;&amp; (</span><span class="identifier">csp</span><span class="plain"> != </span><span class="identifier">instead_CSP</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">named</span><span class="plain">-</span><span class="reserved">rulebook</span><span class="plain">-</span><span class="identifier">outcome</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">to_compile</span><span class="plain">)))</span>
&lt;<span class="cwebmacro">Compile a named rulebook outline midriff</span> <span class="cwebmacronumber">5.3.3</span>&gt;
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Compile a standard midriff</span> <span class="cwebmacronumber">5.3.6</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_3_1"></a><b>&#167;5.3.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile a say term midriff</span> <span class="cwebmacronumber">5.3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="constant">BEGIN_COMPILATION_MODE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">to_compile</span><span class="plain">, </span><span class="constant">suppress_newlines_ANNOT</span><span class="plain">))</span>
<span class="identifier">COMPILATION_MODE_EXIT</span><span class="plain">(</span><span class="constant">IMPLY_NEWLINES_IN_SAY_CMODE</span><span class="plain">);</span>
<span class="functiontext">Routines::Compile::line</span><span class="plain">(</span><span class="identifier">to_compile</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">INTER_VOID_VHMODE</span><span class="plain">);</span>
<span class="constant">END_COMPILATION_MODE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_3">&#167;5.3</a>.</p>
<p class="inwebparagraph"><a id="SP5_3_2"></a><b>&#167;5.3.2. </b>In fact, "now" propositions are never empty, but there's nothing in
principle wrong with asserting that the universally true proposition is
henceforth to be true, so we simply compile empty code in that case.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Compile a now midriff</span> <span class="cwebmacronumber">5.3.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">to_compile</span><span class="plain">;</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">XW</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">);</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">cs</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">condition</span><span class="plain">&gt;(</span><span class="identifier">XW</span><span class="plain">)) </span><span class="identifier">cs</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;; </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">cs</span><span class="plain"> = </span><span class="functiontext">Specifications::new_UNKNOWN</span><span class="plain">(</span><span class="identifier">XW</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">MATCHING</span><span class="plain">, </span><span class="string">"Now cond is $T\n"</span><span class="plain">, </span><span class="identifier">cs</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="functiontext">Dash::check_condition</span><span class="plain">(</span><span class="identifier">cs</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">MATCHING</span><span class="plain">, </span><span class="string">"After Dash, it's $T\n"</span><span class="plain">, </span><span class="identifier">cs</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">cs</span><span class="plain">, </span><span class="constant">TEST_PROPOSITION_NT</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rv</span><span class="plain"> != </span><span class="identifier">NEVER_MATCH</span><span class="plain">) {</span>
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain"> = </span><span class="functiontext">Specifications::to_proposition</span><span class="plain">(</span><span class="identifier">cs</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prop</span><span class="plain">) {</span>
<span class="constant">BEGIN_COMPILATION_MODE</span><span class="plain">;</span>
<span class="identifier">COMPILATION_MODE_ENTER</span><span class="plain">(</span><span class="constant">PERMIT_LOCALS_IN_TEXT_CMODE</span><span class="plain">);</span>
<span class="functiontext">Calculus::Deferrals::emit_now_proposition</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">);</span>
<span class="constant">END_COMPILATION_MODE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTreeUsage::is_condition</span><span class="plain">(</span><span class="identifier">cs</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Issue a problem message for the wrong sort of condition in a "now"</span> <span class="cwebmacronumber">5.3.2.1</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rv</span><span class="plain"> != </span><span class="identifier">NEVER_MATCH</span><span class="plain">) </span>&lt;<span class="cwebmacro">Issue a problem message for an unrecognised condition</span> <span class="cwebmacronumber">5.3.2.2</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_3">&#167;5.3</a>.</p>
<p class="inwebparagraph"><a id="SP5_3_2_1"></a><b>&#167;5.3.2.1. </b>A deluxe problem message.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for the wrong sort of condition in a "now"</span> <span class="cwebmacronumber">5.3.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">cs</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">cs</span><span class="plain">, </span><span class="constant">TEST_VALUE_NT</span><span class="plain">)) {</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_BadNow1</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but although '%2' is a condition which it is legal "</span>
<span class="string">"to test with 'if', 'when', and so forth, it is not something I "</span>
<span class="string">"can arrange to happen on request. Whether it is true or not "</span>
<span class="string">"depends on current circumstances: so to make it true, you will "</span>
<span class="string">"need to adjust those circumstances."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">cs</span><span class="plain">, </span><span class="constant">LOGICAL_AND_NT</span><span class="plain">)) {</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_BadNow2</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but 'now' does not work with the condition '%2' "</span>
<span class="string">"because it can only make one wish come true at a time: so it "</span>
<span class="string">"doesn't like the 'and'. Try rewriting as two 'now's in a row?"</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_BadNow3</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but '%2' isn't the sort of condition which can be "</span>
<span class="string">"made to be true, in the way that 'the ball is on the table' can be "</span>
<span class="string">"made true with a straightforward movement of one object (the ball)."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_3_2">&#167;5.3.2</a>.</p>
<p class="inwebparagraph"><a id="SP5_3_2_2"></a><b>&#167;5.3.2.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for an unrecognised condition</span> <span class="cwebmacronumber">5.3.2.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$T\n"</span><span class="plain">, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">cs</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(...));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but '%2' isn't a condition, so I can't see how to "</span>
<span class="string">"make it true from here on."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_3_2">&#167;5.3.2</a>.</p>
<p class="inwebparagraph"><a id="SP_1"></a><b>&#167;.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for an unrecognised action</span> <span class="cwebmacronumber">.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">cs</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(...));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but '%2' isn't an action, so I can't see how to try it."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is never used.</p>
<p class="inwebparagraph"><a id="SP5_3_3"></a><b>&#167;5.3.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile a named rulebook outline midriff</span> <span class="cwebmacronumber">5.3.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">to_compile</span><span class="plain">;</span>
<span class="reserved">named_rulebook_outcome</span><span class="plain"> *</span><span class="identifier">nrbo</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phrase_being_compiled</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">ram</span><span class="plain"> = </span><span class="functiontext">Phrases::Usage::get_effect</span><span class="plain">(&amp;(</span><span class="identifier">phrase_being_compiled</span><span class="plain">-&gt;</span><span class="element">usage_data</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ram</span><span class="plain"> != </span><span class="constant">RULE_IN_RULEBOOK_EFF</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">ram</span><span class="plain"> != </span><span class="constant">RULE_NOT_IN_RULEBOOK_EFF</span><span class="plain">)) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">to_compile</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_MisplacedRulebookOutcome2</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but this is a rulebook outcome which can only be used "</span>
<span class="string">"within rulebooks which recognise it. You've used it in a definition "</span>
<span class="string">"which isn't for use in rulebooks at all, so it must be wrong here."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">rulebook</span><span class="plain"> *</span><span class="identifier">rb</span><span class="plain"> = </span><span class="functiontext">Rulebooks::Outcomes::allow_outcome</span><span class="plain">(</span><span class="identifier">nrbo</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rb</span><span class="plain">) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">to_compile</span><span class="plain">));</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(3, </span><span class="identifier">rb</span><span class="plain">-&gt;</span><span class="element">primary_name</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_MisplacedRulebookOutcome</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but this is a rulebook outcome which can only be used "</span>
<span class="string">"within rulebooks which recognise it. You've used it in a rule which "</span>
<span class="string">"has to be listed in the '%3' rulebook, where '%2' doesn't have a meaning."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">}</span>
<span class="functiontext">Rulebooks::Outcomes::compile_outcome</span><span class="plain">(</span><span class="identifier">nrbo</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_3">&#167;5.3</a>.</p>
<p class="inwebparagraph"><a id="SP5_3_4"></a><b>&#167;5.3.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile an if midriff</span> <span class="cwebmacronumber">5.3.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">) </span><span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IFELSE_BIP</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">to_compile</span><span class="plain">;</span>
<span class="functiontext">Routines::Compile::line</span><span class="plain">(</span><span class="identifier">to_compile</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">INTER_VAL_VHMODE</span><span class="plain">);</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Frames::Blocks::open_code_block</span><span class="plain">();</span>
<span class="identifier">statement_count</span><span class="plain"> = </span><span class="functiontext">Routines::Compile::code_block</span><span class="plain">(</span><span class="identifier">statement_count</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">) {</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Frames::Blocks::divide_code_block</span><span class="plain">();</span>
<span class="identifier">statement_count</span><span class="plain"> = </span><span class="functiontext">Routines::Compile::code_block</span><span class="plain">(</span><span class="identifier">statement_count</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="functiontext">Frames::Blocks::close_code_block</span><span class="plain">();</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_3">&#167;5.3</a>.</p>
<p class="inwebparagraph"><a id="SP5_3_5"></a><b>&#167;5.3.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile a switch midriff</span> <span class="cwebmacronumber">5.3.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">to_compile</span><span class="plain">;</span>
<span class="functiontext">Routines::Compile::line</span><span class="plain">(</span><span class="identifier">to_compile</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">INTER_VOID_VHMODE</span><span class="plain">);</span>
<span class="functiontext">Frames::Blocks::open_code_block</span><span class="plain">();</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain"> = </span><span class="functiontext">Frames::Blocks::switch_value</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">val</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no switch value"</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">switch_kind</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">pointery</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">sw_v</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Behaviour::uses_pointer_values</span><span class="plain">(</span><span class="identifier">switch_kind</span><span class="plain">)) </span><span class="identifier">pointery</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Switch val is $T for kind $u pointery %d\n"</span><span class="plain">, </span><span class="identifier">val</span><span class="plain">, </span><span class="identifier">switch_kind</span><span class="plain">, </span><span class="identifier">pointery</span><span class="plain">);</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">downs</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pointery</span><span class="plain">) {</span>
<span class="identifier">lvar</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_switch_value</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">);</span>
<span class="identifier">sw_v</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="constant">7</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::ref_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">sw_v</span><span class="plain">);</span>
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">switch_kind</span><span class="plain">, </span><span class="identifier">val</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SWITCH_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">switch_kind</span><span class="plain">, </span><span class="identifier">val</span><span class="plain">);</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">ow_node</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">; </span><span class="identifier">ow_node</span><span class="plain">; </span><span class="identifier">ow_node</span><span class="plain"> = </span><span class="identifier">ow_node</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">++) {</span>
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">ow_node</span><span class="plain">;</span>
<span class="functiontext">Frames::Blocks::divide_code_block</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_control_structure_used</span><span class="plain">(</span><span class="identifier">ow_node</span><span class="plain">) == </span><span class="identifier">default_case_CSP</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pointery</span><span class="plain">) </span>&lt;<span class="cwebmacro">Handle a pointery default</span> <span class="cwebmacronumber">5.3.5.4</span>&gt;
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Handle a non-pointery default</span> <span class="cwebmacronumber">5.3.5.2</span>&gt;<span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">type</span><span class="plain">-</span><span class="identifier">expression</span><span class="plain">-</span><span class="identifier">or</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">ow_node</span><span class="plain">))) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">case_spec</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="identifier">case_spec</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::substitute_constants</span><span class="plain">(</span><span class="identifier">case_spec</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_evaluation</span><span class="plain">(</span><span class="identifier">ow_node</span><span class="plain">, </span><span class="identifier">case_spec</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Dash::check_value</span><span class="plain">(</span><span class="identifier">case_spec</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">) != </span><span class="identifier">NEVER_MATCH</span><span class="plain">) {</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">case_kind</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">case_spec</span><span class="plain">);</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_object_instance</span><span class="plain">(</span><span class="identifier">case_spec</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">I</span><span class="plain">) </span><span class="identifier">case_kind</span><span class="plain"> = </span><span class="functiontext">Instances::to_kind</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">MATCHING</span><span class="plain">, </span><span class="string">"(h.3) switch kind is $u, case kind is $u\n"</span><span class="plain">, </span><span class="identifier">switch_kind</span><span class="plain">, </span><span class="identifier">case_kind</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ParseTree::get_kind_of_value</span><span class="plain">(</span><span class="identifier">case_spec</span><span class="plain">) == </span><span class="identifier">NULL</span><span class="plain">) &amp;&amp; (</span><span class="identifier">I</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(2, </span><span class="identifier">switch_kind</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CaseValueNonConstant</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The case %1 is required to be a constant value, rather than "</span>
<span class="string">"something which has different values at different times: "</span>
<span class="string">"specifically, it has to be %2."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="identifier">case_spec</span><span class="plain"> = </span><span class="functiontext">Rvalues::new_nothing_object_constant</span><span class="plain">();</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::compatible</span><span class="plain">(</span><span class="identifier">case_kind</span><span class="plain">, </span><span class="identifier">switch_kind</span><span class="plain">) != </span><span class="identifier">ALWAYS_MATCH</span><span class="plain">) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(2, </span><span class="identifier">case_kind</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(3, </span><span class="identifier">switch_kind</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CaseValueMismatch</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The case %1 has the wrong kind of value for the possibilities "</span>
<span class="string">"being chosen from: %2 instead of %3."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="identifier">case_spec</span><span class="plain"> = </span><span class="functiontext">Rvalues::new_nothing_object_constant</span><span class="plain">();</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pointery</span><span class="plain">) </span>&lt;<span class="cwebmacro">Handle a pointery case</span> <span class="cwebmacronumber">5.3.5.3</span>&gt;
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Handle a non-pointery case</span> <span class="cwebmacronumber">5.3.5.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue problem message for unknown case value</span> <span class="cwebmacronumber">5.3.5.5</span>&gt;
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue problem message for unknown case value</span> <span class="cwebmacronumber">5.3.5.5</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pointery</span><span class="plain">) {</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">downs</span><span class="plain">-- &gt; </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Frames::Blocks::close_code_block</span><span class="plain">();</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Frames::Blocks::close_code_block</span><span class="plain">();</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">)</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">; </span><span class="identifier">A</span><span class="plain">; </span><span class="identifier">A</span><span class="plain"> = </span><span class="identifier">A</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">dup</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">B</span><span class="plain"> = </span><span class="identifier">A</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">; </span><span class="identifier">B</span><span class="plain">; </span><span class="identifier">B</span><span class="plain"> = </span><span class="identifier">B</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::compare_CONSTANT</span><span class="plain">(</span>
<span class="identifier">ParseTree::get_evaluation</span><span class="plain">(</span><span class="identifier">A</span><span class="plain">), </span><span class="identifier">ParseTree::get_evaluation</span><span class="plain">(</span><span class="identifier">B</span><span class="plain">)))</span>
<span class="identifier">dup</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dup</span><span class="plain">) {</span>
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">A</span><span class="plain">;</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">A</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_spec</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_evaluation</span><span class="plain">(</span><span class="identifier">A</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CaseValueDuplicated</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The case %1 occurs more than once in this 'if' switch."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_3">&#167;5.3</a>.</p>
<p class="inwebparagraph"><a id="SP5_3_5_1"></a><b>&#167;5.3.5.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Handle a non-pointery case</span> <span class="cwebmacronumber">5.3.5.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">CASE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">switch_kind</span><span class="plain">, </span><span class="identifier">case_spec</span><span class="plain">);</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">statement_count</span><span class="plain"> = </span><span class="functiontext">Routines::Compile::code_block</span><span class="plain">(</span><span class="identifier">statement_count</span><span class="plain">, </span><span class="identifier">ow_node</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_3_5">&#167;5.3.5</a>.</p>
<p class="inwebparagraph"><a id="SP5_3_5_2"></a><b>&#167;5.3.5.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Handle a non-pointery default</span> <span class="cwebmacronumber">5.3.5.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">DEFAULT_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">statement_count</span><span class="plain"> = </span><span class="functiontext">Routines::Compile::code_block</span><span class="plain">(</span><span class="identifier">statement_count</span><span class="plain">, </span><span class="identifier">ow_node</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_3_5">&#167;5.3.5</a>.</p>
<p class="inwebparagraph"><a id="SP5_3_5_3"></a><b>&#167;5.3.5.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Handle a pointery case</span> <span class="cwebmacronumber">5.3.5.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">final_flag</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ow_node</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">final_flag</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">final_flag</span><span class="plain">) </span><span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IF_BIP</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IFELSE_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">LocalVariables::set_kind</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">switch_kind</span><span class="plain">);</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">sw_v</span><span class="plain"> = </span><span class="functiontext">Lvalues::new_LOCAL_VARIABLE</span><span class="plain">(</span><span class="identifier">EMPTY_WORDING</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">);</span>
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain"> = </span><span class="functiontext">Calculus::Propositions::Abstract::to_set_relation</span><span class="plain">(</span>
<span class="identifier">R_equality</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">sw_v</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">case_spec</span><span class="plain">);</span>
<span class="functiontext">Calculus::Propositions::Checker::type_check</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="functiontext">Calculus::Propositions::Checker::tc_no_problem_reporting</span><span class="plain">());</span>
<span class="functiontext">Calculus::Deferrals::emit_test_of_proposition</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">);</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">statement_count</span><span class="plain"> = </span><span class="functiontext">Routines::Compile::code_block</span><span class="plain">(</span><span class="identifier">statement_count</span><span class="plain">, </span><span class="identifier">ow_node</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">final_flag</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">downs</span><span class="plain"> += </span><span class="constant">2</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_3_5">&#167;5.3.5</a>.</p>
<p class="inwebparagraph"><a id="SP5_3_5_4"></a><b>&#167;5.3.5.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Handle a pointery default</span> <span class="cwebmacronumber">5.3.5.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">statement_count</span><span class="plain"> = </span><span class="functiontext">Routines::Compile::code_block</span><span class="plain">(</span><span class="identifier">statement_count</span><span class="plain">, </span><span class="identifier">ow_node</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_3_5">&#167;5.3.5</a>.</p>
<p class="inwebparagraph"><a id="SP5_3_6"></a><b>&#167;5.3.6. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile a standard midriff</span> <span class="cwebmacronumber">5.3.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">to_compile</span><span class="plain">;</span>
<span class="functiontext">Routines::Compile::line</span><span class="plain">(</span><span class="identifier">to_compile</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">INTER_VOID_VHMODE</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_3">&#167;5.3</a>.</p>
<p class="inwebparagraph"><a id="SP5_4"></a><b>&#167;5.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile the tail</span> <span class="cwebmacronumber">5.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">csp</span><span class="plain"> == </span><span class="identifier">if_CSP</span><span class="plain">) </span>&lt;<span class="cwebmacro">Compile an if tail</span> <span class="cwebmacronumber">5.4.1</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">csp</span><span class="plain"> == </span><span class="identifier">switch_CSP</span><span class="plain">) </span>&lt;<span class="cwebmacro">Compile a switch tail</span> <span class="cwebmacronumber">5.4.2</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">csp</span><span class="plain"> == </span><span class="identifier">say_CSP</span><span class="plain">) </span>&lt;<span class="cwebmacro">Compile a say tail</span> <span class="cwebmacronumber">5.4.3</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">csp</span><span class="plain"> == </span><span class="identifier">instead_CSP</span><span class="plain">) </span>&lt;<span class="cwebmacro">Compile an instead tail</span> <span class="cwebmacronumber">5.4.4</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ControlStructures::opens_block</span><span class="plain">(</span><span class="identifier">csp</span><span class="plain">)) </span>&lt;<span class="cwebmacro">Compile a loop tail</span> <span class="cwebmacronumber">5.4.5</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_4_1"></a><b>&#167;5.4.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile an if tail</span> <span class="cwebmacronumber">5.4.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_4">&#167;5.4</a>.</p>
<p class="inwebparagraph"><a id="SP5_4_2"></a><b>&#167;5.4.2. </b>Switch statements in I6 look much like those in C, but are written without
the ceaseless repetition of the keyword "case". Thus, <code class="display"><span class="extract">15:</span></code> does what
<code class="display"><span class="extract">case 15:</span></code> would do in C. But <code class="display"><span class="extract">default:</span></code> is the same in both.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Compile a switch tail</span> <span class="cwebmacronumber">5.4.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_4">&#167;5.4</a>.</p>
<p class="inwebparagraph"><a id="SP5_3_5_5"></a><b>&#167;5.3.5.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue problem message for unknown case value</span> <span class="cwebmacronumber">5.3.5.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CaseValueUnknown</span><span class="plain">),</span>
<span class="string">"I don't recognise this case value"</span><span class="plain">,</span>
<span class="string">"that is, the value written after the '--'."</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_3_5">&#167;5.3.5</a> (twice).</p>
<p class="inwebparagraph"><a id="SP_1"></a><b>&#167;.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">If this is a say group, but not a say control structure, notify the paragraphing code</span> <span class="cwebmacronumber">.1</span>&gt; =
</code></p>
<pre class="displaydefn">
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is never used.</p>
<p class="inwebparagraph"><a id="SP5_4_3"></a><b>&#167;5.4.3. </b>As will be seen, two sets of labels and counters are kept here: see the
inline definitions for "say if" and similar.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Compile a say tail</span> <span class="cwebmacronumber">5.4.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">statement_count</span><span class="plain"> = </span><span class="functiontext">Routines::Compile::code_block</span><span class="plain">(</span><span class="identifier">statement_count</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">SAYL</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">SAYL</span><span class="plain">, </span><span class="string">"."</span><span class="plain">);</span>
<span class="functiontext">JumpLabels::write</span><span class="plain">(</span><span class="identifier">SAYL</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Say"</span><span class="plain">);</span>
<span class="identifier">Produce::place_label</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">Produce::reserve_label</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SAYL</span><span class="plain">));</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">SAYL</span><span class="plain">);</span>
<span class="functiontext">JumpLabels::read_counter</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"Say"</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">SAYXL</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">SAYXL</span><span class="plain">, </span><span class="string">"."</span><span class="plain">);</span>
<span class="functiontext">JumpLabels::write</span><span class="plain">(</span><span class="identifier">SAYXL</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"SayX"</span><span class="plain">);</span>
<span class="identifier">Produce::place_label</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">Produce::reserve_label</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SAYXL</span><span class="plain">));</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">SAYXL</span><span class="plain">);</span>
<span class="functiontext">JumpLabels::read_counter</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"SayX"</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_4">&#167;5.4</a>.</p>
<p class="inwebparagraph"><a id="SP5_4_4"></a><b>&#167;5.4.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile an instead tail</span> <span class="cwebmacronumber">5.4.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::rtrue</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_4">&#167;5.4</a>.</p>
<p class="inwebparagraph"><a id="SP5_4_5"></a><b>&#167;5.4.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Compile a loop tail</span> <span class="cwebmacronumber">5.4.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Frames::Blocks::open_code_block</span><span class="plain">();</span>
<span class="identifier">statement_count</span><span class="plain"> = </span><span class="functiontext">Routines::Compile::code_block</span><span class="plain">(</span><span class="identifier">statement_count</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Produce::level</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">()) &gt; </span><span class="identifier">L</span><span class="plain">) </span><span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Frames::Blocks::close_code_block</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5_4">&#167;5.4</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>This routine takes the text of a line from a phrase definition, parses it,
type-checks it, and finally, all being well, compiles it.
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">void_phrase_please</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="comment">instructions for the typechecker</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Routines::Compile::line</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">already_parsed</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">vhm</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">initial_problem_count</span><span class="plain"> = </span><span class="identifier">problem_count</span><span class="plain">;</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXPRESSIONS</span><span class="plain">, </span><span class="string">"\n-- -- Evaluating &lt;%W&gt; -- --\n"</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">));</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXPRESSIONS</span><span class="plain">, </span><span class="string">"(a) Parsing:\n"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">already_parsed</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain"> = </span><span class="functiontext">Invocations::first_in_list</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">inv</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">ParseTree::get_phrase_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Phrases::TypeData::is_a_say_phrase</span><span class="plain">(</span><span class="identifier">ParseTree::get_phrase_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">))) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">ParseTree::get_phrase_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">)-&gt;</span><span class="element">type_data</span><span class="plain">.</span><span class="element">as_say</span><span class="plain">.</span><span class="element">say_control_structure</span><span class="plain"> == </span><span class="constant">NO_SAY_CS</span><span class="plain">)) {</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">PARACONTENT_HL</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">ExParser::parse_void_phrase</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">initial_problem_count</span><span class="plain"> == </span><span class="identifier">problem_count</span><span class="plain">) {</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXPRESSIONS</span><span class="plain">, </span><span class="string">"(b) Type checking:\n$E"</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">);</span>
<span class="functiontext">Dash::check_invl</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">initial_problem_count</span><span class="plain"> == </span><span class="identifier">problem_count</span><span class="plain">) {</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXPRESSIONS</span><span class="plain">, </span><span class="string">"(c) Compilation:\n$E"</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">);</span>
<span class="identifier">value_holster</span><span class="plain"> </span><span class="identifier">VH</span><span class="plain"> = </span><span class="identifier">Holsters::new</span><span class="plain">(</span><span class="identifier">vhm</span><span class="plain">);</span>
<span class="functiontext">Invocations::Compiler::compile_invocation_list</span><span class="plain">(&amp;</span><span class="identifier">VH</span><span class="plain">,</span>
<span class="identifier">p</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">initial_problem_count</span><span class="plain"> == </span><span class="identifier">problem_count</span><span class="plain">) {</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXPRESSIONS</span><span class="plain">, </span><span class="string">"-- -- Completed -- --\n"</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXPRESSIONS</span><span class="plain">, </span><span class="string">"-- -- Failed -- --\n"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Routines::Compile::line is used in <a href="#SP5_3_1">&#167;5.3.1</a>, <a href="#SP5_3_4">&#167;5.3.4</a>, <a href="#SP5_3_5">&#167;5.3.5</a>, <a href="#SP5_3_6">&#167;5.3.6</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>And this is where we are:
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Routines::Compile::line_being_compiled</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phrase_being_compiled</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">current_sentence</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Routines::Compile::line_being_compiled is used in 14/rv (<a href="14-rv.html#SP24_3">&#167;24.3</a>).</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Validation of invocations. </b>Recall that a complex text such as:
</p>
<blockquote>
<p>"Platinum is shinier than [if a Colony is in the Supply Pile]gold[otherwise]silver."</p>
</blockquote>
<p class="inwebparagraph">is complied into a specification holding a list of invocations; in this case
there are five, invoking the phrases &mdash;
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(1) "say [text]"
</li><li>(2) "say if ..."
</li><li>(3) "say [text]"
</li><li>(4) "say otherwise"
</li><li>(5) "say [text]"
</li></ul>
<p class="inwebparagraph">In the following routine we check this list to see that two sorts of control
structure are correctly used. The first is "say if"; here, for instance, it
would be an error to use "say otherwise" without "say if", or to have them
the wrong way round.
</p>
<p class="inwebparagraph">The other is the SSP, the "segmented say phrase". For example:
</p>
<blockquote>
<p>"The best defence is [one of]Lighthouse[or]Moat[or]having no money[at random]."</p>
</blockquote>
<p class="inwebparagraph">Here there are nine invocations, and the interesting ones have to come in
the sequence "[one of]" (a start), then any number of "[or]" segments (middles),
and lastly "[at random]" (an end). SSPs can even be nested, within limits:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">MAX_COMPLEX_SAY_DEPTH</span><span class="plain"> </span><span class="constant">32</span><span class="plain"> </span><span class="comment">and it would be terrible coding style to approach this</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Routines::Compile::verify_say_node_list</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">say_node_list</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">problem_issued</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">say_invocations_found</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Check that say control structures have been used in a correct sequence</span> <span class="cwebmacronumber">8.1</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">say_invocations_found</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Routines::Compile::verify_say_node_list is used in <a href="#SP5_2_1">&#167;5.2.1</a>.</p>
<p class="inwebparagraph"><a id="SP8_1"></a><b>&#167;8.1. </b>Given correct code, the following does very little. It checks that structural
say phrases (SSPs), such as the substitutions here:
</p>
<blockquote>
<p>"Platinum is shinier than [if a Colony is in the Supply Pile]gold[otherwise]silver."</p>
</blockquote>
<p class="inwebparagraph">...are used correctly; for instance, that there isn't an "[otherwise]" before
the "[if...]".
</p>
<p class="inwebparagraph">It doesn't quite do nothing, though, because it also counts the say phrases found.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Check that say control structures have been used in a correct sequence</span> <span class="cwebmacronumber">8.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">it_was_not_worth_adding</span><span class="plain"> = </span><span class="identifier">it_is_not_worth_adding</span><span class="plain">;</span>
<span class="identifier">it_is_not_worth_adding</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">SSP_sp</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">SSP_stack</span><span class="plain">[</span><span class="constant">MAX_COMPLEX_SAY_DEPTH</span><span class="plain">];</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">SSP_stack_otherwised</span><span class="plain">[</span><span class="constant">MAX_COMPLEX_SAY_DEPTH</span><span class="plain">];</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">SSP_invocations</span><span class="plain">[</span><span class="constant">MAX_COMPLEX_SAY_DEPTH</span><span class="plain">];</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">say_if_nesting</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">say_node</span><span class="plain"> = </span><span class="identifier">say_node_list</span><span class="plain">; </span><span class="identifier">say_node</span><span class="plain">; </span><span class="identifier">say_node</span><span class="plain"> = </span><span class="identifier">say_node</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">invl</span><span class="plain"> = </span><span class="identifier">say_node</span><span class="plain">-&gt;</span><span class="element">down</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">invl</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">;</span>
<span class="identifier">LOOP_THROUGH_INVOCATION_LIST</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">invl</span><span class="plain">) {</span>
<span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain"> = </span><span class="identifier">ParseTree::get_phrase_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ParseTree::get_phrase_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Phrases::TypeData::is_a_say_phrase</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">))) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">say_cs</span><span class="plain">, </span><span class="identifier">ssp_tok</span><span class="plain">, </span><span class="identifier">ssp_ctok</span><span class="plain">, </span><span class="identifier">ssp_pos</span><span class="plain">;</span>
<span class="functiontext">Phrases::TypeData::get_say_data</span><span class="plain">(&amp;(</span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">type_data</span><span class="plain">.</span><span class="element">as_say</span><span class="plain">),</span>
<span class="plain">&amp;</span><span class="identifier">say_cs</span><span class="plain">, &amp;</span><span class="identifier">ssp_tok</span><span class="plain">, &amp;</span><span class="identifier">ssp_ctok</span><span class="plain">, &amp;</span><span class="identifier">ssp_pos</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ssp_pos</span><span class="plain"> == </span><span class="constant">SSP_START</span><span class="plain">) </span>&lt;<span class="cwebmacro">This starts a complex SSP</span> <span class="cwebmacronumber">8.1.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ssp_pos</span><span class="plain"> == </span><span class="constant">SSP_MIDDLE</span><span class="plain">) </span>&lt;<span class="cwebmacro">This is a middle term in a complex SSP</span> <span class="cwebmacronumber">8.1.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ssp_pos</span><span class="plain"> == </span><span class="constant">SSP_END</span><span class="plain">) </span>&lt;<span class="cwebmacro">This ends a complex SSP</span> <span class="cwebmacronumber">8.1.3</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">say_cs</span><span class="plain"> == </span><span class="constant">IF_SAY_CS</span><span class="plain">) </span>&lt;<span class="cwebmacro">This is a say if</span> <span class="cwebmacronumber">8.1.4</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">say_cs</span><span class="plain"> == </span><span class="constant">OTHERWISE_SAY_CS</span><span class="plain">) || (</span><span class="identifier">say_cs</span><span class="plain"> == </span><span class="constant">OTHERWISE_IF_SAY_CS</span><span class="plain">))</span>
&lt;<span class="cwebmacro">This is a say otherwise</span> <span class="cwebmacronumber">8.1.5</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">say_cs</span><span class="plain"> == </span><span class="constant">END_IF_SAY_CS</span><span class="plain">) </span>&lt;<span class="cwebmacro">This is a say end if</span> <span class="cwebmacronumber">8.1.6</span>&gt;<span class="plain">;</span>
<span class="identifier">say_invocations_found</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SSP_sp</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">SSP_sp</span><span class="plain"> == </span><span class="constant">1</span><span class="plain">) &amp;&amp; (</span><span class="identifier">SSP_stack</span><span class="plain">[0] == -1)) {</span>
<span class="comment">an if without an end if, which uniquely is legal</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
&lt;<span class="cwebmacro">Issue a problem message for an SSP without end</span> <span class="cwebmacronumber">8.1.7</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">it_is_not_worth_adding</span><span class="plain"> = </span><span class="identifier">it_was_not_worth_adding</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8">&#167;8</a>.</p>
<p class="inwebparagraph"><a id="SP8_1_1"></a><b>&#167;8.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">This starts a complex SSP</span> <span class="cwebmacronumber">8.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SSP_sp</span><span class="plain"> &gt;= </span><span class="constant">MAX_COMPLEX_SAY_DEPTH</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Issue a problem message for an overcomplex SSP</span> <span class="cwebmacronumber">8.1.1.1</span>&gt;<span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">SSP_invocations</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">] = </span><span class="identifier">inv</span><span class="plain">;</span>
<span class="identifier">SSP_stack_otherwised</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">] = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">SSP_stack</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">++] = </span><span class="identifier">ssp_tok</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8_1">&#167;8.1</a>.</p>
<p class="inwebparagraph"><a id="SP8_1_2"></a><b>&#167;8.1.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">This is a middle term in a complex SSP</span> <span class="cwebmacronumber">8.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">SSP_sp</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">SSP_stack</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">-1] != -1) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">compare_words</span><span class="plain">(</span><span class="identifier">SSP_stack</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">-1], </span><span class="identifier">ssp_tok</span><span class="plain">))) {</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">SSP_invocations</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">-1], </span><span class="constant">ssp_segment_count_ANNOT</span><span class="plain">,</span>
<span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">SSP_invocations</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">-1], </span><span class="constant">ssp_segment_count_ANNOT</span><span class="plain">)+1);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="constant">ssp_segment_count_ANNOT</span><span class="plain">,</span>
<span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">SSP_invocations</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">-1], </span><span class="constant">ssp_segment_count_ANNOT</span><span class="plain">));</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue a problem message for middle without start</span> <span class="cwebmacronumber">8.1.2.1</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8_1">&#167;8.1</a>.</p>
<p class="inwebparagraph"><a id="SP8_1_3"></a><b>&#167;8.1.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">This ends a complex SSP</span> <span class="cwebmacronumber">8.1.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">SSP_sp</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">SSP_stack</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">-1] != -1) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">compare_words</span><span class="plain">(</span><span class="identifier">SSP_stack</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">-1], </span><span class="identifier">ssp_tok</span><span class="plain">))) {</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">SSP_invocations</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">-1], </span><span class="constant">ssp_segment_count_ANNOT</span><span class="plain">,</span>
<span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">SSP_invocations</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">-1], </span><span class="constant">ssp_segment_count_ANNOT</span><span class="plain">)+1);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">SSP_invocations</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">-1], </span><span class="constant">ssp_closing_segment_wn_ANNOT</span><span class="plain">, </span><span class="identifier">ssp_ctok</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="constant">ssp_segment_count_ANNOT</span><span class="plain">,</span>
<span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">SSP_invocations</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">-1], </span><span class="constant">ssp_segment_count_ANNOT</span><span class="plain">));</span>
<span class="identifier">SSP_sp</span><span class="plain">--;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue a problem message for end without start</span> <span class="cwebmacronumber">8.1.3.1</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8_1">&#167;8.1</a>.</p>
<p class="inwebparagraph"><a id="SP8_1_4"></a><b>&#167;8.1.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">This is a say if</span> <span class="cwebmacronumber">8.1.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">say_if_nesting</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">say_if_nesting</span><span class="plain">++;</span>
<span class="identifier">SSP_invocations</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">] = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">SSP_stack_otherwised</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">] = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">SSP_stack</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">++] = -1;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue a problem message for nested say if</span> <span class="cwebmacronumber">8.1.4.1</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8_1">&#167;8.1</a>.</p>
<p class="inwebparagraph"><a id="SP8_1_5"></a><b>&#167;8.1.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">This is a say otherwise</span> <span class="cwebmacronumber">8.1.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">say_if_nesting</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Issue a problem message for say otherwise without say if</span> <span class="cwebmacronumber">8.1.5.1</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SSP_sp</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SSP_stack</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">-1] != -1)</span>
&lt;<span class="cwebmacro">Issue a problem message for say otherwise interleaved with another construction</span> <span class="cwebmacronumber">8.1.5.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SSP_stack_otherwised</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">-1])</span>
&lt;<span class="cwebmacro">Issue a problem message for two say otherwises</span> <span class="cwebmacronumber">8.1.5.3</span>&gt;
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">say_cs</span><span class="plain"> == </span><span class="constant">OTHERWISE_SAY_CS</span><span class="plain">) </span><span class="identifier">SSP_stack_otherwised</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">-1] = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8_1">&#167;8.1</a>.</p>
<p class="inwebparagraph"><a id="SP8_1_6"></a><b>&#167;8.1.6. </b><code class="display">
&lt;<span class="cwebmacrodefn">This is a say end if</span> <span class="cwebmacronumber">8.1.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">say_if_nesting</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span>&lt;<span class="cwebmacro">Issue a problem message for say end if without say if</span> <span class="cwebmacronumber">8.1.6.1</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">SSP_sp</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">SSP_stack</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">-1] != -1))</span>
&lt;<span class="cwebmacro">Issue a problem message for say end if interleaved with another construction</span> <span class="cwebmacronumber">8.1.6.2</span>&gt;
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">say_if_nesting</span><span class="plain">--;</span>
<span class="identifier">SSP_sp</span><span class="plain">--;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8_1">&#167;8.1</a>.</p>
<p class="inwebparagraph"><a id="SP8_1_2_1"></a><b>&#167;8.1.2.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for middle without start</span> <span class="cwebmacronumber">8.1.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_issued</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_ComplicatedSayStructure</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In the text at %1, the text substitution '[%2]' ought to occur as the "</span>
<span class="string">"middle part of its construction, but it appears to be on its own."</span><span class="plain">);</span>
<span class="functiontext">Routines::Compile::add_say_construction_to_error</span><span class="plain">(</span><span class="identifier">ssp_tok</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="identifier">problem_issued</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8_1_2">&#167;8.1.2</a>.</p>
<p class="inwebparagraph"><a id="SP8_1_3_1"></a><b>&#167;8.1.3.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for end without start</span> <span class="cwebmacronumber">8.1.3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_issued</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_ComplicatedSayStructure2</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In the text at %1, the text substitution '[%2]' ought to occur as the "</span>
<span class="string">"ending part of its construction, but it appears to be on its own."</span><span class="plain">);</span>
<span class="functiontext">Routines::Compile::add_say_construction_to_error</span><span class="plain">(</span><span class="identifier">ssp_tok</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="identifier">problem_issued</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8_1_3">&#167;8.1.3</a>.</p>
<p class="inwebparagraph"><a id="SP8_1_4_1"></a><b>&#167;8.1.4.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for nested say if</span> <span class="cwebmacronumber">8.1.4.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_issued</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_SayIfNested</span><span class="plain">),</span>
<span class="string">"a second '[if ...]' text substitution occurs inside an existing one"</span><span class="plain">,</span>
<span class="string">"which makes this text too complicated. While a single text can contain "</span>
<span class="string">"more than one '[if ...]', this can only happen if the old if is finished "</span>
<span class="string">"with an '[end if]' or the new one is written '[otherwise if]'. If you "</span>
<span class="string">"need more complicated variety than this allows, the best approach is "</span>
<span class="string">"to define a new text substitution of your own ('To say fiddly details: "</span>
<span class="string">"...') and then use it in this text by including the '[fiddly details]'."</span><span class="plain">);</span>
<span class="identifier">problem_issued</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8_1_4">&#167;8.1.4</a>.</p>
<p class="inwebparagraph"><a id="SP8_1_1_1"></a><b>&#167;8.1.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for an overcomplex SSP</span> <span class="cwebmacronumber">8.1.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_issued</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_SayOverComplex</span><span class="plain">),</span>
<span class="string">"this is too complex a text substitution"</span><span class="plain">,</span>
<span class="string">"and needs to be simplified. You might find it helful to define "</span>
<span class="string">"a new text substitution of your own ('To say fiddly details: "</span>
<span class="string">"...') and then use it in this text by including the '[fiddly details]'."</span><span class="plain">);</span>
<span class="identifier">problem_issued</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8_1_1">&#167;8.1.1</a>.</p>
<p class="inwebparagraph"><a id="SP8_1_5_1"></a><b>&#167;8.1.5.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for say otherwise without say if</span> <span class="cwebmacronumber">8.1.5.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_issued</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_SayOtherwiseWithoutIf</span><span class="plain">),</span>
<span class="string">"an '[otherwise]' text substitution occurs where there appears to be no "</span>
<span class="string">"[if ...]"</span><span class="plain">,</span>
<span class="string">"which doesn't make sense - there is nothing for it to be otherwise to."</span><span class="plain">);</span>
<span class="identifier">problem_issued</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8_1_5">&#167;8.1.5</a>.</p>
<p class="inwebparagraph"><a id="SP8_1_5_2"></a><b>&#167;8.1.5.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for say otherwise interleaved with another construction</span> <span class="cwebmacronumber">8.1.5.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_issued</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_ComplicatedSayStructure5</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In the text at %1, the '[%2]' ought to occur inside an [if ...], but "</span>
<span class="string">"is cut off because it has been interleaved with a complicated say "</span>
<span class="string">"construction."</span><span class="plain">);</span>
<span class="functiontext">Routines::Compile::add_say_construction_to_error</span><span class="plain">(</span><span class="identifier">SSP_stack</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">-1]);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="identifier">problem_issued</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8_1_5">&#167;8.1.5</a>.</p>
<p class="inwebparagraph"><a id="SP8_1_5_3"></a><b>&#167;8.1.5.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for two say otherwises</span> <span class="cwebmacronumber">8.1.5.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_issued</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TwoSayOtherwises</span><span class="plain">),</span>
<span class="string">"there's already an (unconditional) \"[otherwise]\" or \"[else]\" "</span>
<span class="string">"in this text substitution"</span><span class="plain">,</span>
<span class="string">"so it doesn't make sense to follow that with a further one."</span><span class="plain">);</span>
<span class="identifier">problem_issued</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8_1_5">&#167;8.1.5</a>.</p>
<p class="inwebparagraph"><a id="SP8_1_6_1"></a><b>&#167;8.1.6.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for say end if without say if</span> <span class="cwebmacronumber">8.1.6.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_issued</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_SayEndIfWithoutSayIf</span><span class="plain">),</span>
<span class="string">"an '[end if]' text substitution occurs where there appears to be no "</span>
<span class="string">"[if ...]"</span><span class="plain">,</span>
<span class="string">"which doesn't make sense - there is nothing for it to end."</span><span class="plain">);</span>
<span class="identifier">problem_issued</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8_1_6">&#167;8.1.6</a>.</p>
<p class="inwebparagraph"><a id="SP8_1_6_2"></a><b>&#167;8.1.6.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for say end if interleaved with another construction</span> <span class="cwebmacronumber">8.1.6.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_issued</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_ComplicatedSayStructure4</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In the text at %1, the '[%2]' is cut off from its [if ...], because "</span>
<span class="string">"it has been interleaved with a complicated say construction."</span><span class="plain">);</span>
<span class="functiontext">Routines::Compile::add_say_construction_to_error</span><span class="plain">(</span><span class="identifier">SSP_stack</span><span class="plain">[</span><span class="identifier">SSP_sp</span><span class="plain">-1]);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="identifier">problem_issued</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8_1_6">&#167;8.1.6</a>.</p>
<p class="inwebparagraph"><a id="SP8_1_7"></a><b>&#167;8.1.7. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for an SSP without end</span> <span class="cwebmacronumber">8.1.7</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_issued</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">stinv</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">ssp_tok</span><span class="plain"> = -1;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">SSP_sp</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SSP_invocations</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]) {</span>
<span class="identifier">stinv</span><span class="plain"> = </span><span class="identifier">SSP_invocations</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">];</span>
<span class="identifier">ssp_tok</span><span class="plain"> = </span><span class="identifier">SSP_stack</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">];</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">stinv</span><span class="plain">) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">stinv</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_ComplicatedSayStructure3</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"In the text at %1, the text substitution '[%2]' seems to start a "</span>
<span class="string">"complicated say construction, but it doesn't have a matching end."</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ssp_tok</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) </span><span class="functiontext">Routines::Compile::add_say_construction_to_error</span><span class="plain">(</span><span class="identifier">ssp_tok</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="identifier">problem_issued</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8_1">&#167;8.1</a>.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Problem messages for complex say constructions. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Routines::Compile::add_say_construction_to_error</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">ssp_tok</span><span class="plain">) {</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">" %P(The construction I'm thinking of is '"</span><span class="plain">);</span>
<span class="functiontext">Routines::Compile::add_scte_list</span><span class="plain">(</span><span class="identifier">ssp_tok</span><span class="plain">, </span><span class="constant">SSP_START</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">" ... "</span><span class="plain">);</span>
<span class="functiontext">Routines::Compile::add_scte_list</span><span class="plain">(</span><span class="identifier">ssp_tok</span><span class="plain">, </span><span class="constant">SSP_MIDDLE</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">" ... "</span><span class="plain">);</span>
<span class="functiontext">Routines::Compile::add_scte_list</span><span class="plain">(</span><span class="identifier">ssp_tok</span><span class="plain">, </span><span class="constant">SSP_END</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"'.)"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Routines::Compile::add_scte_list</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">ssp_tok</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">list_pos</span><span class="plain">) {</span>
<span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain">; </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">ct</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">, </span><span class="reserved">phrase</span><span class="plain">) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Phrases::TypeData::ssp_matches</span><span class="plain">(&amp;(</span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">type_data</span><span class="plain">), </span><span class="identifier">ssp_tok</span><span class="plain">, </span><span class="identifier">list_pos</span><span class="plain">, &amp;</span><span class="identifier">W</span><span class="plain">)) {</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(3, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ct</span><span class="plain">++ == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"[%3]"</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"/[%3]"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Routines::Compile::add_say_construction_to_error is used in <a href="#SP8_1_2_1">&#167;8.1.2.1</a>, <a href="#SP8_1_3_1">&#167;8.1.3.1</a>, <a href="#SP8_1_5_2">&#167;8.1.5.2</a>, <a href="#SP8_1_6_2">&#167;8.1.6.2</a>, <a href="#SP8_1_7">&#167;8.1.7</a>.</p>
<p class="endnote">The function Routines::Compile::add_scte_list appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="25-cii.html">Back to 'Compile Invocations Inline'</a></li><li><i>(This section ends Chapter 25: Compilation.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>