1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 00:24:22 +03:00
inform7/docs/assertions-module/2-is.html
2022-05-07 13:11:24 +01:00

1615 lines
287 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Imperative Subtrees</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Preform-Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Inform.png" height=72">
</a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../indocn.html">indoc</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
<li><a href="../inrtpsn.html">inrtps</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=18> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="../../../inweb/index.html">inweb</a></li>
<li><a href="../../../intest/index.html">intest</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Imperative Subtrees' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inform7n.html">Inform7</a></li><li><a href="index.html">assertions</a></li><li><a href="index.html#2">Chapter 2: Declarations</a></li><li><b>Imperative Subtrees</b></li></ul></div>
<p class="purpose">To tidy up blocks of rule and phrase definition in the syntax tree.</p>
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>Blocks of imperative code in Inform 7 source text enter the syntax tree
at <span class="extract"><span class="extract-syntax">IMPERATIVE_NT</span></span> nodes: some define phrases, some define rules. Those nodes
are initially followed by a run of <span class="extract"><span class="extract-syntax">UNKNOWN_NT</span></span> nodes for the actual code.
The process of "acceptance" turns such definitions into a subtree, as
follows:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">IMPERATIVE_NT 'every turn' IMPERATIVE_NT 'every turn</span>
<span class="plain-syntax">UNKNOWN_NT 'say "Hello!"' --&gt; INVOCATION_LIST_NT 'say "Hello!"'</span>
<span class="plain-syntax">UNKNOWN_NT 'now the guard is alert' INVOCATION_LIST_NT 'now the guard is alert'</span>
</pre>
<p class="commentary"><a href="2-is.html#SP1" class="internal">ImperativeSubtrees::accept</a> needs to be called on every <span class="extract"><span class="extract-syntax">IMPERATIVE_NT</span></span> node in order
for this to work; note that it does nothing further, but also causes no harm,
if called multiple times on the same node. <a href="2-is.html#SP1" class="internal">ImperativeSubtrees::accept_all</a> can
therefore safely be used to sweep up any <span class="extract"><span class="extract-syntax">IMPERATIVE_NT</span></span> nodes not already processed.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ImperativeSubtrees::accept_all</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">; </span><span class="comment-syntax"> for then the tree is perhaps broken anyway</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">SyntaxTree::traverse</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><a href="2-is.html#SP1" class="function-link"><span class="function-syntax">ImperativeSubtrees::accept</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ImperativeSubtrees::accept</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">ImperativeSubtrees::accept</span></span>:<br/>Passes through Major Nodes - <a href="2-ptmn.html#SP3_1_1">&#167;3.1.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="2-is.html#SP1" class="function-link"><span class="function-syntax">ImperativeSubtrees::accept_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ImperativeSubtrees::accept_body</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">ImperativeSubtrees::accept_body</span></span>:<br/>Adjectival Definition Family - <a href="5-adf.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="2-is.html#SP1" class="function-link"><span class="function-syntax">ImperativeSubtrees::accept_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ImperativeSubtrees::accept_inner</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">accept_header</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">) == </span><span class="identifier-syntax">IMPERATIVE_NT</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_impdef</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">header</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">end_def</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">end_def</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">end_def</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) == </span><span class="identifier-syntax">UNKNOWN_NT</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">end_def</span><span class="plain-syntax"> = </span><span class="identifier-syntax">end_def</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">header</span><span class="plain-syntax"> != </span><span class="identifier-syntax">end_def</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> splice so that </span><span class="extract"><span class="extract-syntax">p-&gt;next</span></span><span class="comment-syntax"> to </span><span class="extract"><span class="extract-syntax">end_def</span></span><span class="comment-syntax"> become the children of </span><span class="extract"><span class="extract-syntax">p</span></span><span class="comment-syntax">:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">end_def</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">end_def</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inv_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">; </span><span class="identifier-syntax">inv_p</span><span class="plain-syntax">; </span><span class="identifier-syntax">inv_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inv_p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">InvocationLists::make_into_list_node</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv_p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1" class="named-paragraph-link"><span class="named-paragraph">Parse the structure of the code block</span><span class="named-paragraph-number">1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> worry about the preamble in the node p</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">accept_header</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_impdef</span><span class="plain-syntax">(</span><span class="identifier-syntax">header</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="5-id.html#SP2" class="function-link"><span class="function-syntax">ImperativeDefinitions::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">header</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP1_1" class="paragraph-anchor"></a><b>&#167;1.1. </b>After acceptance, and therefore exactly once, the structure of the code in
the definition is parsed and checked for sanity.
</p>
<p class="commentary">Though it is now a historical relic, Inform has two different syntaxes for
blocks of code: "colon syntax", introduced in March 2008, which uses Python-like
colons and indentation to show structural subdivision; and "begin/end syntax",
which uses explicit marker phrases like "end if" and "end while". The compiler
continues to support both though they cannot be mixed in a single <span class="extract"><span class="extract-syntax">IMPERATIVE_NT</span></span>
subtree.
</p>
<p class="commentary">The old syntax is retained not for compatibility with old code &mdash; very little
remains from the pre-2008 era which has not been modernised &mdash; but because
some partially sighted users find tabbed indentation difficult to manage
with screen-readers.
</p>
<p class="commentary">Here, then, we must work out which syntax is used, decipher it, and turn the
list into a proper tree structure in a single unified format. We will also
try to find and report as many problems as we can which are due to code blocks
being improperly opened or closed, because punctuation errors in rules are
one of the biggest sources of beginners' difficulties with Inform, and we want
to catch and report these problems early.
</p>
<p class="commentary">This means looking out for control structures such as "if" and "while": see
<a href="../supervisor-module/6-cs.html" class="internal">Control Structures (in supervisor)</a> for where these are defined.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse the structure of the code block</span><span class="named-paragraph-number">1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">initial_problem_count</span><span class="plain-syntax"> = </span><span class="identifier-syntax">problem_count</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">uses_colon_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">uses_begin_end_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mispunctuates_begin_end_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">requires_colon_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_1" class="named-paragraph-link"><span class="named-paragraph">(a.1) See which block syntax is used by conditionals and loops</span><span class="named-paragraph-number">1.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_2" class="named-paragraph-link"><span class="named-paragraph">(a.2) Report problems if the two syntaxes are mixed up with each other</span><span class="named-paragraph-number">1.1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">initial_problem_count</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">uses_colon_syntax</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_3" class="named-paragraph-link"><span class="named-paragraph">(b.1) Annotate the parse tree with indentation levels</span><span class="named-paragraph-number">1.1.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_4" class="named-paragraph-link"><span class="named-paragraph">(b.2) Annotate the parse tree with control structure usage</span><span class="named-paragraph-number">1.1.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_5" class="named-paragraph-link"><span class="named-paragraph">(c) Expand comma notation for blocks</span><span class="named-paragraph-number">1.1.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">initial_problem_count</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">uses_colon_syntax</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6" class="named-paragraph-link"><span class="named-paragraph">(d) Insert end nodes and check the indentation</span><span class="named-paragraph-number">1.1.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">initial_problem_count</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_7" class="named-paragraph-link"><span class="named-paragraph">(e) Structure the parse tree to match the use of control structures</span><span class="named-paragraph-number">1.1.7</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">initial_problem_count</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_8" class="named-paragraph-link"><span class="named-paragraph">(f) Police the structure of the parse tree</span><span class="named-paragraph-number">1.1.8</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">initial_problem_count</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_9" class="named-paragraph-link"><span class="named-paragraph">(g) Optimise out the otherwise if nodes</span><span class="named-paragraph-number">1.1.9</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">initial_problem_count</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_11" class="named-paragraph-link"><span class="named-paragraph">(h) Remove any end markers as no longer necessary</span><span class="named-paragraph-number">1.1.11</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">initial_problem_count</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">uses_colon_syntax</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_13" class="named-paragraph-link"><span class="named-paragraph">(i) Remove any begin markers as no longer necessary</span><span class="named-paragraph-number">1.1.13</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_15" class="named-paragraph-link"><span class="named-paragraph">(j) Insert code block nodes so that nodes needing to be parsed are childless</span><span class="named-paragraph-number">1.1.15</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_17" class="named-paragraph-link"><span class="named-paragraph">(k) Insert instead marker nodes</span><span class="named-paragraph-number">1.1.17</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_19" class="named-paragraph-link"><span class="named-paragraph">(l) Break up say phrases</span><span class="named-paragraph-number">1.1.19</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1">&#167;1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_1" class="paragraph-anchor"></a><b>&#167;1.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(a.1) See which block syntax is used by conditionals and loops</span><span class="named-paragraph-number">1.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ControlStructures::detect</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">syntax_used</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">colon_block_command_ANNOT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">syntax_used</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) { </span><span class="comment-syntax"> i.e., doesn't end with a colon</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> don't count "if x is 1, let y be 2" &mdash; with no block &mdash; as deciding it</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">subordinate_to</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (!(</span><span class="function-syntax">&lt;phrase-beginning-block&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)))))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">syntax_used</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">syntax_used</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">syntax_used</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">uses_colon_syntax</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">uses_colon_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Note what looks like a begin-end piece of syntax</span><span class="named-paragraph-number">1.1.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">requires_new_syntax</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">requires_colon_syntax</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">requires_colon_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ControlStructures::detect_end</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">uses_begin_end_syntax</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">uses_begin_end_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1">&#167;1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_1_1" class="paragraph-anchor"></a><b>&#167;1.1.1.1. </b>It's possible in oddball cases to mis-punctuate such as to fool us, so:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Note what looks like a begin-end piece of syntax</span><span class="named-paragraph-number">1.1.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">uses_begin_end_syntax</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">mispunctuates_begin_end_syntax</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;phrase-beginning-block&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">uses_begin_end_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mispunctuates_begin_end_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_1">&#167;1.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_2" class="paragraph-anchor"></a><b>&#167;1.1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(a.2) Report problems if the two syntaxes are mixed up with each other</span><span class="named-paragraph-number">1.1.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">uses_colon_syntax</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">mispunctuates_begin_end_syntax</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">mispunctuates_begin_end_syntax</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_BadOldSyntax</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The rule or phrase definition %1 seems to use indentation and colons to group "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"phrases together into 'if', 'repeat' or 'while' blocks. That's fine, but then "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this phrase seems to be missing some punctuation - %2. Perhaps a colon is missing?"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">uses_colon_syntax</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">uses_begin_end_syntax</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">uses_colon_syntax</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">uses_begin_end_syntax</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_BothBlockSyntaxes</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The rule or phrase definition %1 seems to use both ways of grouping phrases "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"together into 'if', 'repeat' and 'while' blocks at once. Inform allows two "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"alternative forms, but they cannot be mixed in the same definition. %P"</span>
<span class="plain-syntax"> </span><span class="string-syntax">"One way is to end the 'if', 'repeat' or 'while' phrases with a 'begin', and "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"then to match that with an 'end if' or similar. ('Otherwise' or 'otherwise if' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"clauses are phrases like any other, and end with semicolons in this case.) "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"You use this begin/end form here, for instance - %3. %P"</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The other way is to end with a colon ':' and then indent the subsequent phrases "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"underneath, using tabs. (Note that any 'otherwise' or 'otherwise if' clauses "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"also have to end with colons in this case.) You use this indented form here - %2."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">requires_colon_syntax</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">uses_begin_end_syntax</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">requires_colon_syntax</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_NotInOldSyntax</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The construction %2, in the rule or phrase definition %1, is only allowed if the "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"rule is written in the 'new' format, that is, with the phrases written one to a "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"line with indentation showing how they are grouped together, and with colons "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"indicating the start of such a group."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1">&#167;1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_3" class="paragraph-anchor"></a><b>&#167;1.1.3. </b>If we're using Pythonesque notation, then the number of tab stops of
indentation of a phrase tells us where it belongs in the structure, so
we mark up the tree with that information.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(b.1) Annotate the parse tree with indentation levels</span><span class="named-paragraph-number">1.1.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation_level_ANNOT</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Lexer::indentation_level</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">))));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexer::indentation_level</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation_level_ANNOT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1">&#167;1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_4" class="paragraph-anchor"></a><b>&#167;1.1.4. </b>Note that we are a little cautious about recognising phrases which will
open blocks, such as "repeat...", because of the dangers of false positives;
so we look for the "begin" keyword, or the colon. We're less cautious with
subordinate phrases (such as "otherwise") because we know their wonding
more certainly, and similarly for "end X" phrases.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(b.2) Annotate the parse tree with control structure usage</span><span class="named-paragraph-number">1.1.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">csp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">csp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ControlStructures::detect</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">colon_block_command_ANNOT</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="function-syntax">&lt;phrase-beginning-block&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">))) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">subordinate_to</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">csp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">case_CSP</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_4_1" class="named-paragraph-link"><span class="named-paragraph">Trim a switch case to just the case value</span><span class="named-paragraph-number">1.1.4.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">csp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ControlStructures::detect_end</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">) </span><span class="identifier-syntax">Node::set_end_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">csp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1">&#167;1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_4_1" class="paragraph-anchor"></a><b>&#167;1.1.4.1. </b>At this point anything at all can be a case value: it won't be parsed
or type-checked until compilation.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Trim a switch case to just the case value</span><span class="named-paragraph-number">1.1.4.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;control-structure-phrase&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">));</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_4">&#167;1.1.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_5" class="paragraph-anchor"></a><b>&#167;1.1.5. </b>"Comma notation" is when a comma is used in an "if" statement to divide
off only a single consequential phrase, as in
</p>
<blockquote>
<p>if the hat is worn, try dropping the hat;</p>
</blockquote>
<p class="commentary">Such a line occupies a single node in its routine's parse tree, and we need
to break this up.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(c) Expand comma notation for blocks</span><span class="named-paragraph-number">1.1.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">csp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">csp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ControlStructures::detect</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">if_CSP</span><span class="plain-syntax">) &amp;&amp; (</span><span class="function-syntax">&lt;phrase-with-comma-notation&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">))))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_5_1" class="named-paragraph-link"><span class="named-paragraph">Effect a comma expansion</span><span class="named-paragraph-number">1.1.5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1">&#167;1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_5_1" class="paragraph-anchor"></a><b>&#167;1.1.5.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Effect a comma expansion</span><span class="named-paragraph-number">1.1.5.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">BCW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;phrase-with-comma-notation&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">); </span><span class="comment-syntax"> text before the comma</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">ACW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;phrase-with-comma-notation&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">); </span><span class="comment-syntax"> text after the comma</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> First trim and annotate the "if ..." part</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">colon_block_command_ANNOT</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">); </span><span class="comment-syntax"> it previously had no colon...</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">csp</span><span class="plain-syntax">); </span><span class="comment-syntax"> ...and therefore didn't have its CSP set</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">BCW</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Now make a new node for the "then" part, indenting it one step inward</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">then_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InvocationLists::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">ACW</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">then_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">results_from_splitting_ANNOT</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">then_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation_level_ANNOT</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation_level_ANNOT</span><span class="plain-syntax">) + </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">last_node_of_if_construction</span><span class="plain-syntax"> = </span><span class="identifier-syntax">then_node</span><span class="plain-syntax">, *</span><span class="identifier-syntax">rest_of_defn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Attach the "then" node after the "if" node:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">then_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_5_1_1" class="named-paragraph-link"><span class="named-paragraph">Deal with an immediately following otherwise node, if there is one</span><span class="named-paragraph-number">1.1.5.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">uses_colon_syntax</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_node_of_if_construction</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><a href="2-is.html#SP4" class="function-link"><span class="function-syntax">ImperativeSubtrees::end_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_node_of_if_construction</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rest_of_defn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_node_of_if_construction</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rest_of_defn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_5">&#167;1.1.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_5_1_1" class="paragraph-anchor"></a><b>&#167;1.1.5.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Deal with an immediately following otherwise node, if there is one</span><span class="named-paragraph-number">1.1.5.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rest_of_defn</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">uses_colon_syntax</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation_level_ANNOT</span><span class="plain-syntax">) ==</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">rest_of_defn</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation_level_ANNOT</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">rest_of_defn</span><span class="plain-syntax">) == </span><span class="identifier-syntax">otherwise_CSP</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_5_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Deal with an immediately following otherwise</span><span class="named-paragraph-number">1.1.5.1.1.1</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ControlStructures::abbreviated_otherwise</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">rest_of_defn</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_5_1_1_2" class="named-paragraph-link"><span class="named-paragraph">Deal with an abbreviated otherwise node</span><span class="named-paragraph-number">1.1.5.1.1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_5_1">&#167;1.1.5.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_5_1_1_1" class="paragraph-anchor"></a><b>&#167;1.1.5.1.1.1. </b>We string a plain "otherwise" node onto the "if" construction.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Deal with an immediately following otherwise</span><span class="named-paragraph-number">1.1.5.1.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">then_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rest_of_defn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_node_of_if_construction</span><span class="plain-syntax"> = </span><span class="identifier-syntax">last_node_of_if_construction</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rest_of_defn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rest_of_defn</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_5_1_1">&#167;1.1.5.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_5_1_1_2" class="paragraph-anchor"></a><b>&#167;1.1.5.1.1.2. </b>An abbreviated otherwise clause looks like this:
</p>
<blockquote>
<p>otherwise award 4 points;</p>
</blockquote>
<p class="commentary">and we want to split this, too, into distinct nodes.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Deal with an abbreviated otherwise node</span><span class="named-paragraph-number">1.1.5.1.1.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">CODE_BLOCK_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">results_from_splitting_ANNOT</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation_level_ANNOT</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation_level_ANNOT</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Wordings::one_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">rest_of_defn</span><span class="plain-syntax">)))); </span><span class="comment-syntax"> extract just the word "otherwise"</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">otherwise_CSP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">then_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rest_of_defn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">rest_of_defn</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Wordings::trim_first_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">rest_of_defn</span><span class="plain-syntax">))); </span><span class="comment-syntax"> to remove the "otherwise"</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">rest_of_defn</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation_level_ANNOT</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">rest_of_defn</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation_level_ANNOT</span><span class="plain-syntax">) + </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_node_of_if_construction</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rest_of_defn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rest_of_defn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rest_of_defn</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_5_1_1">&#167;1.1.5.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_6" class="paragraph-anchor"></a><b>&#167;1.1.6. </b>If the old-style syntax is used, there are explicit "end if", "end repeat"
and "end while" nodes in the list already. But if the Pythonesque syntax is
used then we need to create these nodes and insert them into the list; we
do these by reading off the structure from the pattern of indentation. It's
quite a long task, since this pattern may contain errors, which we have to
report more or less helpfully.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(d) Insert end nodes and check the indentation</span><span class="named-paragraph-number">1.1.6</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">, *</span><span class="identifier-syntax">prev</span><span class="plain-syntax">, *</span><span class="identifier-syntax">run_on_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first_misaligned_phrase</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">first_overindented_phrase</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax">, </span><span class="identifier-syntax">indent</span><span class="plain-syntax">, </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">indent_misalign</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">indent_overmuch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">just_opened_block</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> the blocks open stack holds blocks currently open</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">blstack_opening_phrase</span><span class="plain-syntax">[</span><span class="identifier-syntax">GROSS_AMOUNT_OF_INDENTATION</span><span class="plain-syntax">+1];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">blstack_construct</span><span class="plain-syntax">[</span><span class="identifier-syntax">GROSS_AMOUNT_OF_INDENTATION</span><span class="plain-syntax">+1];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">blstack_stage</span><span class="plain-syntax">[</span><span class="identifier-syntax">GROSS_AMOUNT_OF_INDENTATION</span><span class="plain-syntax">+1];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">suppress_further_problems</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation_level_ANNOT</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem message for failing to start flush on the left margin</span><span class="named-paragraph-number">1.1.6.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">prev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">, </span><span class="identifier-syntax">k</span><span class="plain-syntax">=1; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">prev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">, </span><span class="identifier-syntax">k</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_2" class="named-paragraph-link"><span class="named-paragraph">Determine actual indentation of this phrase</span><span class="named-paragraph-number">1.1.6.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_3" class="named-paragraph-link"><span class="named-paragraph">Compare actual indentation to what we expect from structure so far</span><span class="named-paragraph-number">1.1.6.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_4" class="named-paragraph-link"><span class="named-paragraph">Insert begin marker and increase expected indentation if a block begins here</span><span class="named-paragraph-number">1.1.6.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">indent</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_5" class="named-paragraph-link"><span class="named-paragraph">Try closing blocks to bring expected indentation down to match</span><span class="named-paragraph-number">1.1.6.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">indent_overmuch</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_7" class="named-paragraph-link"><span class="named-paragraph">Issue problem message for an excess of indentation</span><span class="named-paragraph-number">1.1.6.7</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">run_on_at</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_8" class="named-paragraph-link"><span class="named-paragraph">Issue problem message for run-ons within phrase definition</span><span class="named-paragraph-number">1.1.6.8</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">indent_misalign</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_6" class="named-paragraph-link"><span class="named-paragraph">Issue problem message for misaligned indentation</span><span class="named-paragraph-number">1.1.6.6</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1">&#167;1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_6_1" class="paragraph-anchor"></a><b>&#167;1.1.6.1. </b>Controversially:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem message for failing to start flush on the left margin</span><span class="named-paragraph-number">1.1.6.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_NonflushRule</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The phrase or rule definition %1 is written using tab indentations "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"to show how its phrases are to be grouped together. But in that "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"case the opening line needs to be on the left margin, not indented."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">suppress_further_problems</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_6">&#167;1.1.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_6_2" class="paragraph-anchor"></a><b>&#167;1.1.6.2. </b>Here we set <span class="extract"><span class="extract-syntax">indent</span></span> to the number of tab-stops in from the margin, or to
<span class="extract"><span class="extract-syntax">expected_indent</span></span> if the text does not appear to be at the start of its own
line in the source (because it runs on from a previous phrase, in
which case we set the <span class="extract"><span class="extract-syntax">run_on_at</span></span> flag: except for following on from cases
in switches with a non-control-structure, which is allowed, because otherwise
the lines often look silly and short).
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Determine actual indentation of this phrase</span><span class="named-paragraph-number">1.1.6.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">indent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation_level_ANNOT</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">indent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation_level_ANNOT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::break_before</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'\n'</span><span class="plain-syntax">: </span><span class="identifier-syntax">indent</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'\t'</span><span class="plain-syntax">: </span><span class="identifier-syntax">indent</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">prev</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pcsp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">prev</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pcsp</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">pcsp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allow_run_on</span><span class="plain-syntax">)) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">results_from_splitting_ANNOT</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">run_on_at</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="identifier-syntax">run_on_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">indent</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">GROSS_AMOUNT_OF_INDENTATION</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_2_1" class="named-paragraph-link"><span class="named-paragraph">Record an excess of indentation</span><span class="named-paragraph-number">1.1.6.2.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_6">&#167;1.1.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_6_3" class="paragraph-anchor"></a><b>&#167;1.1.6.3. </b>We now know the <span class="extract"><span class="extract-syntax">indent</span></span> level of the line as read, and also the
<span class="extract"><span class="extract-syntax">expected_indent</span></span> given the definition so far. If they agree, fine. If they
don't agree, it isn't necessarily bad news &mdash; if each line's indentation were
a function of the last, there would be no information in it, after all.
Roughly speaking, when <span class="extract"><span class="extract-syntax">indent</span></span> is greater than we expect, that must be
wrong &mdash; it means indentation has jumped inward as if to open a new block,
but blocks are opened explicitly and not by simply raising the indent.
But when <span class="extract"><span class="extract-syntax">indent</span></span> is less than we expect, this may simply mean that the
current block(s) has or have been closed, because blocks are indeed closed
implicitly just by moving the indentation back in.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compare actual indentation to what we expect from structure so far</span><span class="named-paragraph-number">1.1.6.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">indent</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_3_3" class="named-paragraph-link"><span class="named-paragraph">Record a misalignment of indentation</span><span class="named-paragraph-number">1.1.6.3.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_3_2" class="named-paragraph-link"><span class="named-paragraph">Record a phrase within current block</span><span class="named-paragraph-number">1.1.6.3.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">subordinate_to</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_3_1" class="named-paragraph-link"><span class="named-paragraph">Compare actual indentation to what we expect for an intermediate phrase</span><span class="named-paragraph-number">1.1.6.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">just_opened_block</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">indent</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_3_3" class="named-paragraph-link"><span class="named-paragraph">Record a misalignment of indentation</span><span class="named-paragraph-number">1.1.6.3.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">indent</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_5" class="named-paragraph-link"><span class="named-paragraph">Try closing blocks to bring expected indentation down to match</span><span class="named-paragraph-number">1.1.6.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">indent</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_3_2" class="named-paragraph-link"><span class="named-paragraph">Record a phrase within current block</span><span class="named-paragraph-number">1.1.6.3.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_6">&#167;1.1.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_6_3_1" class="paragraph-anchor"></a><b>&#167;1.1.6.3.1. </b>This is a small variation used for an intermediate phrase like "otherwise".
These are required to be at the same indentation as the line which opened the
block, rather than being one tab step in from there: in other words they are
not deemed part of the block itself. They can also occur in "stages", which
is a way to enforce one intermediate phrase only being allowed after another
one &mdash; for instance, "otherwise if..." is not allowed after an "otherwise"
within an "if".
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Compare actual indentation to what we expect for an intermediate phrase</span><span class="named-paragraph-number">1.1.6.3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">indent</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem for an intermediate phrase not matching</span><span class="named-paragraph-number">1.1.6.3.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_5" class="named-paragraph-link"><span class="named-paragraph">Try closing blocks to bring expected indentation down to match</span><span class="named-paragraph-number">1.1.6.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">subordinate_to</span><span class="plain-syntax"> != </span><span class="identifier-syntax">blstack_construct</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">-1])) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem for an intermediate phrase not matching</span><span class="named-paragraph-number">1.1.6.3.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">blstack_stage</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">-1] &gt; </span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">used_at_stage</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_3_1_2" class="named-paragraph-link"><span class="named-paragraph">Issue problem for an intermediate phrase out of sequence</span><span class="named-paragraph-number">1.1.6.3.1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">blstack_stage</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">-1] = </span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">used_at_stage</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax">++;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_6_3">&#167;1.1.6.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_6_4" class="paragraph-anchor"></a><b>&#167;1.1.6.4. </b>In colon syntax, blocks are explicitly opened; they are only implicitly
closed. Here is the opening:
</p>
<p class="commentary">If <span class="extract"><span class="extract-syntax">p</span></span> is a node representing a phrase beginning a block, and we're in the
colon syntax, then it is followed by a word which is the colon: thus if <span class="extract"><span class="extract-syntax">p</span></span>
reads "if x is 2" then the word following the "2" will be ":".
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Insert begin marker and increase expected indentation if a block begins here</span><span class="named-paragraph-number">1.1.6.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">subordinate_to</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">colon_block_command_ANNOT</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">indent_subblocks</span><span class="plain-syntax">) </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">blstack_construct</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">] = </span><span class="identifier-syntax">csp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">blstack_stage</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">] = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">blstack_opening_phrase</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">just_opened_block</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_6">&#167;1.1.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_6_5" class="paragraph-anchor"></a><b>&#167;1.1.6.5. </b>Now for the closing of colon-syntax blocks. We know that blocks must be
being closed if the indentation has jumped backwards: but it may be that many
blocks are being closed at once. (It may also be that the indentation has
gone awry.)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Try closing blocks to bring expected indentation down to match</span><span class="named-paragraph-number">1.1.6.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">just_opened_block</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (!(</span><span class="identifier-syntax">blstack_construct</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">-1]-&gt;</span><span class="identifier-syntax">body_empty_except_for_subordinates</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_5_2" class="named-paragraph-link"><span class="named-paragraph">Issue problem for an empty block</span><span class="named-paragraph-number">1.1.6.5.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">indent</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">opening</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_3_3" class="named-paragraph-link"><span class="named-paragraph">Record a misalignment of indentation</span><span class="named-paragraph-number">1.1.6.3.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">indent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">blstack_construct</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">-1]-&gt;</span><span class="identifier-syntax">body_empty_except_for_subordinates</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">indent</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">indent</span><span class="plain-syntax"> = </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">blstack_construct</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">-1]-&gt;</span><span class="identifier-syntax">indent_subblocks</span><span class="plain-syntax">) </span><span class="identifier-syntax">expected_indent</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">opening</span><span class="plain-syntax"> = </span><span class="identifier-syntax">blstack_opening_phrase</span><span class="plain-syntax">[--</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_5_1" class="named-paragraph-link"><span class="named-paragraph">Insert end marker to match the opening of the block phrase</span><span class="named-paragraph-number">1.1.6.5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_6">&#167;1.1.6</a>, <a href="2-is.html#SP1_1_6_3">&#167;1.1.6.3</a>, <a href="2-is.html#SP1_1_6_3_1">&#167;1.1.6.3.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_6_3_2" class="paragraph-anchor"></a><b>&#167;1.1.6.3.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Record a phrase within current block</span><span class="named-paragraph-number">1.1.6.3.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">blstack_stage</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">-1] == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">blstack_construct</span><span class="plain-syntax">[</span><span class="identifier-syntax">blo_sp</span><span class="plain-syntax">-1]-&gt;</span><span class="identifier-syntax">body_empty_except_for_subordinates</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_6_3_2_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem for non-case in a switch</span><span class="named-paragraph-number">1.1.6.3.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">just_opened_block</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_6_3">&#167;1.1.6.3</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_6_5_1" class="paragraph-anchor"></a><b>&#167;1.1.6.5.1. </b>An end marker is a phrase like "end if" which matches the "if... begin"
above it: here we insert such a marker at a place where the source text
indentation implicitly requires it.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Insert end marker to match the opening of the block phrase</span><span class="named-paragraph-number">1.1.6.5.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">implicit_end</span><span class="plain-syntax"> = </span><a href="2-is.html#SP4" class="function-link"><span class="function-syntax">ImperativeSubtrees::end_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">opening</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">implicit_end</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">; </span><span class="identifier-syntax">prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">implicit_end</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">prev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">implicit_end</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_6_5">&#167;1.1.6.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_6_3_3" class="paragraph-anchor"></a><b>&#167;1.1.6.3.3. </b>Here we throw what amounts to an exception...
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Record a misalignment of indentation</span><span class="named-paragraph-number">1.1.6.3.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">indent_misalign</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">first_misaligned_phrase</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">first_misaligned_phrase</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_6_3">&#167;1.1.6.3</a> (twice), <a href="2-is.html#SP1_1_6_5">&#167;1.1.6.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_6_6" class="paragraph-anchor"></a><b>&#167;1.1.6.6. </b>...and catch it with something of a catch-all message:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem message for misaligned indentation</span><span class="named-paragraph-number">1.1.6.6</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">suppress_further_problems</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$T\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">first_misaligned_phrase</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_MisalignedIndentation</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The phrase or rule definition %1 is written using the 'colon and indentation' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"syntax for its 'if's, 'repeat's and 'while's, where blocks of phrases grouped "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"together are indented one tab step inward from the 'if ...:' or similar phrase "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"to which they belong. But the tabs here seem to be misaligned, and I can't "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"determine the structure. The first phrase going awry in the definition seems "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"to be %2, in case that helps. %P"</span>
<span class="plain-syntax"> </span><span class="string-syntax">"This sometimes happens even when the code looks about right, to the eye, if rows "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"of spaces have been used to indent phrases instead of tabs."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">UsingProblems::diagnose_further</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_6">&#167;1.1.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_6_2_1" class="paragraph-anchor"></a><b>&#167;1.1.6.2.1. </b>And another...
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Record an excess of indentation</span><span class="named-paragraph-number">1.1.6.2.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">indent_overmuch</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">first_overindented_phrase</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">first_overindented_phrase</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_6_2">&#167;1.1.6.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_6_7" class="paragraph-anchor"></a><b>&#167;1.1.6.7. </b>...caught here:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem message for an excess of indentation</span><span class="named-paragraph-number">1.1.6.7</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">suppress_further_problems</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">first_overindented_phrase</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_TooMuchIndentation</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The phrase or rule definition %1 is written using tab indentations to show how "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"its phrases are to be grouped together. But the level of indentation goes far "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"too deep, reaching more than 25 tab stops from the left margin."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_6">&#167;1.1.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_6_8" class="paragraph-anchor"></a><b>&#167;1.1.6.8. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem message for run-ons within phrase definition</span><span class="named-paragraph-number">1.1.6.8</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">suppress_further_problems</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">run_on_at</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_RunOnsInTabbedRoutine</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The phrase or rule definition %1 is written using the 'colon and indentation' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"syntax for its 'if's, 'repeat's and 'while's, but that's only allowed if each "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"phrase in the definition occurs on its own line. So phrases like %2, which follow "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"directly on from the previous phrase, aren't allowed."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_6">&#167;1.1.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_6_5_2" class="paragraph-anchor"></a><b>&#167;1.1.6.5.2. </b>It's a moot point whether the following should be incorrect syntax, but it
far more often happens as an accident than anything else, and it's hard to
think of a sensible use.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for an empty block</span><span class="named-paragraph-number">1.1.6.5.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">suppress_further_problems</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$T\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">prev</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EmptyIndentedBlock</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The phrase or rule definition %1 is written using the 'colon and indentation' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"syntax for its 'if's, 'repeat's and 'while's, where blocks of phrases grouped "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"together are indented one tab step inward from the 'if ...:' or similar phrase "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"to which they belong. But the phrase %2, which ought to begin a block, is "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"immediately followed by %3 at the same or a lower indentation, so the block "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"seems to be empty - this must mean there has been a mistake in indenting the "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"phrases."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_6_5">&#167;1.1.6.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_6_3_2_1" class="paragraph-anchor"></a><b>&#167;1.1.6.3.2.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for non-case in a switch</span><span class="named-paragraph-number">1.1.6.3.2.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">suppress_further_problems</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source_eliding_begin</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_NonCaseInIf</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"In the phrase or rule definition %1, the phrase %2 came as a surprise since "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"it was not a case in an 'if X is...' but was instead some other miscellaneous "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"instruction."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_6_3_2">&#167;1.1.6.3.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_6_3_1_1" class="paragraph-anchor"></a><b>&#167;1.1.6.3.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for an intermediate phrase not matching</span><span class="named-paragraph-number">1.1.6.3.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">indent_misalign</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">suppress_further_problems</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">subordinate_to</span><span class="plain-syntax"> == </span><span class="identifier-syntax">if_CSP</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$T\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_MisalignedOtherwise</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this doesn't match a corresponding 'if'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"as it must. An 'otherwise' must be vertically underneath the 'if' to which "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"it corresponds, at the same indentation, and if the 'otherwise' uses a colon "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"to begin a block then the 'if' must do the same."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">subordinate_to</span><span class="plain-syntax"> == </span><span class="identifier-syntax">switch_CSP</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_MisalignedCase</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this seems to be misplaced since it is not a case within an 'if X is...'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"as it must be. Each case must be placed one tab stop in from the 'if X "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"is...' to which it belongs, and the instructions for what to do in that "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"case should be one tab stop further in still."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_6_3_1">&#167;1.1.6.3.1</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_6_3_1_2" class="paragraph-anchor"></a><b>&#167;1.1.6.3.1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for an intermediate phrase out of sequence</span><span class="named-paragraph-number">1.1.6.3.1.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">indent_misalign</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">suppress_further_problems</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">default_case_CSP</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">case_CSP</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_DefaultCaseNotLast</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'otherwise' must be the last clause if an 'if ... is:'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and in particular it has to come after all the '-- V:' case values supplied."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_MisarrangedOtherwise</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this seems to be misplaced since it is out of sequence within its 'if'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"with an 'otherwise if...' coming after the more general 'otherwise' rather "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"than before. (Note that an 'otherwise' or 'otherwise if' must be vertically "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"underneath the 'if' to which it corresponds, at the same indentation."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_6_3_1">&#167;1.1.6.3.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_7" class="paragraph-anchor"></a><b>&#167;1.1.7. </b>And after all that work, the routine's parse tree still consists only of a
linked list of nodes; but at least it now contains the same pattern of nodes
whichever syntax is used. We finally make a meaningful tree out of it.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(e) Structure the parse tree to match the use of control structures</span><span class="named-paragraph-number">1.1.7</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">routine_list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">top_level</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">CODE_BLOCK_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">top_level</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">attach_owners</span><span class="plain-syntax">[</span><span class="identifier-syntax">MAX_BLOCK_NESTING</span><span class="plain-syntax">+1];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">attach_points</span><span class="plain-syntax">[</span><span class="identifier-syntax">MAX_BLOCK_NESTING</span><span class="plain-syntax">+1];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">attach_csps</span><span class="plain-syntax">[</span><span class="identifier-syntax">MAX_BLOCK_NESTING</span><span class="plain-syntax">+1];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> push the top level code block onto the stack</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">attach_owners</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">attach_csps</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">attach_points</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">top_level</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">overflow_point</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> if any overflow is found</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">routine_list</span><span class="plain-syntax">, *</span><span class="identifier-syntax">pn_prev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">pn</span><span class="plain-syntax">; </span><span class="identifier-syntax">pn_prev</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">pn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> unstring this node from the old list</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pn_prev</span><span class="plain-syntax">) </span><span class="identifier-syntax">pn_prev</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_7_1" class="named-paragraph-link"><span class="named-paragraph">Attach the node to the routine's growing parse tree</span><span class="named-paragraph-number">1.1.7.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">overflow_point</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">overflow_point</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_BlockNestingTooDeep</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"compound phrases have gone too deep"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"perhaps because many have begun but not been properly ended?"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1">&#167;1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_7_1" class="paragraph-anchor"></a><b>&#167;1.1.7.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Attach the node to the routine's growing parse tree</span><span class="named-paragraph-number">1.1.7.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">go_up</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">go_down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_end_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">) </span><span class="identifier-syntax">go_up</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">csp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">go_down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ControlStructures::opens_block</span><span class="plain-syntax">(</span><span class="identifier-syntax">csp</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">go_up</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">CODE_BLOCK_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">go_up</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_7_1_1" class="named-paragraph-link"><span class="named-paragraph">Move the attachment point up in the tree</span><span class="named-paragraph-number">1.1.7.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_7_1_2" class="named-paragraph-link"><span class="named-paragraph">Attach this latest node</span><span class="named-paragraph-number">1.1.7.1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">go_down</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_7_1_3" class="named-paragraph-link"><span class="named-paragraph">Move the attachment point down in the tree</span><span class="named-paragraph-number">1.1.7.1.3</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_7">&#167;1.1.7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_7_1_1" class="paragraph-anchor"></a><b>&#167;1.1.7.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Move the attachment point up in the tree</span><span class="named-paragraph-number">1.1.7.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">superior_csp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">attach_csps</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">-1];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">superior_csp</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">superior_csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">subordinate_to</span><span class="plain-syntax">)) </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_7_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Pop the CSP stack</span><span class="named-paragraph-number">1.1.7.1.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">go_down</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_7_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Pop the CSP stack</span><span class="named-paragraph-number">1.1.7.1.1.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_7_1">&#167;1.1.7.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_7_1_2" class="paragraph-anchor"></a><b>&#167;1.1.7.1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Attach this latest node</span><span class="named-paragraph-number">1.1.7.1.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">attach_points</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">-1];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">go_up</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">go_down</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">attach_owners</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">-1]))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">attach_owners</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">-1];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">SyntaxTree::graft</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="identifier-syntax">to</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_7_1">&#167;1.1.7.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_7_1_3" class="paragraph-anchor"></a><b>&#167;1.1.7.1.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Move the attachment point down in the tree</span><span class="named-paragraph-number">1.1.7.1.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_attach_point</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">go_up</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">CODE_BLOCK_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">next_attach_point</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP1_1_7_1_3_1" class="named-paragraph-link"><span class="named-paragraph">Push the CSP stack</span><span class="named-paragraph-number">1.1.7.1.3.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_7_1">&#167;1.1.7.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_7_1_1_1" class="paragraph-anchor"></a><b>&#167;1.1.7.1.1.1. </b>It's an error to let this underflow, but we'll catch that problem later.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Pop the CSP stack</span><span class="named-paragraph-number">1.1.7.1.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">--;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_7_1_1">&#167;1.1.7.1.1</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_7_1_3_1" class="paragraph-anchor"></a><b>&#167;1.1.7.1.3.1. </b>An overflow, however, we must catch right here.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Push the CSP stack</span><span class="named-paragraph-number">1.1.7.1.3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">MAX_BLOCK_NESTING</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">attach_owners</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">] = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">attach_csps</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">] = </span><span class="identifier-syntax">csp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">attach_points</span><span class="plain-syntax">[</span><span class="identifier-syntax">attach_point_sp</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">next_attach_point</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">overflow_point</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">overflow_point</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1_7_1_3">&#167;1.1.7.1.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_8" class="paragraph-anchor"></a><b>&#167;1.1.8. </b>We now have a neatly structured tree, so from here on anything we do will
need a recursive procedure.
</p>
<p class="commentary">Firstly, the tree is certainly neat, but it can still contain all kinds
of nonsense: "if" blocks with multiple "otherwise"s, for example. This is
where we look for such mistakes.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(f) Police the structure of the parse tree</span><span class="named-paragraph-number">1.1.8</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="identifier-syntax">problem_count</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="2-is.html#SP2" class="function-link"><span class="function-syntax">ImperativeSubtrees::police_code_block</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">n</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Local parse tree: $T\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1">&#167;1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>Which recursively uses the following:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ImperativeSubtrees::police_code_block</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">ImperativeSubtrees::police_code_block</span></span>:<br/><a href="2-is.html#SP1_1_8">&#167;1.1.8</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">block</span><span class="plain-syntax">, </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">context</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">, *</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prior</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax">)?</span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax">):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">control_structure_phrase</span><span class="plain-syntax"> *</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_end_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> != </span><span class="identifier-syntax">prior</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">prior</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP2_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem for end without begin</span><span class="named-paragraph-number">2.1</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP2_2" class="named-paragraph-link"><span class="named-paragraph">Issue problem for wrong sort of end</span><span class="named-paragraph-number">2.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">csp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ControlStructures::opens_block</span><span class="plain-syntax">(</span><span class="identifier-syntax">csp</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_end_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP2_3" class="named-paragraph-link"><span class="named-paragraph">Issue problem for begin without end</span><span class="named-paragraph-number">2.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">context</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP2_4" class="named-paragraph-link"><span class="named-paragraph">Choose a problem for a loose clause</span><span class="named-paragraph-number">2.4</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">context</span><span class="plain-syntax"> != </span><span class="identifier-syntax">csp</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">subordinate_to</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP2_5" class="named-paragraph-link"><span class="named-paragraph">Choose a problem for the wrong clause</span><span class="named-paragraph-number">2.5</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">otherwise_CSP</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP2_6" class="named-paragraph-link"><span class="named-paragraph">Choose a problem for otherwise not occurring last</span><span class="named-paragraph-number">2.6</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">default_case_CSP</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP2_7" class="named-paragraph-link"><span class="named-paragraph">Issue a problem for the default case not occurring last</span><span class="named-paragraph-number">2.7</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">) </span><a href="2-is.html#SP2" class="function-link"><span class="function-syntax">ImperativeSubtrees::police_code_block</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">csp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2_1" class="paragraph-anchor"></a><b>&#167;2.1. </b>These used to be much-seen problem messages, until Inform moved to Pythonesque
structure-by-indentation. Nowadays "end if", "end while" and such are
automatically inserted into the stream of commands, always in the right place,
and always passing these checks. But the problem messages are kept for the sake
of old-format source text, and for refuseniks.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for end without begin</span><span class="named-paragraph-number">2.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem_with_note</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EndWithoutBegin</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this is an 'end' with no matching 'begin'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which should not happen: every phrase like 'if ... begin;' should eventually be "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"followed by its bookend 'end if'. It makes no sense to have an 'end ...' on its "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"own."</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Perhaps the problem is actually that you opened several such begin... end "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'blocks' and accidentally closed them once too many? This is very easily done."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP2">&#167;2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2" class="paragraph-anchor"></a><b>&#167;2.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for wrong sort of end</span><span class="named-paragraph-number">2.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wide_text</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">prior</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">keyword</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_WrongEnd</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"You wrote %1, but the end I was expecting next was 'end %2', "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"finishing the block you began with %3."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP2">&#167;2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_3" class="paragraph-anchor"></a><b>&#167;2.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for begin without end</span><span class="named-paragraph-number">2.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_BeginWithoutEnd</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the definition of the phrase ended with no matching 'end' for this 'begin'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"bearing in mind that every begin must have a matching end, and that the one "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"most recently begun must be the one first to end. For instance, 'if ... begin' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"must have a matching 'end if'."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP2">&#167;2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_4" class="paragraph-anchor"></a><b>&#167;2.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Choose a problem for a loose clause</span><span class="named-paragraph-number">2.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">otherwise_CSP</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_OtherwiseWithoutIf</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this is an 'else' or 'otherwise' with no matching 'if' (or 'unless')"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which must be wrong."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">otherwise_if_CSP</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_OtherwiseIfMisplaced</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the 'otherwise if' clause here seems not to be occurring inside a large 'if'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and seems to be freestanding instead. (Though 'otherwise ...' can usually "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"be used after simple one-line 'if's to provide an alternative course of action, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'otherwise if...' is a different matter, and is used to divide up larger-scale "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"instructions.)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">BelievedImpossible</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this clause can't occur outside of a control phrase"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which suggests that the structure of this routine is wrong."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP2">&#167;2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_5" class="paragraph-anchor"></a><b>&#167;2.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Choose a problem for the wrong clause</span><span class="named-paragraph-number">2.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">otherwise_CSP</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">csp</span><span class="plain-syntax"> == </span><span class="identifier-syntax">otherwise_if_CSP</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wide_text</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">context</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">keyword</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_OtherwiseInNonIf</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"The %1 here did not make sense inside a '%2' structure: it's provided for 'if' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"(or 'unless')."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">BelievedImpossible</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this clause is wrong for the phrase containing it"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which suggests that the structure of this routine is wrong."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP2">&#167;2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_6" class="paragraph-anchor"></a><b>&#167;2.6. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Choose a problem for otherwise not occurring last</span><span class="named-paragraph-number">2.6</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">doubled</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">oi</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">; </span><span class="identifier-syntax">p2</span><span class="plain-syntax">; </span><span class="identifier-syntax">p2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p2</span><span class="plain-syntax">) == </span><span class="identifier-syntax">otherwise_CSP</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">doubled</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p2</span><span class="plain-syntax">) == </span><span class="identifier-syntax">otherwise_if_CSP</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">oi</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">doubled</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_DoubleOtherwise</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"that makes two unconditional 'otherwise' or 'else' clauses for this 'if'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which is forbidden since 'otherwise' is meant to be a single (optional) "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"catch-all clause at the end."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">oi</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_OtherwiseIfAfterOtherwise</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this seems to be misplaced since it is out of sequence within its 'if'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"with an 'otherwise if...' coming after the more general 'otherwise' rather "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"than before. (If there's an 'otherwise' clause, it has to be the last clause "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"of the 'if'.)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">BelievedImpossible</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'otherwise' must be the last clause"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"but it seems not to be."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP2">&#167;2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_7" class="paragraph-anchor"></a><b>&#167;2.7. </b>This shouldn't happen because the switch construct requires Python syntax
and the structure of that was checked at indentation time, but just in case.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem for the default case not occurring last</span><span class="named-paragraph-number">2.7</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">BelievedImpossible</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'otherwise' must be the last clause"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which must be wrong."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP2">&#167;2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_9" class="paragraph-anchor"></a><b>&#167;1.1.9. </b>The tree is now known to be correctly structured, and there are no possible
problem messages left to issue. It's therefore safe to begin rearranging it.
We'll first eliminate one whole construction: "otherwise if whatever: ..."
can now become "otherwise: if whatever: ...".
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(g) Optimise out the otherwise if nodes</span><span class="named-paragraph-number">1.1.9</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="identifier-syntax">problem_count</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="2-is.html#SP1_1_10" class="function-link"><span class="function-syntax">ImperativeSubtrees::purge_otherwise_if</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">n</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Local parse tree: $T\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1">&#167;1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_10" class="paragraph-anchor"></a><b>&#167;1.1.10. </b>We made a similar manoeuvre above, but for one-line "otherwise do something"
phrases following one-line "if", not for the wider case of "otherwise if". We
didn't handle this back then because to do so would have made it impossible
to issue good problem messages for failures to use "otherwise if" correctly.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ImperativeSubtrees::purge_otherwise_if</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">ImperativeSubtrees::purge_otherwise_if</span></span>:<br/><a href="2-is.html#SP1_1_9">&#167;1.1.9</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">block</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">, *</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">) == </span><span class="identifier-syntax">otherwise_if_CSP</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">former_contents</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">former_successors</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> put an otherwise node in the position previously occupied by p</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">CODE_BLOCK_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">otherwise_CSP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> extract just the word "otherwise"</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::one_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">))));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax">) </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> move p to below the otherwise node</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">otherwise_node</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">InvocationLists::make_into_list_node</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">if_CSP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wordings::trim_first_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)));</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> put the code previously under p under a new code block node under p</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">CODE_BLOCK_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">former_contents</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> any further "otherwise if" or "otherwise" nodes after p follow</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">former_successors</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">) </span><a href="2-is.html#SP1_1_10" class="function-link"><span class="function-syntax">ImperativeSubtrees::purge_otherwise_if</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP1_1_11" class="paragraph-anchor"></a><b>&#167;1.1.11. </b>End nodes are now redundant: maybe they got here as explicit "end if" phrases
in the source text, or maybe they were auto-inserted by the indentation reader,
but now that the structure is known to be correct they serve no further purpose.
We remove them.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(h) Remove any end markers as no longer necessary</span><span class="named-paragraph-number">1.1.11</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="2-is.html#SP1_1_12" class="function-link"><span class="function-syntax">ImperativeSubtrees::purge_end_markers</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1">&#167;1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_12" class="paragraph-anchor"></a><b>&#167;1.1.12. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ImperativeSubtrees::purge_end_markers</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">ImperativeSubtrees::purge_end_markers</span></span>:<br/><a href="2-is.html#SP1_1_11">&#167;1.1.11</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">block</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">, *</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_end_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax">) </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">) </span><a href="2-is.html#SP1_1_12" class="function-link"><span class="function-syntax">ImperativeSubtrees::purge_end_markers</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP1_1_13" class="paragraph-anchor"></a><b>&#167;1.1.13. </b>The "begin" keyword at the end of control constructs in the old-style syntax
can now be removed, too.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(i) Remove any begin markers as no longer necessary</span><span class="named-paragraph-number">1.1.13</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="2-is.html#SP1_1_14" class="function-link"><span class="function-syntax">ImperativeSubtrees::purge_begin_markers</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1">&#167;1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_14" class="paragraph-anchor"></a><b>&#167;1.1.14. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ImperativeSubtrees::purge_begin_markers</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">ImperativeSubtrees::purge_begin_markers</span></span>:<br/><a href="2-is.html#SP1_1_13">&#167;1.1.13</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">block</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">, *</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;phrase-beginning-block&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;phrase-beginning-block&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">) </span><a href="2-is.html#SP1_1_14" class="function-link"><span class="function-syntax">ImperativeSubtrees::purge_begin_markers</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP1_1_15" class="paragraph-anchor"></a><b>&#167;1.1.15. </b>This all makes a nice tree, but it has the defect that the statements heading
block-opening phrases (the ifs, whiles, repeats) have child nodes (the blocks
of code consequent on them). We want them to be leaves for now, so that we
can append statement-parsing data underneath them later. So we insert blank
code block nodes to mark these phrases, and transfer the control structure
annotations to them.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(j) Insert code block nodes so that nodes needing to be parsed are childless</span><span class="named-paragraph-number">1.1.15</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="2-is.html#SP1_1_16" class="function-link"><span class="function-syntax">ImperativeSubtrees::insert_cb_nodes</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1">&#167;1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_16" class="paragraph-anchor"></a><b>&#167;1.1.16. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ImperativeSubtrees::insert_cb_nodes</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">ImperativeSubtrees::insert_cb_nodes</span></span>:<br/><a href="2-is.html#SP1_1_15">&#167;1.1.15</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">block</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">, *</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ControlStructures::opens_block</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">CODE_BLOCK_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax">) </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">) </span><a href="2-is.html#SP1_1_16" class="function-link"><span class="function-syntax">ImperativeSubtrees::insert_cb_nodes</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP1_1_17" class="paragraph-anchor"></a><b>&#167;1.1.17. </b>Now:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(k) Insert instead marker nodes</span><span class="named-paragraph-number">1.1.17</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="2-is.html#SP1_1_18" class="function-link"><span class="function-syntax">ImperativeSubtrees::read_instead_markers</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1">&#167;1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_1_18" class="paragraph-anchor"></a><b>&#167;1.1.18. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ImperativeSubtrees::read_instead_markers</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">ImperativeSubtrees::read_instead_markers</span></span>:<br/><a href="2-is.html#SP1_1_17">&#167;1.1.17</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">block</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">, *</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;instead-keyword&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;instead-keyword&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">instead_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">CODE_BLOCK_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">instead_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">instead_CSP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">instead_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">instead_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">) </span><a href="2-is.html#SP1_1_18" class="function-link"><span class="function-syntax">ImperativeSubtrees::read_instead_markers</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP1_1_19" class="paragraph-anchor"></a><b>&#167;1.1.19. </b>Now:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(l) Break up say phrases</span><span class="named-paragraph-number">1.1.19</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="2-is.html#SP3" class="function-link"><span class="function-syntax">ImperativeSubtrees::break_up_says</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">imperative_node</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP1_1">&#167;1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ImperativeSubtrees::break_up_says</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">ImperativeSubtrees::break_up_says</span></span>:<br/><a href="2-is.html#SP1_1_19">&#167;1.1.19</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">block</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">, *</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">sf</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NO_SIGF</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">from_text_substitution_ANNOT</span><span class="plain-syntax">)) </span><span class="identifier-syntax">sf</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SAY_SIGF</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;other-significant-phrase&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sf</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;r&gt;&gt;</span><span class="plain-syntax">; </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;other-significant-phrase&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sf</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SAY_SIGF:</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">CODE_BLOCK_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">say_CSP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">prev_p</span><span class="plain-syntax">) </span><span class="identifier-syntax">prev_p</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">block</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="2-is.html#SP3" class="function-link"><span class="function-syntax">ImperativeSubtrees::unroll_says</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">blank_cb_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NOW_SIGF:</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">now_CSP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cond_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">CONDITION_CONTEXT_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">cond_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cond_node</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">) </span><a href="2-is.html#SP3" class="function-link"><span class="function-syntax">ImperativeSubtrees::break_up_says</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ImperativeSubtrees::unroll_says</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">ImperativeSubtrees::unroll_says</span></span>:<br/><a href="2-is.html#SP3_1">&#167;3.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cb_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;phrase-with-comma-notation&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">AW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;phrase-with-comma-notation&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">BW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;phrase-with-comma-notation&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AW</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP3_1" class="named-paragraph-link"><span class="named-paragraph">Bite off a say term</span><span class="named-paragraph-number">3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">BW</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP3_1" class="named-paragraph-link"><span class="named-paragraph">Bite off a say term</span><span class="named-paragraph-number">3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3_1" class="paragraph-anchor"></a><b>&#167;3.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Bite off a say term</span><span class="named-paragraph-number">3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Wordings::length</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Wide::cmp</span><span class="plain-syntax">(</span><span class="identifier-syntax">Lexer::word_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)), </span><span class="identifier-syntax">L</span><span class="string-syntax">"\"\""</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Wordings::length</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">) == </span><span class="constant-syntax">1</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Vocabulary::test_flags</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">), </span><span class="identifier-syntax">TEXTWITHSUBS_MC</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">depth</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexer::word_raw_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP3_1_1" class="named-paragraph-link"><span class="named-paragraph">Check that substitution does not contain suspicious punctuation</span><span class="named-paragraph-number">3.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP3_1_2" class="named-paragraph-link"><span class="named-paragraph">Write a form of the text bracketing substitutions with commas</span><span class="named-paragraph-number">3.1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">A</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Feeds::feed_text_expanding_strings</span><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;verify-expanded-text-substitution&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">A</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="2-is.html#SP3" class="function-link"><span class="function-syntax">ImperativeSubtrees::unroll_says</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cb_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">A</span><span class="plain-syntax">, </span><span class="identifier-syntax">depth</span><span class="plain-syntax">+1);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">say_term_node</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">INVOCATION_LIST_SAY_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">say_term_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">SyntaxTree::graft</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">say_term_node</span><span class="plain-syntax">, </span><span class="identifier-syntax">cb_node</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP3">&#167;3</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP3_1_1" class="paragraph-anchor"></a><b>&#167;3.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check that substitution does not contain suspicious punctuation</span><span class="named-paragraph-number">3.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">sqb</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">]; </span><span class="identifier-syntax">k</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">]) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'['</span><span class="plain-syntax">: </span><span class="identifier-syntax">sqb</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sqb</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP3_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem message for nested substitution</span><span class="named-paragraph-number">3.1.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">']'</span><span class="plain-syntax">: </span><span class="identifier-syntax">sqb</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sqb</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP3_1_1_3" class="named-paragraph-link"><span class="named-paragraph">Issue problem message for unopened substitution</span><span class="named-paragraph-number">3.1.1.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">':'</span><span class="plain-syntax">:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">k</span><span class="plain-syntax">&gt;0) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Characters::isdigit</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">-1])) &amp;&amp; (</span><span class="identifier-syntax">Characters::isdigit</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+1]))) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sqb</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP3_1_1_5" class="named-paragraph-link"><span class="named-paragraph">Issue PM_TSWithPunctuation problem</span><span class="named-paragraph-number">3.1.1.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">';'</span><span class="plain-syntax">:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sqb</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP3_1_1_5" class="named-paragraph-link"><span class="named-paragraph">Issue PM_TSWithPunctuation problem</span><span class="named-paragraph-number">3.1.1.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sqb</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP3_1_1_2" class="named-paragraph-link"><span class="named-paragraph">Issue problem message for unclosed substitution</span><span class="named-paragraph-number">3.1.1.2</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP3_1">&#167;3.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_1_2" class="paragraph-anchor"></a><b>&#167;3.1.2. </b>A long-standing annoyance in Inform syntax was that commas were not allowed
inside text substitutions: <span class="extract"><span class="extract-syntax">"Like [this, that]."</span></span> The reason for this was that
such a text converts to the say phrase <span class="extract"><span class="extract-syntax">say "Like ", this, that, "."</span></span>; so that
what was intended as a single expression with a comma in <span class="extract"><span class="extract-syntax">this, that</span></span> came out
as two, <span class="extract"><span class="extract-syntax">this</span></span> then <span class="extract"><span class="extract-syntax">that</span></span>. This arose seldom, but meant that phrases using
phrase options, which unhappily include a comma in their syntax, could not
easily be used in substitutions.
</p>
<p class="commentary">The text now converts to <span class="extract"><span class="extract-syntax">say "Like ", (this, that), "."</span></span>, so that a single
bracketed expression <span class="extract"><span class="extract-syntax">(this, that)</span></span> appears. Thus, round brackets are put
around the contents of any substitution which contains a comma.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Write a form of the text bracketing substitutions with commas</span><span class="named-paragraph-number">3.1.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax">=0, </span><span class="identifier-syntax">in_ts_with_commas</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">]; </span><span class="identifier-syntax">k</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">] == </span><span class="character-syntax">'['</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">=</span><span class="identifier-syntax">k</span><span class="plain-syntax">+1; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">]) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] != </span><span class="character-syntax">']'</span><span class="plain-syntax">); </span><span class="identifier-syntax">j</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] == </span><span class="character-syntax">','</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">in_ts_with_commas</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">] == </span><span class="character-syntax">']'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">in_ts_with_commas</span><span class="plain-syntax">)) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="character-syntax">')'</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">] == </span><span class="character-syntax">'['</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">in_ts_with_commas</span><span class="plain-syntax">)) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="character-syntax">'('</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">] == </span><span class="character-syntax">']'</span><span class="plain-syntax">) </span><span class="identifier-syntax">in_ts_with_commas</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP3_1">&#167;3.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_1_1_1" class="paragraph-anchor"></a><b>&#167;3.1.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem message for nested substitution</span><span class="named-paragraph-number">3.1.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">TextSubstitutions::it_is_not_worth_adding</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+1] == </span><span class="character-syntax">'u'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+2] == </span><span class="character-syntax">'n'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+3] == </span><span class="character-syntax">'i'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+4] == </span><span class="character-syntax">'c'</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+5] == </span><span class="character-syntax">'o'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+6] == </span><span class="character-syntax">'d'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+7] == </span><span class="character-syntax">'e'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">+8] == </span><span class="character-syntax">' '</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_NestedUSubstitution</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the text here contains one substitution '[...]' inside another"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which is not allowed. Actually, it looks as if you might have got into this "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"by typing an exotic character as part of the name of a text substitution - "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"those get rewritten automatically as '[unicode N]' for the appropriate Unicode "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"character code number N. Either way - this isn't allowed."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_NestedSubstitution</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the text here contains one substitution '[...]' inside another"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which is not allowed. (If you just wanted a literal open and closed square "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"bracket, use '[bracket]' and '[close bracket]'.)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TextSubstitutions::it_is_worth_adding</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP3_1_1">&#167;3.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_1_1_2" class="paragraph-anchor"></a><b>&#167;3.1.1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem message for unclosed substitution</span><span class="named-paragraph-number">3.1.1.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">TextSubstitutions::it_is_not_worth_adding</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_UnclosedSubstitution</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the text here uses an open square bracket '[', which opens a substitution "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"in the text, but doesn't close it again"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"so that the result is malformed. (If you just wanted a literal open square "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"bracket, use '[bracket]'.)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TextSubstitutions::it_is_worth_adding</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP3_1_1">&#167;3.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_1_1_3" class="paragraph-anchor"></a><b>&#167;3.1.1.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem message for unopened substitution</span><span class="named-paragraph-number">3.1.1.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">TextSubstitutions::it_is_not_worth_adding</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_UnopenedSubstitution</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the text here uses a close square bracket ']', which closes a substitution in the "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"text, but never actually opened it"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"with a matching '['. (If you just wanted a literal close square bracket, use "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'[close bracket]'.)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TextSubstitutions::it_is_worth_adding</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP3_1_1">&#167;3.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_1_1_4" class="paragraph-anchor"></a><b>&#167;3.1.1.4. </b>Something devious happens when text following a "say" is found. Double-quoted text
is literal if it contains no square brackets, but is expanded if it includes text
substitutions in squares. Thus:
</p>
<blockquote>
<p>"Look, [the noun] said."</p>
</blockquote>
<p class="commentary">becomes:
</p>
<blockquote>
<p>"Look, ", the noun, " said."</p>
</blockquote>
<p class="commentary">This is then re-parsed with the following nonterminal; note that we report any
problem with misuse of commas &mdash; really, of square brackets &mdash; before handing back
to &lt;s-say-phrase&gt; to parse the list.
</p>
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;verify-expanded-text-substitution&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">***</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">.</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">***</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP3_1_1_5" class="named-paragraph-link"><span class="named-paragraph">Issue PM_TSWithPunctuation problem</span><span class="named-paragraph-number">3.1.1.5</span></a></span><span class="Preform-constant-syntax">;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> { fail };</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">,</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">***</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP3_1_1_4_1" class="named-paragraph-link"><span class="named-paragraph">Issue PM_EmptySubstitution problem</span><span class="named-paragraph-number">3.1.1.4.1</span></a></span><span class="Preform-constant-syntax">;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> { fail };</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">***</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">,</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP3_1_1_4_1" class="named-paragraph-link"><span class="named-paragraph">Issue PM_EmptySubstitution problem</span><span class="named-paragraph-number">3.1.1.4.1</span></a></span><span class="Preform-constant-syntax">;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> { fail };</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">***</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">,</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">,</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">***</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-is.html#SP3_1_1_4_1" class="named-paragraph-link"><span class="named-paragraph">Issue PM_EmptySubstitution problem</span><span class="named-paragraph-number">3.1.1.4.1</span></a></span><span class="Preform-constant-syntax">;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> { fail };</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> { -, - }</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_1_1_5" class="paragraph-anchor"></a><b>&#167;3.1.1.5. </b>So now just the problem messages:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_TSWithPunctuation problem</span><span class="named-paragraph-number">3.1.1.5</span></span><span class="Preform-comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">TextSubstitutions::it_is_not_worth_adding</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_TSWithPunctuation</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"a substitution contains a '.', ':' or ';'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which suggests that a close square bracket ']' may have gone astray."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TextSubstitutions::it_is_worth_adding</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP3_1_1">&#167;3.1.1</a> (twice), <a href="2-is.html#SP3_1_1_4">&#167;3.1.1.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3_1_1_4_1" class="paragraph-anchor"></a><b>&#167;3.1.1.4.1. </b>And:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_EmptySubstitution problem</span><span class="named-paragraph-number">3.1.1.4.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">TextSubstitutions::it_is_not_worth_adding</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_EmptySubstitution</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the text here contains an empty substitution '[]'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which is not allowed. To say nothing - well, say nothing."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TextSubstitutions::it_is_worth_adding</span><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-is.html#SP3_1_1_4">&#167;3.1.1.4</a> (three times).</li></ul>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>The following manufactures end nodes to match a given begin node.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">ImperativeSubtrees::end_node</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">ImperativeSubtrees::end_node</span></span>:<br/><a href="2-is.html#SP1_1_5_1">&#167;1.1.5.1</a>, <a href="2-is.html#SP1_1_6_5_1">&#167;1.1.6.5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">opening</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">implicit_end</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InvocationLists::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_end_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">implicit_end</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::get_control_structure_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">opening</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::write_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">implicit_end</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation_level_ANNOT</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Annotations::read_int</span><span class="plain-syntax">(</span><span class="identifier-syntax">opening</span><span class="plain-syntax">, </span><span class="identifier-syntax">indentation_level_ANNOT</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">implicit_end</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="2-ps.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-am.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresssection"><a href="2-bv.html">bv</a></li><li class="progresssection"><a href="2-ptmn.html">ptmn</a></li><li class="progresssection"><a href="2-ar.html">ar</a></li><li class="progresssection"><a href="2-cs.html">cs</a></li><li class="progresssection"><a href="2-ps.html">ps</a></li><li class="progresscurrent">is</li><li class="progresschapter"><a href="3-dlr.html">3</a></li><li class="progresschapter"><a href="4-nr.html">4</a></li><li class="progresschapter"><a href="5-id.html">5</a></li><li class="progresschapter"><a href="6-rls.html">6</a></li><li class="progresschapter"><a href="7-tc.html">7</a></li><li class="progresschapter"><a href="8-kpr.html">8</a></li><li class="progressnext"><a href="3-dlr.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>