1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-03 07:24:58 +03:00
inform7/docs/values-module/5-dsh.html
2021-11-15 22:44:29 +00:00

4395 lines
775 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Dash</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">
<script>
MathJax = {
tex: {
inlineMath: '$', '$'], ['\\(', '\\)'
},
svg: {
fontCache: 'global'
}
};
</script>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>
<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="../compiler.html">compiler tools</a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul><h2>Compiler Webs</h2><ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
</ul><h2>Inbuild Modules</h2><ul>
<li><a href="../supervisor-module/index.html">supervisor</a></li>
</ul><h2>Inform7 Modules</h2><ul>
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../assertions-module/index.html">assertions</a></li>
<li><a href="index.html"><span class="selectedlink">values</span></a></li>
<li><a href="../knowledge-module/index.html">knowledge</a></li>
<li><a href="../imperative-module/index.html">imperative</a></li>
<li><a href="../runtime-module/index.html">runtime</a></li>
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="../index-module/index.html">index</a></li>
</ul><h2>Inter Modules</h2><ul>
<li><a href="../bytecode-module/index.html">bytecode</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../pipeline-module/index.html">pipeline</a></li>
<li><a href="../final-module/index.html">final</a></li>
</ul><h2>Services</h2><ul>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../calculus-module/index.html">calculus</a></li>
<li><a href="../html-module/index.html">html</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Dash' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7</a></li><li><a href="index.html">values</a></li><li><a href="index.html#5">Chapter 5: Type Checking</a></li><li><b>Dash</b></li></ul></div>
<p class="purpose">The part of Inform most nearly like a typechecker in a conventional compiler.</p>
<ul class="toc"><li><a href="5-dsh.html#SP3">&#167;3. The Dashboard</a></li><li><a href="5-dsh.html#SP7">&#167;7. Return values</a></li><li><a href="5-dsh.html#SP8">&#167;8. (1) Entering Dash</a></li><li><a href="5-dsh.html#SP9">&#167;9. (2) Recursion point</a></li><li><a href="5-dsh.html#SP10">&#167;10. (3) Context switching</a></li><li><a href="5-dsh.html#SP10_8">&#167;10.8. New variables</a></li><li><a href="5-dsh.html#SP10_9">&#167;10.9. (4) Typechecking within current context</a></li><li><a href="5-dsh.html#SP10_9_1_2">&#167;10.9.1.2. (4S) Verifying single non-invocation readings</a></li><li><a href="5-dsh.html#SP12">&#167;12. Arithmetic operands</a></li><li><a href="5-dsh.html#SP13">&#167;13. Local variable markers</a></li><li><a href="5-dsh.html#SP14">&#167;14. Problems, problems, problems</a></li><li><a href="5-dsh.html#SP18">&#167;18. (5) Single nodes</a></li><li><a href="5-dsh.html#SP18_2">&#167;18.2. Rule (5.a)</a></li><li><a href="5-dsh.html#SP18_3">&#167;18.3. Rule (5.b)</a></li><li><a href="5-dsh.html#SP18_4">&#167;18.4. Rule (5.c)</a></li><li><a href="5-dsh.html#SP18_5">&#167;18.5. Rule (5.d)</a></li><li><a href="5-dsh.html#SP18_6">&#167;18.6. Rule (5.e)</a></li><li><a href="5-dsh.html#SP21">&#167;21. Ambiguity testing flags</a></li><li><a href="5-dsh.html#SP26">&#167;26. Value checking</a></li><li><a href="5-dsh.html#SP27">&#167;27. Ambiguous alternatives</a></li><li><a href="5-dsh.html#SP28">&#167;28. Internal testing</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>Dash is the second typechecking algorithm to be used in Inform, installed in
early 2015: the first had served since 2003, but became unwieldy after so many
exceptional cases had been added to it, and was impossible to adapt to the
redesigned parse tree. Dash is not so called because it's faster (it's
actually a few percent slower), but because at one stage Inform was running
both typecheckers side by side: TC and TC-dash, or Dash for short. TC-dash
won, it's still called Dash, and TC is no more.
</p>
<p class="commentary">Because Dash also deals with text which entirely fails to make sense, which in
other compilers would be rejected at a lower level, it has to issue basic
syntax errors as well as type mismatch errors. This is arguably a good thing,
though, because it means they can be issued using the same generally helpful
system as more sophisticated problems.
</p>
<p class="commentary">Partly because of the need to do this, the type-checker has a top-down
approach. It aims to prove that the node found can match what's expected,
making selections from alternative readings, and in limited cases actually
making changes to the parse tree, in order to do this. For instance,
consider checking the tree for:
</p>
<blockquote>
<p>let the score be the score plus 10</p>
</blockquote>
<p class="commentary">Dash takes the view that the phrase usage can be proved correct, so long as
the arguments can also be proved. There are several valid interpretations of
"let ... be ...", and these are all present in the parse tree as alternative
interpretations, so the typechecker tries each in turn, accepting one (or
more) if the arguments can be proved to be of the right type. This means
proving that argument 0 ("the score") is an lvalue and also that argument 1
("the score plus 10") is an rvalue. A further rule requires that the kind of
value of argument 1 must match the kind of value stored in the variable, here
a "number", so we must prove that too. Now "plus" is polymorphic and can
produce different kinds of value depending on the kinds of value it acts upon,
so again we must check all possible interpretations. But we finally succeed in
showing that "score" is an lvalue, "10" is a number, "score" is also a number,
and that "plus" on two numbers gives a number, so we complete the proof and
the phrase is proved correct.
</p>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>When issuing problems, we show a form of backtrace so that the user can
see what we've considered, and this is used to accumulate data for that.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">inv_token_problem_token</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">problematic_text</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">as_parsed</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">already_described</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">new_name</span><span class="plain-syntax">; </span><span class="comment-syntax"> found in context of a name not yet defined</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">inv_token_problem_token</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure inv_token_problem_token is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. The Dashboard. </b>Dash uses a small suite of global variables to keep track of two decidedly
global side-effects of checking: the issuing of problem messages, and the
setting of kind variables. This suite is called the "dashboard".
</p>
<p class="commentary">First, we keep track of the problem messages we will issue, if any, using
a bitmap made up of the following modes:
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">BEGIN_DASH_MODE</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">s_dm</span><span class="plain-syntax"> = </span><span class="identifier-syntax">dash_mode</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> **</span><span class="identifier-syntax">s_kvc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">kind_of_var_to_create</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">s_invl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Dash_ambiguity_list</span><span class="plain-syntax">;</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">DASH_MODE_ENTER</span><span class="plain-syntax">(</span><span class="identifier-syntax">mode</span><span class="plain-syntax">) </span><span class="identifier-syntax">dash_mode</span><span class="plain-syntax"> |= </span><span class="identifier-syntax">mode</span><span class="plain-syntax">;</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">DASH_MODE_CREATE</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">) </span><span class="identifier-syntax">kind_of_var_to_create</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K</span><span class="plain-syntax">;</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">DASH_MODE_EXIT</span><span class="plain-syntax">(</span><span class="identifier-syntax">mode</span><span class="plain-syntax">) </span><span class="identifier-syntax">dash_mode</span><span class="plain-syntax"> &amp;= (~</span><span class="identifier-syntax">mode</span><span class="plain-syntax">);</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">END_DASH_MODE</span><span class="plain-syntax"> </span><span class="identifier-syntax">dash_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">s_dm</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind_of_var_to_create</span><span class="plain-syntax"> = </span><span class="identifier-syntax">s_kvc</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Dash_ambiguity_list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">s_invl</span><span class="plain-syntax">;</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">TEST_DASH_MODE</span><span class="plain-syntax">(</span><span class="identifier-syntax">mode</span><span class="plain-syntax">) (</span><span class="identifier-syntax">dash_mode</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">mode</span><span class="plain-syntax">)</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">ISSUE_PROBLEMS_DMODE</span><span class="plain-syntax"> </span><span class="constant-syntax">0x00000001</span><span class="plain-syntax"> </span><span class="comment-syntax"> rather than keep silent about them</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">ISSUE_LOCAL_PROBLEMS_DMODE</span><span class="plain-syntax"> </span><span class="constant-syntax">0x00000002</span><span class="plain-syntax"> </span><span class="comment-syntax"> at the end, that is</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">ISSUE_GROSS_PROBLEMS_DMODE</span><span class="plain-syntax"> </span><span class="constant-syntax">0x00000004</span><span class="plain-syntax"> </span><span class="comment-syntax"> at the end, that is</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">ISSUE_INTERESTING_PROBLEMS_DMODE</span><span class="plain-syntax"> </span><span class="constant-syntax">0x00000008</span><span class="plain-syntax"> </span><span class="comment-syntax"> unless casting to text</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">ABSOLUTE_SILENCE_DMODE</span><span class="plain-syntax"> </span><span class="constant-syntax">0x00000010</span><span class="plain-syntax"> </span><span class="comment-syntax"> say nothing at all</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">dash_mode</span><span class="plain-syntax"> = </span><span class="constant-syntax">ISSUE_PROBLEMS_DMODE</span><span class="plain-syntax">; </span><span class="comment-syntax"> default</span>
<span class="identifier-syntax">kind</span><span class="plain-syntax"> **</span><span class="identifier-syntax">kind_of_var_to_create</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">dash_recursion_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>Three grades of problem can appear: "ordinary", "gross" and "grosser than
gross". We distinguish these in order to produce a Problem message which
reflects the biggest thing wrong, rather than being so esoteric that it misses
the main point. Changing a particular error condition from an ordinary to a
gross problem, or vice versa, has no effect on the result returned by Dash,
only on the Problem messages given to the user.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">no_gross_problems_thrown</span><span class="plain-syntax">++; </span><span class="comment-syntax"> problems this gross cannot be suppressed</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">THIS_IS_A_GROSS_PROBLEM</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">no_gross_problems_thrown</span><span class="plain-syntax">++; </span><span class="comment-syntax"> this increments even if the message is suppressed</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">TEST_DASH_MODE</span><span class="plain-syntax">(</span><span class="constant-syntax">ISSUE_PROBLEMS_DMODE</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">TEST_DASH_MODE</span><span class="plain-syntax">(</span><span class="constant-syntax">ISSUE_GROSS_PROBLEMS_DMODE</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TEST_DASH_MODE</span><span class="plain-syntax">(</span><span class="constant-syntax">ISSUE_PROBLEMS_DMODE</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_gross_problems_thrown</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_interesting_problems_thrown</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><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="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">backtraced_problem_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::problems_have_been_issued</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">Dash::problems_have_been_issued</span></span>:<br/><a href="5-dsh.html#SP10_9_2">&#167;10.9.2</a>, <a href="5-dsh.html#SP10_9_2_2">&#167;10.9.2.2</a>, <a href="5-dsh.html#SP10_9_1_1_3_1">&#167;10.9.1.1.3.1</a>, <a href="5-dsh.html#SP10_9_1_1_4">&#167;10.9.1.1.4</a>, <a href="5-dsh.html#SP14">&#167;14</a></span></button><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">initial_problem_count</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">problem_count</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>Next, we keep track of the most recent set of meanings attached to the
kind variables A, B, C, ..., Z, and the most recently looked-at list of
invocations.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">kind_variable_declaration</span><span class="plain-syntax"> *</span><span class="identifier-syntax">most_recent_interpretation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Dash_ambiguity_list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>We need careful debug logging of what Dash does. During Inform's infancy, the
type checker was the hardest thing to debug, but that wasn't so much because
this was the great habitat and breeding ground for bugs; it was more that those
bugs which were here were by far the hardest to root out. So careful logging
on demand is vital.
</p>
<p class="commentary">Each call to the recursive Dash has its own unique ID number, to make logging
more legible.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">LOG_DASH_LEFT</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"[%d%s] "</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">unique_DR_call_identifier</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">TEST_DASH_MODE</span><span class="plain-syntax">(</span><span class="constant-syntax">ISSUE_PROBLEMS_DMODE</span><span class="plain-syntax">))?</span><span class="string-syntax">""</span><span class="plain-syntax">:</span><span class="string-syntax">"-silent"</span><span class="plain-syntax">);</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="identifier-syntax">stage</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"[%d%s] %s $P\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">unique_DR_call_identifier</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">TEST_DASH_MODE</span><span class="plain-syntax">(</span><span class="constant-syntax">ISSUE_PROBLEMS_DMODE</span><span class="plain-syntax">))?</span><span class="string-syntax">""</span><span class="plain-syntax">:</span><span class="string-syntax">"-silent"</span><span class="plain-syntax">, </span><span class="identifier-syntax">stage</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">unique_DR_call_identifier</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">DR_call_counter</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> solely to make the log more legible</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. Return values. </b>Dash records the outcome of checking as one of three states.
</p>
<p class="commentary">It is perhaps telling that we never need a <span class="extract"><span class="extract-syntax">Dash::best_case</span></span> routine.
Typecheckers are not allowed to be optimistic.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::worst_case</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">Dash::worst_case</span></span>:<br/><a href="5-dsh.html#SP10_5">&#167;10.5</a>, <a href="5-dsh.html#SP10_6">&#167;10.6</a>, <a href="5-dsh.html#SP10_9_2_2_1">&#167;10.9.2.2.1</a>, <a href="5-dsh.html#SP10_9_1_1">&#167;10.9.1.1</a>, <a href="5-dsh.html#SP10_9_1_1_4">&#167;10.9.1.1.4</a>, <a href="5-dsh.html#SP10_9_1_1_6">&#167;10.9.1.1.6</a>, <a href="5-dsh.html#SP10_9_1_2">&#167;10.9.1.2</a>, <a href="5-dsh.html#SP26">&#167;26</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv2</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">rv1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">rv2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEVER_MATCH</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">rv1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">SOMETIMES_MATCH</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">rv2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">SOMETIMES_MATCH</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">SOMETIMES_MATCH</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">ALWAYS_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. (1) Entering Dash. </b>Dash is structured into levels and this is level 1, the topmost.
</p>
<p class="commentary">Dash has three points of entry: to check a condition, check a value, or check
an invocation list for a phrase used in a routine.
</p>
<p class="commentary">These top-level routines do not look recursive, but in fact some can be,
because Dash needs to call the predicate calculus engine to typecheck
propositions: and these in turn call Dash to check that constant values
are used correctly.
</p>
<p class="commentary">All of these funnel downwards into level 2:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::check_condition</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">Dash::check_condition</span></span>:<br/><a href="5-dsh.html#SP23">&#167;23</a>, <a href="5-dsh.html#SP24">&#167;24</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><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cn</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">cn</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">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Dash (1): condition\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="5-dsh.html#SP8" class="function-link"><span class="function-syntax">Dash::funnel_to_level_2</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cn</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">int</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::check_value</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">Dash::check_value</span></span>:<br/><a href="5-dsh.html#SP24">&#167;24</a>, <a href="5-dsh.html#SP28_1">&#167;28.1</a><br/>Specifications - <a href="2-spc.html#SP12">&#167;12</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="identifier-syntax">kind</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">vn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">RVALUE_CONTEXT_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax">) </span><span class="identifier-syntax">Node::set_kind_required_by_context</span><span class="plain-syntax">(</span><span class="identifier-syntax">vn</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">vn</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Dash (1): value of kind %u\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Dash (1): value\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="5-dsh.html#SP8" class="function-link"><span class="function-syntax">Dash::funnel_to_level_2</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">vn</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">int</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::check_value_silently</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">Dash::check_value_silently</span></span>:<br/>Literal Lists - <a href="3-ll.html#SP8">&#167;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">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">vn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">RVALUE_CONTEXT_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax">) </span><span class="identifier-syntax">Node::set_kind_required_by_context</span><span class="plain-syntax">(</span><span class="identifier-syntax">vn</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">vn</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Dash (1): value of kind %u\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Dash (1): value\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="5-dsh.html#SP8" class="function-link"><span class="function-syntax">Dash::funnel_to_level_2</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">vn</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">int</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::check_invl</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="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Dash (1): invocation list '%W'\n"</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">return</span><span class="plain-syntax"> </span><a href="5-dsh.html#SP8" class="function-link"><span class="function-syntax">Dash::funnel_to_level_2</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">int</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::funnel_to_level_2</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">silently</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">no_gross_problems_thrown</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">dash_recursion_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="constant-syntax">BEGIN_DASH_MODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><span class="identifier-syntax">silently</span><span class="plain-syntax">) </span><span class="identifier-syntax">DASH_MODE_ENTER</span><span class="plain-syntax">(</span><span class="constant-syntax">ISSUE_PROBLEMS_DMODE</span><span class="plain-syntax">);</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">DASH_MODE_CREATE</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">Latticework::show_frame_variables</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">rv</span><span class="plain-syntax"> = </span><a href="5-dsh.html#SP9" class="function-link"><span class="function-syntax">Dash::typecheck_recursive</span></a><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="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="constant-syntax">END_DASH_MODE</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">rv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. (2) Recursion point. </b>Loosely speaking, Dash works by visiting every node in the parse tree being
examined with the following routine, which is therefore recursive as Dash
heads ever downward.
</p>
<p class="commentary">The routine itself is really just an outer shell, though, and has two
functions: it keeps the debugging log tidy (see above) and it produces
the backtrace if the inner routine should throw a problem message.
</p>
<p class="commentary">The recursion limit below is clearly arbitrary, but is there to prevent the
algorithm from slowing Inform unacceptably in the event of something like
</p>
<blockquote>
<p>say g + g + g + g + g + g + g + g + g + g + g + g + g + g + g + g + g + g + g + g + g + g + g;</p>
</blockquote>
<p class="commentary">where "g" is a term Inform doesn't recognise, because otherwise this will
recurse through every possible interpretation of the plus sign (i.e. every
possible order of operations).
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_DASH_RECURSION</span><span class="plain-syntax"> </span><span class="constant-syntax">10000</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::typecheck_recursive</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">Dash::typecheck_recursive</span></span>:<br/><a href="5-dsh.html#SP8">&#167;8</a>, <a href="5-dsh.html#SP10_1">&#167;10.1</a>, <a href="5-dsh.html#SP10_9_1">&#167;10.9.1</a>, <a href="5-dsh.html#SP10_9_2_2_1">&#167;10.9.2.2.1</a>, <a href="5-dsh.html#SP10_9_1_1_2_1">&#167;10.9.1.1.2.1</a>, <a href="5-dsh.html#SP10_9_1_1_3_1">&#167;10.9.1.1.3.1</a>, <a href="5-dsh.html#SP10_9_1_2">&#167;10.9.1.2</a>, <a href="5-dsh.html#SP12">&#167;12</a>, <a href="5-dsh.html#SP14_3">&#167;14.3</a>, <a href="5-dsh.html#SP14_4">&#167;14.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="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">context</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">consider_alternatives</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">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Dash on null node"</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">dash_recursion_count</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">MAX_DASH_RECURSION</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">dash_recursion_count</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">outer_id</span><span class="plain-syntax"> = </span><span class="identifier-syntax">unique_DR_call_identifier</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">problem_count_before</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">unique_DR_call_identifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DR_call_counter</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_INDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(2)"</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">return_value</span><span class="plain-syntax"> = </span><a href="5-dsh.html#SP10" class="function-link"><span class="function-syntax">Dash::typecheck_recursive_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">context</span><span class="plain-syntax">, </span><span class="identifier-syntax">consider_alternatives</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">return_value</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">ALWAYS_MATCH:</span><span class="plain-syntax"> </span><span class="constant-syntax">LOG_DASH_LEFT</span><span class="plain-syntax">; </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"== always\n"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SOMETIMES_MATCH:</span><span class="plain-syntax"> </span><span class="constant-syntax">LOG_DASH_LEFT</span><span class="plain-syntax">; </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"== sometimes\n"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEVER_MATCH:</span><span class="plain-syntax"> </span><span class="constant-syntax">LOG_DASH_LEFT</span><span class="plain-syntax">; </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"== never\n"</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="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"impossible verdict from Dash"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_OUTDENT</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">problem_count_before</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">consider_alternatives</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP9_1" class="named-paragraph-link"><span class="named-paragraph">Consider adding a backtrace of what the type-checker was up to</span><span class="named-paragraph-number">9.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">unique_DR_call_identifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">outer_id</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">return_value</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9_1" class="paragraph-anchor"></a><b>&#167;9.1. </b>The backtrace is added to problem messages only if we have just been checking
a phrase, and if it produced problems not previously seen. The trick here is
to ensure that if we have
</p>
<blockquote>
<p>let X be a random wibble bibble spong;</p>
</blockquote>
<p class="commentary">then it will be the "random ..." phrase which is backtraced, and not the
"let ..." phrase, even though that also goes wrong in turn.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Consider adding a backtrace of what the type-checker was up to</span><span class="named-paragraph-number">9.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">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">backtraced_problem_count</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">p</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">) &amp;&amp;</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">INVOCATION_LIST_NT</span><span class="plain-syntax">)) {</span>
<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="named-paragraph-container code-font"><a href="5-dsh.html#SP9_1_1" class="named-paragraph-link"><span class="named-paragraph">Backtrace what phrase definitions the type-checker was looking at</span><span class="named-paragraph-number">9.1.1</span></a></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="identifier-syntax">backtraced_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="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP9">&#167;9</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_1_1" class="paragraph-anchor"></a><b>&#167;9.1.1. </b>We skip proven invocations, and those never needed because of them, since
those aren't in dispute; and we also skip groups not even reached, since they
aren't where the problem lies. (This can happen when checking a compound "say",
from a text substitution.)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Backtrace what phrase definitions the type-checker was looking at</span><span class="named-paragraph-number">9.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">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_ALTERNATIVES</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</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">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$e\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">to_show</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_ALTERNATIVES</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</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">id_body</span><span class="plain-syntax"> *</span><span class="identifier-syntax">idb</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_phrase_invoked</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">IDTypeData::is_a_spare_say_X_phrase</span><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">idb</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">type_data</span><span class="plain-syntax">))) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">to_show</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">announce</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">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">latest</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Problems::latest_sigil</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">Str::eq_wide_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">latest</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"PM_AllInvsFailed"</span><span class="plain-syntax">)) </span><span class="identifier-syntax">announce</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">announce</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP9_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Produce the I was trying... banner</span><span class="named-paragraph-number">9.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="5-dsh.html#SP9_1_1_2" class="named-paragraph-link"><span class="named-paragraph">Produce the list of possibilities</span><span class="named-paragraph-number">9.1.1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">real_found</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="5-dsh.html#SP9_1_1_3" class="named-paragraph-link"><span class="named-paragraph">Produce the tokens which were recognisable as something</span><span class="named-paragraph-number">9.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="5-dsh.html#SP9_1_1_5" class="named-paragraph-link"><span class="named-paragraph">Produce the tokens which weren't recognisable as something</span><span class="named-paragraph-number">9.1.1.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP9_1_1_4" class="named-paragraph-link"><span class="named-paragraph">Produce the tokens which were intentionally not recognisable as something</span><span class="named-paragraph-number">9.1.1.4</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">real_found</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP9_1_1_6" class="named-paragraph-link"><span class="named-paragraph">Produce a note about real versus integer</span><span class="named-paragraph-number">9.1.1.6</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP9_1">&#167;9.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_1_1_1" class="paragraph-anchor"></a><b>&#167;9.1.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Produce the I was trying... banner</span><span class="named-paragraph-number">9.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">Problems::issue_problem_begin</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="string-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">to_show</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">Problems::issue_problem_segment</span><span class="plain-syntax">(</span><span class="string-syntax">"I was trying to match one of these phrases:"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span><span class="string-syntax">"I was trying to match this phrase:"</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="5-dsh.html#SP9_1_1">&#167;9.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_1_1_2" class="paragraph-anchor"></a><b>&#167;9.1.1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Produce the list of possibilities</span><span class="named-paragraph-number">9.1.1.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">shown</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_ALTERNATIVES</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</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">id_body</span><span class="plain-syntax"> *</span><span class="identifier-syntax">idb</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_phrase_invoked</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">IDTypeData::is_a_spare_say_X_phrase</span><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">idb</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">type_data</span><span class="plain-syntax">))) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">shown</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_number</span><span class="plain-syntax">(1, &amp;</span><span class="identifier-syntax">shown</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_invocation</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">announce</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">Problems::issue_problem_begin</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="string-syntax">"***"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">announce</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">Problems::issue_problem_begin</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="string-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">to_show</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span><span class="string-syntax">"%1. %2"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span><span class="string-syntax">"%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>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP9_1_1">&#167;9.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_1_1_3" class="paragraph-anchor"></a><b>&#167;9.1.1.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Produce the tokens which were recognisable as something</span><span class="named-paragraph-number">9.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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">any</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">inv_token_problem_token</span><span class="plain-syntax"> *</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">, </span><span class="reserved-syntax">inv_token_problem_token</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_parsed</span><span class="plain-syntax">, </span><span class="identifier-syntax">UNKNOWN_NT</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">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">already_described</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">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">already_described</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">any</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">any</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">Problems::issue_problem_begin</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="string-syntax">"*"</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="string-syntax">"I recognised:"</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="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP9_1_1_3_1" class="named-paragraph-link"><span class="named-paragraph">Produce this token</span><span class="named-paragraph-number">9.1.1.3.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="5-dsh.html#SP9_1_1">&#167;9.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_1_1_3_1" class="paragraph-anchor"></a><b>&#167;9.1.1.3.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Produce this token</span><span class="named-paragraph-number">9.1.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="identifier-syntax">Problems::quote_wording_tinted_green</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">problematic_text</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_spec</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_parsed</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_begin</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="string-syntax">"****"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::is_value</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_parsed</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_parsed</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">changed</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">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::substitute</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">changed</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">Problems::quote_kind</span><span class="plain-syntax">(3, </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">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_real_number</span><span class="plain-syntax">)) </span><span class="identifier-syntax">real_found</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><a href="2-lvl.html#SP8" class="function-link"><span class="function-syntax">Lvalues::is_lvalue</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_parsed</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP9_1_1_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Produce the token for an lvalue</span><span class="named-paragraph-number">9.1.1.3.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">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_parsed</span><span class="plain-syntax">, </span><span class="identifier-syntax">PHRASE_TO_DECIDE_VALUE_NT</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP9_1_1_3_1_2" class="named-paragraph-link"><span class="named-paragraph">Produce the token for a phrase deciding a value</span><span class="named-paragraph-number">9.1.1.3.1.2</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP9_1_1_3_1_3" class="named-paragraph-link"><span class="named-paragraph">Produce the token for a constant rvalue</span><span class="named-paragraph-number">9.1.1.3.1.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="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span><span class="string-syntax">"%1 = &lt;i&gt;%2&lt;/i&gt;"</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="5-dsh.html#SP9_1_1_3">&#167;9.1.1.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_1_1_3_1_1" class="paragraph-anchor"></a><b>&#167;9.1.1.3.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Produce the token for an lvalue</span><span class="named-paragraph-number">9.1.1.3.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span><span class="string-syntax">"%1 = &lt;i&gt;%2&lt;/i&gt;, holding &lt;i&gt;%3&lt;/i&gt;"</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP9_1_1_3_1">&#167;9.1.1.3.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_1_1_3_1_2" class="paragraph-anchor"></a><b>&#167;9.1.1.3.1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Produce the token for a phrase deciding a value</span><span class="named-paragraph-number">9.1.1.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">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">seg</span><span class="plain-syntax"> = </span><span class="string-syntax">"%1 = an instruction to work out &lt;i&gt;%3&lt;/i&gt;"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">seg</span><span class="plain-syntax"> = </span><span class="string-syntax">"%1 = a phrase"</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">found_invl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_parsed</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">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_ALTERNATIVES</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">found_invl</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">"$e\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP21" class="function-link"><span class="function-syntax">Dash::reading_passed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</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">seg</span><span class="plain-syntax"> = </span><span class="string-syntax">"%1 = an instruction I think should work out &lt;i&gt;%3&lt;/i&gt;, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"but which I can't make sense of"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><a href="4-inv.html#SP6" class="function-link"><span class="function-syntax">Invocations::get_no_tokens</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tok</span><span class="plain-syntax"> = </span><a href="4-inv.html#SP10" class="function-link"><span class="function-syntax">Invocations::get_token_as_parsed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</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">Problems::quote_wording</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">tok</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">seg</span><span class="plain-syntax"> = </span><span class="string-syntax">"%1 = an instruction I think should work out &lt;i&gt;%3&lt;/i&gt;, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"but which I can't perform because '%4' doesn't make sense here"</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="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span><span class="identifier-syntax">seg</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP9_1_1_3_1">&#167;9.1.1.3.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_1_1_3_1_3" class="paragraph-anchor"></a><b>&#167;9.1.1.3.1.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Produce the token for a constant rvalue</span><span class="named-paragraph-number">9.1.1.3.1.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">seg</span><span class="plain-syntax"> = </span><span class="string-syntax">"%1 = &lt;i&gt;%3&lt;/i&gt;"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-rvl.html#SP21" class="function-link"><span class="function-syntax">Rvalues::is_CONSTANT_construction</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_parsed</span><span class="plain-syntax">, </span><span class="identifier-syntax">CON_property</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_constant_property</span><span class="plain-syntax">(</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_parsed</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">Properties::is_value_property</span><span class="plain-syntax">(</span><span class="identifier-syntax">prn</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">binary_predicate</span><span class="plain-syntax"> *</span><span class="identifier-syntax">bp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ValueProperties::get_stored_relation</span><span class="plain-syntax">(</span><span class="identifier-syntax">prn</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">bp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">seg</span><span class="plain-syntax"> = </span><span class="string-syntax">"%1 = &lt;i&gt;%3&lt;/i&gt;, which is used to store %4, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"but is not the same thing as the relation itself"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_relation</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">bp</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="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span><span class="identifier-syntax">seg</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP9_1_1_3_1">&#167;9.1.1.3.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_1_1_4" class="paragraph-anchor"></a><b>&#167;9.1.1.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Produce the tokens which were intentionally not recognisable as something</span><span class="named-paragraph-number">9.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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">unknowns</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">inv_token_problem_token</span><span class="plain-syntax"> *</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">, </span><span class="reserved-syntax">inv_token_problem_token</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_parsed</span><span class="plain-syntax">, </span><span class="identifier-syntax">UNKNOWN_NT</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">new_name</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">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">already_described</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">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">already_described</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">unknowns</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">5</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording_tinted_red</span><span class="plain-syntax">(++</span><span class="identifier-syntax">unknowns</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">problematic_text</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">unknowns</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">Problems::issue_problem_begin</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="string-syntax">"*"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">chunk</span><span class="plain-syntax"> = </span><span class="string-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">unknowns</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><span class="identifier-syntax">chunk</span><span class="plain-syntax"> = </span><span class="string-syntax">"The name '%1' doesn't yet exist."</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="constant-syntax">2</span><span class="plain-syntax">: </span><span class="identifier-syntax">chunk</span><span class="plain-syntax"> = </span><span class="string-syntax">"The names '%1' and '%2' don't yet exist."</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="constant-syntax">3</span><span class="plain-syntax">: </span><span class="identifier-syntax">chunk</span><span class="plain-syntax"> = </span><span class="string-syntax">"The names '%1', '%2' and '%3' don't yet exist."</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="constant-syntax">4</span><span class="plain-syntax">: </span><span class="identifier-syntax">chunk</span><span class="plain-syntax"> = </span><span class="string-syntax">"The names '%1', '%2', '%3' and '%4' don't yet exist."</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="identifier-syntax">chunk</span><span class="plain-syntax"> = </span><span class="string-syntax">"The names '%1', '%2', '%3', '%4', and so on, don't yet exist."</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">Problems::issue_problem_segment</span><span class="plain-syntax">(</span><span class="identifier-syntax">chunk</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="5-dsh.html#SP9_1_1">&#167;9.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_1_1_5" class="paragraph-anchor"></a><b>&#167;9.1.1.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Produce the tokens which weren't recognisable as something</span><span class="named-paragraph-number">9.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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">unknowns</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">inv_token_problem_token</span><span class="plain-syntax"> *</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">, </span><span class="reserved-syntax">inv_token_problem_token</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_parsed</span><span class="plain-syntax">, </span><span class="identifier-syntax">UNKNOWN_NT</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">new_name</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">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">already_described</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">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">already_described</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">unknowns</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">5</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording_tinted_red</span><span class="plain-syntax">(++</span><span class="identifier-syntax">unknowns</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">problematic_text</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">unknowns</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">Problems::issue_problem_begin</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="string-syntax">"*"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">chunk</span><span class="plain-syntax"> = </span><span class="string-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">unknowns</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><span class="identifier-syntax">chunk</span><span class="plain-syntax"> = </span><span class="string-syntax">"But I didn't recognise '%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="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">: </span><span class="identifier-syntax">chunk</span><span class="plain-syntax"> = </span><span class="string-syntax">"But I didn't recognise '%1' or '%2'."</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="constant-syntax">3</span><span class="plain-syntax">: </span><span class="identifier-syntax">chunk</span><span class="plain-syntax"> = </span><span class="string-syntax">"But I didn't recognise '%1', '%2' or '%3'."</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="constant-syntax">4</span><span class="plain-syntax">: </span><span class="identifier-syntax">chunk</span><span class="plain-syntax"> = </span><span class="string-syntax">"But I didn't recognise '%1', '%2', '%3' or '%4'."</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="identifier-syntax">chunk</span><span class="plain-syntax"> = </span><span class="string-syntax">"But I didn't recognise '%1', '%2', '%3', '%4' and so 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="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span><span class="identifier-syntax">chunk</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="5-dsh.html#SP9_1_1">&#167;9.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_1_1_6" class="paragraph-anchor"></a><b>&#167;9.1.1.6. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Produce a note about real versus integer</span><span class="named-paragraph-number">9.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">Problems::issue_problem_begin</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="string-syntax">"*"</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">" %PNote that Inform's kinds 'number' and 'real number' are not "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"interchangeable. A 'number' like 7 can be used where a 'real "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"number' is expected - it becomes 7.000 - but not vice versa. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Use 'R to the nearest whole number' if you want to make a "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"conversion."</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="5-dsh.html#SP9_1_1">&#167;9.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. (3) Context switching. </b>After those epic preliminaries, we finally do some typechecking.
</p>
<p class="commentary">The scheme here is that our expectations of <span class="extract"><span class="extract-syntax">p</span></span> depend on the context, and
this is defined by some node higher in the current subtree than <span class="extract"><span class="extract-syntax">p</span></span>, which
we will call <span class="extract"><span class="extract-syntax">context</span></span>. Most of the time this is the parent of <span class="extract"><span class="extract-syntax">p</span></span>, but
sometimes the grandparent or great-grandparent; and at the start of the
recursion, when no context has appeared yet, it will be null. In effect,
then, the tree we're checking contains its own instructions on how it
should be checked. For example, the subtree
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> CONDITION_CONTEXT_NT</span>
<span class="plain-syntax"> p</span>
</pre>
<p class="commentary">tells us that when we reach <span class="extract"><span class="extract-syntax">p</span></span> it should be checked as a condition.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::typecheck_recursive_inner</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">Dash::typecheck_recursive_inner</span></span>:<br/><a href="5-dsh.html#SP9">&#167;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">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">context</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">consider_alternatives</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(3)"</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">-&gt;</span><span class="identifier-syntax">node_type</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">CONDITION_CONTEXT_NT:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_1" class="named-paragraph-link"><span class="named-paragraph">Switch context</span><span class="named-paragraph-number">10.1</span></a></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">RVALUE_CONTEXT_NT:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_1" class="named-paragraph-link"><span class="named-paragraph">Switch context</span><span class="named-paragraph-number">10.1</span></a></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">MATCHING_RVALUE_CONTEXT_NT:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_5" class="named-paragraph-link"><span class="named-paragraph">Switch context to an rvalue matching a description</span><span class="named-paragraph-number">10.5</span></a></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">SPECIFIC_RVALUE_CONTEXT_NT:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_6" class="named-paragraph-link"><span class="named-paragraph">Switch context to an rvalue matching a value</span><span class="named-paragraph-number">10.6</span></a></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">VOID_CONTEXT_NT:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_7" class="named-paragraph-link"><span class="named-paragraph">Switch to a void context</span><span class="named-paragraph-number">10.7</span></a></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">LVALUE_CONTEXT_NT:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_2" class="named-paragraph-link"><span class="named-paragraph">Switch context to an lvalue</span><span class="named-paragraph-number">10.2</span></a></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">LVALUE_TR_CONTEXT_NT:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_3" class="named-paragraph-link"><span class="named-paragraph">Switch context to a table reference lvalue</span><span class="named-paragraph-number">10.3</span></a></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">LVALUE_LOCAL_CONTEXT_NT:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_4" class="named-paragraph-link"><span class="named-paragraph">Switch context to an existing local variable lvalue</span><span class="named-paragraph-number">10.4</span></a></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">NEW_LOCAL_CONTEXT_NT:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_8" class="named-paragraph-link"><span class="named-paragraph">Deal with a new local variable name</span><span class="named-paragraph-number">10.8</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9" class="named-paragraph-link"><span class="named-paragraph">Typecheck within current context</span><span class="named-paragraph-number">10.9</span></a></span><span class="plain-syntax">;</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">NEVER_MATCH</span><span class="plain-syntax">; </span><span class="comment-syntax"> to prevent compiler warnings: unreachable in fact</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10_1" class="paragraph-anchor"></a><b>&#167;10.1. </b>When we find a node like <span class="extract"><span class="extract-syntax">CONDITION_CONTEXT_NT</span></span>, that becomes the new context
and we move down to its only child.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">SWITCH_CONTEXT_AND_RECURSE</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">) </span><a href="5-dsh.html#SP9" class="function-link"><span class="function-syntax">Dash::typecheck_recursive</span></a><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">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">)</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Switch context</span><span class="named-paragraph-number">10.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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">SWITCH_CONTEXT_AND_RECURSE</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="5-dsh.html#SP10">&#167;10</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP10_2" class="paragraph-anchor"></a><b>&#167;10.2. </b>Other context switches are essentially the same thing, plus a check that
the value meets some extra requirement. For example:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Switch context to an lvalue</span><span class="named-paragraph-number">10.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SWITCH_CONTEXT_AND_RECURSE</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><a href="2-lvl.html#SP8" class="function-link"><span class="function-syntax">Lvalues::is_lvalue</span></a><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">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_2_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem for not being an lvalue</span><span class="named-paragraph-number">10.2.1</span></a></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">rv</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_3" class="paragraph-anchor"></a><b>&#167;10.3. </b>More specifically:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Switch context to a table reference lvalue</span><span class="named-paragraph-number">10.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SWITCH_CONTEXT_AND_RECURSE</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">Node::is</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">TABLE_ENTRY_NT</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="5-dsh.html#SP10_3_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem for not being a table reference</span><span class="named-paragraph-number">10.3.1</span></a></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">rv</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_4" class="paragraph-anchor"></a><b>&#167;10.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Switch context to an existing local variable lvalue</span><span class="named-paragraph-number">10.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SWITCH_CONTEXT_AND_RECURSE</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">Node::is</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">LOCAL_VARIABLE_NT</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="5-dsh.html#SP10_4_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem for not being an existing local</span><span class="named-paragraph-number">10.4.1</span></a></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">rv</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_5" class="paragraph-anchor"></a><b>&#167;10.5. </b>Suppose we are matching the parameter of a phrase like this:
</p>
<blockquote>
<p>To inspect (D - an open door): ...</p>
</blockquote>
<p class="commentary">and typechecking the following invocation:
</p>
<blockquote>
<p>inspect the Marble Portal;</p>
</blockquote>
<p class="commentary">Then we would have <span class="extract"><span class="extract-syntax">p</span></span> set to some value &mdash; here "the Marble Portal" &mdash;
and the <span class="extract"><span class="extract-syntax">MATCHING_RVALUE_CONTEXT_NT</span></span> node would point to a description node
for open doors. We must see if <span class="extract"><span class="extract-syntax">p</span></span> matches that. Any match can be at best at
the "sometimes" level. We can prove the Marble Portal is a door at compile
time, but we can't prove it's open until run-time.
</p>
<p class="commentary">Note that we switch context and recurse first, then make the supplementary
check afterwards, when we know the kinds at least must be right.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Switch context to an rvalue matching a description</span><span class="named-paragraph-number">10.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SWITCH_CONTEXT_AND_RECURSE</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">rv</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><a href="5-dsh.html#SP7" class="function-link"><span class="function-syntax">Dash::worst_case</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rv</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="5-dsh.html#SP26" class="function-link"><span class="function-syntax">Dash::compatible_with_description</span></a><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">Node::get_token_to_be_parsed_against</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_6" class="paragraph-anchor"></a><b>&#167;10.6. </b>This is something else that wouldn't appear in a typical typechecker.
Here we are dealing with a phrase specification such as:
</p>
<blockquote>
<p>To attract (N - 10) things: ...</p>
</blockquote>
<p class="commentary">where the "N" argument will be accepted if and only if it's the value 10.
The fact that Inform allows this is further evidence of the slippery way
that natural language doesn't distinguish values from types; early designs
of Inform didn't allow it, but many people reported this as a bug.
</p>
<p class="commentary">Again we switch context and recurse first. We can't safely test pointer
values, such as texts, for equality at compile time &mdash; for one thing, we
don't know what text substitutions will then expand to &mdash; so the value
test only forces us towards never or always when the constants being
compared are word values.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Switch context to an rvalue matching a value</span><span class="named-paragraph-number">10.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">rv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SWITCH_CONTEXT_AND_RECURSE</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">rv</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><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="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Kinds::Behaviour::uses_block_values</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</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">CONSTANT_NT</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">val</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_token_to_be_parsed_against</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><a href="2-rvl.html#SP22" class="function-link"><span class="function-syntax">Rvalues::compare_CONSTANT</span></a><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">val</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_6_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem for being the wrong rvalue</span><span class="named-paragraph-number">10.6.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="identifier-syntax">rv</span><span class="plain-syntax"> = </span><a href="5-dsh.html#SP7" class="function-link"><span class="function-syntax">Dash::worst_case</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rv</span><span class="plain-syntax">, </span><span class="identifier-syntax">SOMETIMES_MATCH</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"dropping to sometimes level for value comparison\n"</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_7" class="paragraph-anchor"></a><b>&#167;10.7. </b>I would ideally like to remove void contexts from Dash entirely, but was
forced to retain them by the popularity of the Hypothetical Questions
extension, which made use of the old undocumented <span class="extract"><span class="extract-syntax">phrase</span></span> token.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Switch to a void context</span><span class="named-paragraph-number">10.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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SWITCH_CONTEXT_AND_RECURSE</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">rv</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!(</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">, </span><span class="identifier-syntax">PHRASE_TO_DECIDE_VALUE_NT</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_7_1" class="named-paragraph-link"><span class="named-paragraph">Issue problem for not being a phrase</span><span class="named-paragraph-number">10.7.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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_2_1" class="paragraph-anchor"></a><b>&#167;10.2.1. </b>A whole set of problem messages arise out of contextual failures:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for not being an lvalue</span><span class="named-paragraph-number">10.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="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</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_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">Node::get_text</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">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_ValueAsStorageItem</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 '%2' is a value, not a place where a value is "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"stored. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"%PFor example, if 'The tally is a number that varies.', then "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"I can 'increment the tally', but I can't 'increment 37' - the "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"number 37 is always what it is. Similarly, I can't 'increment "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the number of people'. Phrases like 'increment' work only on "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"stored values, like values that vary, or table entries."</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="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_2">&#167;10.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_3_1" class="paragraph-anchor"></a><b>&#167;10.3.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for not being a table reference</span><span class="named-paragraph-number">10.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="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</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_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">Node::get_text</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">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_ValueAsTableReference</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 '%2' is a value, not a reference to an entry "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"in a table."</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="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_3">&#167;10.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_4_1" class="paragraph-anchor"></a><b>&#167;10.4.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for not being an existing local</span><span class="named-paragraph-number">10.4.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TEST_DASH_MODE</span><span class="plain-syntax">(</span><span class="constant-syntax">ISSUE_LOCAL_PROBLEMS_DMODE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</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_wording</span><span class="plain-syntax">(2, </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><a href="2-spc.html#SP2" class="function-link"><span class="function-syntax">Specifications::is_kind_like</span></a><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">Problems::quote_text</span><span class="plain-syntax">(3, </span><span class="string-syntax">"a kind of value"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind_of</span><span class="plain-syntax">(3, </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">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_ExistingVarNotFound</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 sentence %1, I was expecting that '%2' would be the "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"name of a temporary value, but it turned out to be %3."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_4">&#167;10.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_6_1" class="paragraph-anchor"></a><b>&#167;10.6.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for being the wrong rvalue</span><span class="named-paragraph-number">10.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="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</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_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">Node::get_text</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">Problems::quote_spec</span><span class="plain-syntax">(3, </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">Problems::quote_spec</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">val</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_NotExactValueWanted</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 sentence %1, I was expecting that '%2' would be the specific "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"value '%4'."</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="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_6">&#167;10.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_7_1" class="paragraph-anchor"></a><b>&#167;10.7.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue problem for not being a phrase</span><span class="named-paragraph-number">10.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="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</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_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">Node::get_text</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">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="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 sentence %1, I was expecting that '%2' would be a phrase."</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="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_7">&#167;10.7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_8" class="paragraph-anchor"></a><b>&#167;10.8. New variables. </b>The following doesn't switch context and recurse down: there's nothing
to recurse down to, since all we have is a name for a new variable. Instead
we deal with that right away.
</p>
<p class="commentary">It might seem rather odd that the typechecker should be the part of Inform
which creates local variables. Surely that's a sign that the parsing went
wrong, so how did things get to this stage?
</p>
<p class="commentary">In a C-like language, where variables are predeclared, that would be true.
But in Inform, a phrase like:
</p>
<blockquote>
<p>let the monster be a random pterodactyl;</p>
</blockquote>
<p class="commentary">can be valid even where "the monster" is text not known to the S-parser
as yet &mdash; indeed, that's how local variables are made. It's the typechecker
which sorts this out, because only the typechecker can decide which of the
subtly different forms of "let" is being used.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Deal with a new local variable name</span><span class="named-paragraph-number">10.8</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_kind_required_by_context</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">check</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">check</span><span class="plain-syntax">, </span><span class="identifier-syntax">AMBIGUITY_NT</span><span class="plain-syntax">)) </span><span class="identifier-syntax">check</span><span class="plain-syntax"> = </span><span class="identifier-syntax">check</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">LocalVariables::permit_as_new_local</span><span class="plain-syntax">(</span><span class="identifier-syntax">check</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">kind_of_var_to_create</span><span class="plain-syntax">) *</span><span class="identifier-syntax">kind_of_var_to_create</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">ALWAYS_MATCH</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="5-dsh.html#SP10_8_1" class="named-paragraph-link"><span class="named-paragraph">Issue a problem for an inappropriate variable name</span><span class="named-paragraph-number">10.8.1</span></a></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">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_8_1" class="paragraph-anchor"></a><b>&#167;10.8.1. </b>This problem message is never normally seen using the definitions in the
Standard Rules because the definitions made there are such that other
problems appear first. So the only way to see this message is to declare an
unambiguous phrase with one of its tokens requiring a variable of a
species; and then to misuse that phrase.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem for an inappropriate variable name</span><span class="named-paragraph-number">10.8.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="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</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_wording</span><span class="plain-syntax">(2, </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><a href="2-spc.html#SP2" class="function-link"><span class="function-syntax">Specifications::is_kind_like</span></a><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">Problems::quote_text</span><span class="plain-syntax">(3, </span><span class="string-syntax">"a kind of value"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind_of</span><span class="plain-syntax">(3, </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">Problems::quote_kind</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><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_KindOfVariable</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 sentence %1, I was expecting that '%2' would be a new "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"variable name (to hold %4), but it turned out to be %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="5-dsh.html#SP10_8">&#167;10.8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9" class="paragraph-anchor"></a><b>&#167;10.9. (4) Typechecking within current context. </b>Everything else, then, passes through here, with the context now set either
to <span class="extract"><span class="extract-syntax">NULL</span></span> (meaning no expectations) or to some ancestor of <span class="extract"><span class="extract-syntax">p</span></span> in the parse
tree.
</p>
<p class="commentary">Level 4 forks rapidly into three branches: (4A), for ambiguous readings;
(4I), for single invocations; and (4S), for single readings other than
invocations. Here's the code which does the switching:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Typecheck within current context</span><span class="named-paragraph-number">10.9</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_needed</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">condition_context</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">context</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind_needed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_kind_required_by_context</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">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">context</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::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">context</span><span class="plain-syntax">, </span><span class="identifier-syntax">LOGICAL_AND_NT</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">context</span><span class="plain-syntax">, </span><span class="identifier-syntax">LOGICAL_OR_NT</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">context</span><span class="plain-syntax">, </span><span class="identifier-syntax">LOGICAL_NOT_NT</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">context</span><span class="plain-syntax">, </span><span class="identifier-syntax">LOGICAL_TENSE_NT</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">condition_context</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="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4)"</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">outcome</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ALWAYS_MATCH</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">consider_alternatives</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_2" class="named-paragraph-link"><span class="named-paragraph">Resolve an ambiguous reading</span><span class="named-paragraph-number">10.9.2</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1" class="named-paragraph-link"><span class="named-paragraph">Verify an unambiguous reading</span><span class="named-paragraph-number">10.9.1</span></a></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">outcome</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1" class="paragraph-anchor"></a><b>&#167;10.9.1. </b>For a phrase node, we pass the buck down to its invocation list. For an
invocation list, we pass the buck down to its invocation (which may or
may not be the first in a chain of alternatives), which means we end up
in (4I) either directly or via (4A). For everything else, it's (4S) for us.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Verify an unambiguous reading</span><span class="named-paragraph-number">10.9.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">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">node_type</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">PHRASE_TO_DECIDE_VALUE_NT:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> = </span><a href="5-dsh.html#SP9" class="function-link"><span class="function-syntax">Dash::typecheck_recursive</span></a><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">context</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">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INVOCATION_LIST_NT:</span><span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INVOCATION_LIST_SAY_NT:</span><span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">AMBIGUITY_NT:</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><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_3" class="named-paragraph-link"><span class="named-paragraph">Unknown found text occurs as a command</span><span class="named-paragraph-number">10.9.1.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="constant-syntax">BEGIN_DASH_MODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Dash_ambiguity_list</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">outcome</span><span class="plain-syntax"> = </span><a href="5-dsh.html#SP9" class="function-link"><span class="function-syntax">Dash::typecheck_recursive</span></a><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">context</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="constant-syntax">END_DASH_MODE</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="identifier-syntax">INVOCATION_NT:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1" class="named-paragraph-link"><span class="named-paragraph">Step (4I) Verify an invocation</span><span class="named-paragraph-number">10.9.1.1</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_2" class="named-paragraph-link"><span class="named-paragraph">Step (4S) Verify anything else</span><span class="named-paragraph-number">10.9.1.2</span></a></span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9">&#167;10.9</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_2" class="paragraph-anchor"></a><b>&#167;10.9.2. </b>(4A) Ambiguities.
Ambiguities presently consist of chains of invocation nodes listed in
the tree as alternatives.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Resolve an ambiguous reading</span><span class="named-paragraph-number">10.9.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4A)"</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">list_of_possible_readings</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_INVOCATIONS_PER_PHRASE</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">no_of_possible_readings</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_of_passed_readings</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="5-dsh.html#SP10_9_2_1" class="named-paragraph-link"><span class="named-paragraph">Step (4A.a) Set up the list of readings to test</span><span class="named-paragraph-number">10.9.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_2_2" class="named-paragraph-link"><span class="named-paragraph">Step (4A.b) Recurse Dash to try each reading in turn</span><span class="named-paragraph-number">10.9.2.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><a href="5-dsh.html#SP4" class="function-link"><span class="function-syntax">Dash::problems_have_been_issued</span></a><span class="plain-syntax">()) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">no_of_passed_readings</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="5-dsh.html#SP10_9_2_3" class="named-paragraph-link"><span class="named-paragraph">Step (4A.c) Preserve successful readings</span><span class="named-paragraph-number">10.9.2.3</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_2_4" class="named-paragraph-link"><span class="named-paragraph">Step (4A.d) Give up with no readings possible</span><span class="named-paragraph-number">10.9.2.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Ambiguity resolved to: $E"</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="5-dsh.html#SP10_9">&#167;10.9</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_2_1" class="paragraph-anchor"></a><b>&#167;10.9.2.1. </b>Phrase definitions are kept in a linked list with a total ordering which
properly contains the partial ordering in which \(P_1\leq P_2\) if they are
lexically identical and if each parameter of \(P_1\) provably, at compile time,
also satisfies the requirements for the corresponding parameter of \(P_2\).
They have already been lexically parsed in that order, so the list of
invocations (which will have accumulated during parsing) is also in that
same order. Now this is nearly the correct order for type-checking. But we
make one last adjustment: the phrase being compiled is moved to the back of
the list. This is to make recursion always the last thing checked, so that
later rules can override earlier ones but still make use of them.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4A.a) Set up the list of readings to test</span><span class="named-paragraph-number">10.9.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4A.a)"</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">alt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_ALTERNATIVES</span><span class="plain-syntax">(</span><span class="identifier-syntax">alt</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">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">alt</span><span class="plain-syntax">, </span><span class="identifier-syntax">INVOCATION_NT</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_phrase_invoked</span><span class="plain-syntax">(</span><span class="identifier-syntax">alt</span><span class="plain-syntax">) != </span><span class="identifier-syntax">Functions::defn_being_compiled</span><span class="plain-syntax">()))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_2_1_1" class="named-paragraph-link"><span class="named-paragraph">Add this reading to the list of test cases</span><span class="named-paragraph-number">10.9.2.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_ALTERNATIVES</span><span class="plain-syntax">(</span><span class="identifier-syntax">alt</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">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">alt</span><span class="plain-syntax">, </span><span class="identifier-syntax">INVOCATION_NT</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_phrase_invoked</span><span class="plain-syntax">(</span><span class="identifier-syntax">alt</span><span class="plain-syntax">) != </span><span class="identifier-syntax">Functions::defn_being_compiled</span><span class="plain-syntax">())))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_2_1_1" class="named-paragraph-link"><span class="named-paragraph">Add this reading to the list of test cases</span><span class="named-paragraph-number">10.9.2.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Resolving %d possible readings:\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">no_of_possible_readings</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">no_of_possible_readings</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Possibility (P%d) $e\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">list_of_possible_readings</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_2">&#167;10.9.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_2_1_1" class="paragraph-anchor"></a><b>&#167;10.9.2.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Add this reading to the list of test cases</span><span class="named-paragraph-number">10.9.2.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">no_of_possible_readings</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">MAX_INVOCATIONS_PER_PHRASE</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"overrun"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">list_of_possible_readings</span><span class="plain-syntax">[</span><span class="identifier-syntax">no_of_possible_readings</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">alt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::clear_flags</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">alt</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_2_1">&#167;10.9.2.1</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_2_2" class="paragraph-anchor"></a><b>&#167;10.9.2.2. </b>Now we work through the list of tests. We must produce at least one reading
passing at least at the "sometimes" level marked by the <span class="extract"><span class="extract-syntax">UNPROVEN_DASHFLAG</span></span>, or
else the whole specification fails its match. The first proven match stops our
work, since we can never need lower-priority interpretations.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4A.b) Recurse Dash to try each reading in turn</span><span class="named-paragraph-number">10.9.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4A.b)"</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">ref</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">ref</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">no_of_possible_readings</span><span class="plain-syntax">; </span><span class="identifier-syntax">ref</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">list_of_possible_readings</span><span class="plain-syntax">[</span><span class="identifier-syntax">ref</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_2_2_1" class="named-paragraph-link"><span class="named-paragraph">Test the current reading and set its results flags accordingly</span><span class="named-paragraph-number">10.9.2.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(P%d) %s: $e\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">ref</span><span class="plain-syntax">, </span><a href="5-dsh.html#SP21" class="function-link"><span class="function-syntax">Dash::verdict_to_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">), </span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::test_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="constant-syntax">PASSED_DASHFLAG</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">no_of_passed_readings</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::test_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="constant-syntax">UNPROVEN_DASHFLAG</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</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><a href="5-dsh.html#SP4" class="function-link"><span class="function-syntax">Dash::problems_have_been_issued</span></a><span class="plain-syntax">()) </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> to prevent duplication of problem messages</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"List %s: "</span><span class="plain-syntax">, (</span><span class="identifier-syntax">no_of_passed_readings</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)?</span><span class="string-syntax">"passed"</span><span class="plain-syntax">:</span><span class="string-syntax">"failed"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">no_of_possible_readings</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">list_of_possible_readings</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"%s "</span><span class="plain-syntax">, </span><a href="5-dsh.html#SP21" class="function-link"><span class="function-syntax">Dash::quick_verdict_to_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"|\n"</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_2">&#167;10.9.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_2_2_1" class="paragraph-anchor"></a><b>&#167;10.9.2.2.1. </b>We tell Dash to run silently unless grosser-than-gross problems arise, and
also tell it to check the reading with no alternatives considered. (If we
let it consider alternatives, that would be circular: we'd end up here
again, and so on forever.)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Test the current reading and set its results flags accordingly</span><span class="named-paragraph-number">10.9.2.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">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(P%d) Trying &lt;%W&gt;: $e\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">ref</span><span class="plain-syntax">, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">), </span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="constant-syntax">BEGIN_DASH_MODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DASH_MODE_EXIT</span><span class="plain-syntax">(</span><span class="constant-syntax">ISSUE_PROBLEMS_DMODE</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">rv</span><span class="plain-syntax"> = </span><a href="5-dsh.html#SP9" class="function-link"><span class="function-syntax">Dash::typecheck_recursive</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">context</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="constant-syntax">END_DASH_MODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::set_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="constant-syntax">TESTED_DASHFLAG</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">rv</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::set_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="constant-syntax">PASSED_DASHFLAG</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> = </span><a href="5-dsh.html#SP7" class="function-link"><span class="function-syntax">Dash::worst_case</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">outcome</span><span class="plain-syntax">, </span><span class="identifier-syntax">rv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_2_2">&#167;10.9.2.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_2_3" class="paragraph-anchor"></a><b>&#167;10.9.2.3. </b>This is the happy ending, in which the list can probably be passed, though
there are still a handful of pitfalls.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4A.c) Preserve successful readings</span><span class="named-paragraph-number">10.9.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4A.c)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_2_3_1" class="named-paragraph-link"><span class="named-paragraph">Step (4A.c.1) Winnow the reading list down to the survivors</span><span class="named-paragraph-number">10.9.2.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_2_3_2" class="named-paragraph-link"><span class="named-paragraph">Step (4A.c.2) Infer the kind of any requested local variable</span><span class="named-paragraph-number">10.9.2.3.2</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_2">&#167;10.9.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_2_3_1" class="paragraph-anchor"></a><b>&#167;10.9.2.3.1. </b>To recap, after checking through the possible readings we have something
like this as the result:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> f ? f g ? ? p - - -</span>
</pre>
<p class="commentary">We can now throw away the <span class="extract"><span class="extract-syntax">f</span></span>, <span class="extract"><span class="extract-syntax">g</span></span> and <span class="extract"><span class="extract-syntax">-</span></span> readings &mdash; failed, grossly failed,
or never reached &mdash; to leave just those which will be compiled:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> ? ? ? p</span>
</pre>
<p class="commentary">If compiled this will result in run-time code to check if the arguments
allow the first invocation and run it if so; then the second; then the third;
and, if those three fell through, run the fourth invocation without further
checking.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4A.c.1) Winnow the reading list down to the survivors</span><span class="named-paragraph-number">10.9.2.3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4A.c.1)"</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">invocational</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">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">Dash_ambiguity_list</span><span class="plain-syntax">, </span><span class="identifier-syntax">AMBIGUITY_NT</span><span class="plain-syntax">)) </span><span class="identifier-syntax">invocational</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">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Winnow %s from $T\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">invocational</span><span class="plain-syntax">)?</span><span class="string-syntax">"invocationally"</span><span class="plain-syntax">:</span><span class="string-syntax">"regularly"</span><span class="plain-syntax">, </span><span class="identifier-syntax">Dash_ambiguity_list</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">invocational</span><span class="plain-syntax">) </span><span class="identifier-syntax">Dash_ambiguity_list</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="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">last_survivor</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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ref</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">ref</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">no_of_possible_readings</span><span class="plain-syntax">; </span><span class="identifier-syntax">ref</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">list_of_possible_readings</span><span class="plain-syntax">[</span><span class="identifier-syntax">ref</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inv</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</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><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::test_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="constant-syntax">PASSED_DASHFLAG</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">invocational</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">last_survivor</span><span class="plain-syntax">) </span><span class="identifier-syntax">last_survivor</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">Dash_ambiguity_list</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_survivor</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">link</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Dash_ambiguity_list</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::copy</span><span class="plain-syntax">(</span><span class="identifier-syntax">Dash_ambiguity_list</span><span class="plain-syntax">, </span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Dash_ambiguity_list</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">link</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Dash_ambiguity_list</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</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">break</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">invocational</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">Dash_ambiguity_list</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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">nfi</span><span class="plain-syntax"> = -1, </span><span class="identifier-syntax">number_ambiguity</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_ALTERNATIVES</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</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">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">INVOCATION_NT</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">nti</span><span class="plain-syntax"> = </span><a href="4-inv.html#SP6" class="function-link"><span class="function-syntax">Invocations::get_no_tokens</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">nfi</span><span class="plain-syntax"> == -1) </span><span class="identifier-syntax">nfi</span><span class="plain-syntax"> = </span><span class="identifier-syntax">nti</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">nfi</span><span class="plain-syntax"> != </span><span class="identifier-syntax">nti</span><span class="plain-syntax">) </span><span class="identifier-syntax">number_ambiguity</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">number_ambiguity</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_2_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Issue the number ambiguity problem message</span><span class="named-paragraph-number">10.9.2.3.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"After winnowing, CS is $T\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_2_3">&#167;10.9.2.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_2_3_1_1" class="paragraph-anchor"></a><b>&#167;10.9.2.3.1.1. </b>This is another sort of error which couldn't happen with a conventional
programming language &mdash; in C, for instance, it's syntactically obvious
how many arguments a function call has, because the brackets and commas
are unambiguous. But in Inform, there are no reserved tokens of syntax
acting like that. So we could easily have two accepted invocations in the
list which have different numbers of arguments to each other, and there's
no way safely to adjudicate that at run-time.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue the number ambiguity problem message</span><span class="named-paragraph-number">10.9.2.3.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</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">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_UnequalValueAmbiguity</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 %1 is ambiguous in a way that I can't disentangle. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"It has more than one plausible interpretation, such that it "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"would only be possible to tell which is valid at run-time: "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"ordinarily that would be fine, but because the different "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"interpretations are so different (and involve different "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"numbers of values being used) there's no good way to cope. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Try rewording one of the phrases which caused this clash: "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"there's a good chance the problem will then go away."</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="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_2_3_1">&#167;10.9.2.3.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_2_3_2" class="paragraph-anchor"></a><b>&#167;10.9.2.3.2. </b>If an invocation passes, and asks to create a local variable, we need
to mark the tree accordingly. If there's just one invocation then (4I)
handles this, but if there's ambiguity, we handle it here, and only
for the surviving nodes.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4A.c.2) Infer the kind of any requested local variable</span><span class="named-paragraph-number">10.9.2.3.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4A.c.2)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_ALTERNATIVES</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</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">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">INVOCATION_NT</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP13" class="function-link"><span class="function-syntax">Dash::set_up_any_local_required</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NEVER_MATCH</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">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_2_3">&#167;10.9.2.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_2_4" class="paragraph-anchor"></a><b>&#167;10.9.2.4. </b>And this is the unhappy ending:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4A.d) Give up with no readings possible</span><span class="named-paragraph-number">10.9.2.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4A.d)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-il.html#SP6" class="function-link"><span class="function-syntax">InvocationLists::length</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">) == </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="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"All possibilities failed: issuing problem\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="5-dsh.html#SP14" class="function-link"><span class="function-syntax">Dash::failed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">list_of_possible_readings</span><span class="plain-syntax">, </span><span class="identifier-syntax">no_of_possible_readings</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">context</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind_needed</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_2">&#167;10.9.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1" class="paragraph-anchor"></a><b>&#167;10.9.1.1. </b>(4I) Invocations.
Invocations are the hardest nodes to check, but here at least we can forget
all about the ambiguities arising from multiple possibilities, and look at
just a single one.
</p>
<p class="commentary">In the event of an interesting problem message, we mark an invocation as being
interestingly problematic, but we keep going, since other invocations might be
better. Only if everything fails will we retrace our steps and actually throw
the problem.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4I) Verify an invocation</span><span class="named-paragraph-number">10.9.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4I)"</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">no_gross_problems_thrown_before</span><span class="plain-syntax"> = </span><span class="identifier-syntax">no_gross_problems_thrown</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">no_interesting_problems_thrown_before</span><span class="plain-syntax"> = </span><span class="identifier-syntax">no_interesting_problems_thrown</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">qualified</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-pi.html#SP5" class="function-link"><span class="function-syntax">ParseInvocations::parse_within_inv</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::set_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="constant-syntax">TESTED_DASHFLAG</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">id_body</span><span class="plain-syntax"> *</span><span class="identifier-syntax">idb</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_phrase_invoked</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">idb</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_kind_resulting</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">IDTypeData::get_return_kind</span><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">idb</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">type_data</span><span class="plain-syntax">)));</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> are the arguments of the right kind?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_2" class="named-paragraph-link"><span class="named-paragraph">Step (4I.a) Take care of arithmetic phrases</span><span class="named-paragraph-number">10.9.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">outcome</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_3" class="named-paragraph-link"><span class="named-paragraph">Step (4I.b) Take care of non-arithmetic phrases</span><span class="named-paragraph-number">10.9.1.1.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">outcome</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_4" class="named-paragraph-link"><span class="named-paragraph">Step (4I.c) Match type templates in the argument specifications</span><span class="named-paragraph-number">10.9.1.1.4</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">outcome</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_5" class="named-paragraph-link"><span class="named-paragraph">Step (4I.d) Match kinds in assignment phrases</span><span class="named-paragraph-number">10.9.1.1.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> if this evaluates something, is it a value of the right kind?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_6" class="named-paragraph-link"><span class="named-paragraph">Step (4I.e) Check kind of value returned</span><span class="named-paragraph-number">10.9.1.1.6</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> are there any special rules about invoking this phrase?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_7" class="named-paragraph-link"><span class="named-paragraph">Step (4I.f) Check any phrase options</span><span class="named-paragraph-number">10.9.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">outcome</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_8" class="named-paragraph-link"><span class="named-paragraph">Step (4I.g) Worry about self in say property of</span><span class="named-paragraph-number">10.9.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">outcome</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_9" class="named-paragraph-link"><span class="named-paragraph">Step (4I.h) Worry about using a phrase outside of the control structure it belongs to</span><span class="named-paragraph-number">10.9.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">outcome</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_10" class="named-paragraph-link"><span class="named-paragraph">Step (4I.i) Disallow any phrases which are now deprecated</span><span class="named-paragraph-number">10.9.1.1.10</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> should we mark to create a let variable here?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">consider_alternatives</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> = </span><a href="5-dsh.html#SP7" class="function-link"><span class="function-syntax">Dash::worst_case</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">outcome</span><span class="plain-syntax">, </span><a href="5-dsh.html#SP13" class="function-link"><span class="function-syntax">Dash::set_up_any_local_required</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> the outcome is now definitely known</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_11" class="named-paragraph-link"><span class="named-paragraph">Step (4I.j) Cope with failure</span><span class="named-paragraph-number">10.9.1.1.11</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="5-dsh.html#SP10_9_1_1_12" class="named-paragraph-link"><span class="named-paragraph">Step (4I.k) Cope with success</span><span class="named-paragraph-number">10.9.1.1.12</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1">&#167;10.9.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_1" class="paragraph-anchor"></a><b>&#167;10.9.1.1.1. </b>Most problem messages issued by (4I) will be of a sort called "interesting",
and will use the following macro.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">THIS_IS_AN_INTERESTING_PROBLEM</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">no_interesting_problems_thrown</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TEST_DASH_MODE</span><span class="plain-syntax">(</span><span class="constant-syntax">ISSUE_INTERESTING_PROBLEMS_DMODE</span><span class="plain-syntax">))</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_2" class="paragraph-anchor"></a><b>&#167;10.9.1.1.2. </b>"Polymorphic" here means that the phrase (i) produces a value, and (ii) that
the kind of this value depends on the kinds of its arguments. Inform supports
only a few polymorphic phrases, all clearly declared as such in the Standard
Rules, and they come in two sorts: those marked with a "polymorphism exception",
and those marked as "arithmetic operations".
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4I.a) Take care of arithmetic phrases</span><span class="named-paragraph-number">10.9.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4I.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">IDTypeData::arithmetic_operation</span><span class="plain-syntax">(</span><span class="identifier-syntax">idb</span><span class="plain-syntax">) == </span><span class="identifier-syntax">TOTAL_OPERATION</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_2_1" class="named-paragraph-link"><span class="named-paragraph">Step (4I.a.1) "Total P of O" has kind the kind of P</span><span class="named-paragraph-number">10.9.1.1.2.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">IDTypeData::is_arithmetic_phrase</span><span class="plain-syntax">(</span><span class="identifier-syntax">idb</span><span class="plain-syntax">)) </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_2_2" class="named-paragraph-link"><span class="named-paragraph">Step (4I.a.2) Dimension-check arithmetic phrases</span><span class="named-paragraph-number">10.9.1.1.2.2</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1">&#167;10.9.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_2_1" class="paragraph-anchor"></a><b>&#167;10.9.1.1.2.1. </b>For instance, the kind of "total carrying capacity of people in the Dining
Room" is a number, because the kind of the property "carrying capacity" is
"number".
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4I.a.1) "Total P of O" has kind the kind of P</span><span class="named-paragraph-number">10.9.1.1.2.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4I.a.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">P</span><span class="plain-syntax"> = </span><a href="4-inv.html#SP10" class="function-link"><span class="function-syntax">Invocations::get_token_as_parsed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><a href="5-dsh.html#SP9" class="function-link"><span class="function-syntax">Dash::typecheck_recursive</span></a><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="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">rv</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) &amp;&amp; (</span><a href="2-rvl.html#SP21" class="function-link"><span class="function-syntax">Rvalues::is_CONSTANT_construction</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">CON_property</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prn</span><span class="plain-syntax"> = </span><a href="2-rvl.html#SP3" class="function-link"><span class="function-syntax">Rvalues::to_property</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Properties::is_value_property</span><span class="plain-syntax">(</span><span class="identifier-syntax">prn</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_kind_resulting</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">ValueProperties::kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">prn</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_AN_INTERESTING_PROBLEM</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_TotalEitherOr</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this seems to be an attempt to total up an either/or property"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and by definition such a property has nothing to total."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_2_1_1" class="named-paragraph-link"><span class="named-paragraph">Fail the invocation for totalling something other than a property</span><span class="named-paragraph-number">10.9.1.1.2.1.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1_2">&#167;10.9.1.1.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_2_1_1" class="paragraph-anchor"></a><b>&#167;10.9.1.1.2.1.1. </b>The problem message here is to help what turns out to be quite a popular
mistake. (Perhaps we should simply implement column-totalling and be done
with it.)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Fail the invocation for totalling something other than a property</span><span class="named-paragraph-number">10.9.1.1.2.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4I.a.1) failed as nonproperty"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::get_construct</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_kind_of_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">CON_table_column</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_AN_INTERESTING_PROBLEM</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_TotalTableColumn</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this seems to be an attempt to total up the column of a table"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"whereas it's only legal to use 'total' for properties."</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">outcome</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1_2_1">&#167;10.9.1.1.2.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_2_2" class="paragraph-anchor"></a><b>&#167;10.9.1.1.2.2. </b>For instance, the following blocks an attempt to add a number to a text.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4I.a.2) Dimension-check arithmetic phrases</span><span class="named-paragraph-number">10.9.1.1.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4I.a.2)"</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">op_number</span><span class="plain-syntax"> = </span><span class="identifier-syntax">IDTypeData::arithmetic_operation</span><span class="plain-syntax">(</span><span class="identifier-syntax">idb</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Arithmetic operation &lt;op-%d&gt;\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">op_number</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">L</span><span class="plain-syntax">, *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_wanted</span><span class="plain-syntax">, *</span><span class="identifier-syntax">left_kind</span><span class="plain-syntax">, *</span><span class="identifier-syntax">right_kind</span><span class="plain-syntax">, *</span><span class="identifier-syntax">kind_produced</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_2_2_1" class="named-paragraph-link"><span class="named-paragraph">Work out the kinds of the operands, and what we want, and what we get</span><span class="named-paragraph-number">10.9.1.1.2.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"%u (~) %u = %u\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">left_kind</span><span class="plain-syntax">, </span><span class="identifier-syntax">right_kind</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind_produced</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kind_produced</span><span class="plain-syntax">) </span><span class="identifier-syntax">Node::set_kind_resulting</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind_produced</span><span class="plain-syntax">);</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="5-dsh.html#SP10_9_1_1_2_2_2" class="named-paragraph-link"><span class="named-paragraph">Fail the invocation for a dimensional problem</span><span class="named-paragraph-number">10.9.1.1.2.2.2</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1_2">&#167;10.9.1.1.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_2_2_1" class="paragraph-anchor"></a><b>&#167;10.9.1.1.2.2.1. </b>For the way this is actually worked out, see the section on "Dimensions".
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Work out the kinds of the operands, and what we want, and what we get</span><span class="named-paragraph-number">10.9.1.1.2.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">L</span><span class="plain-syntax"> = </span><a href="4-inv.html#SP7" class="function-link"><span class="function-syntax">Invocations::get_token</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</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">left_kind</span><span class="plain-syntax"> = </span><a href="5-dsh.html#SP12" class="function-link"><span class="function-syntax">Dash::fix_arithmetic_operand</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Dimensions::arithmetic_op_is_unary</span><span class="plain-syntax">(</span><span class="identifier-syntax">op_number</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">right_kind</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><a href="4-inv.html#SP7" class="function-link"><span class="function-syntax">Invocations::get_token</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</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">right_kind</span><span class="plain-syntax"> = </span><a href="5-dsh.html#SP12" class="function-link"><span class="function-syntax">Dash::fix_arithmetic_operand</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</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">left_kind</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Kinds::Behaviour::is_quasinumerical</span><span class="plain-syntax">(</span><span class="identifier-syntax">left_kind</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">right_kind</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Kinds::Behaviour::is_quasinumerical</span><span class="plain-syntax">(</span><span class="identifier-syntax">right_kind</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind_produced</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind_produced</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::Dimensions::arithmetic_on_kinds</span><span class="plain-syntax">(</span><span class="identifier-syntax">left_kind</span><span class="plain-syntax">, </span><span class="identifier-syntax">right_kind</span><span class="plain-syntax">, </span><span class="identifier-syntax">op_number</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind_wanted</span><span class="plain-syntax"> = </span><span class="identifier-syntax">kind_needed</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1_2_2">&#167;10.9.1.1.2.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_2_2_2" class="paragraph-anchor"></a><b>&#167;10.9.1.1.2.2.2. </b>Note that "value" &mdash; the vaguest kind of all &mdash; might come up here as
a result of some problem evaluating one of the operands, which has already been
reported in a problem message; so we only issue this problem message when
L and R are more definite.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Fail the invocation for a dimensional problem</span><span class="named-paragraph-number">10.9.1.1.2.2.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">left_kind</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">left_kind</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_value</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">right_kind</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">right_kind</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_AN_INTERESTING_PROBLEM</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">"So the inv subtree is:\n$T\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="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_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">left_kind</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(5, </span><span class="identifier-syntax">right_kind</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">op_number</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">PLUS_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"adding"</span><span class="plain-syntax">); </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(7, </span><span class="string-syntax">"to"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">MINUS_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"subtracting"</span><span class="plain-syntax">); </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(7, </span><span class="string-syntax">"from"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TIMES_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"multiplying"</span><span class="plain-syntax">); </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(7, </span><span class="string-syntax">"by"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">DIVIDE_OPERATION:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">REMAINDER_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"dividing"</span><span class="plain-syntax">); </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(7, </span><span class="string-syntax">"by"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">APPROXIMATION_OPERATION:</span><span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"rounding"</span><span class="plain-syntax">); </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(7, </span><span class="string-syntax">"to"</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">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_BadArithmetic</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 that seems to involve %6 %4 ('%2') %7 %5 ('%3'), "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which is not good arithmetic."</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="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1_2_2">&#167;10.9.1.1.2.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_3" class="paragraph-anchor"></a><b>&#167;10.9.1.1.3. </b>This is the general case: almost all phrases fall into this category,
including all phrases created outside the Standard Rules.
</p>
<p class="commentary">The deal is simply that every argument must match its specification. For
instance, if <span class="extract"><span class="extract-syntax">inv</span></span> is an invocation of this phrase:
</p>
<blockquote>
<p>To truncate (L - a list of values) to (N - a number) entries: ...</p>
</blockquote>
<p class="commentary">...then token 0 must match "list of values", and token 1 must match "number".
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4I.b) Take care of non-arithmetic phrases</span><span class="named-paragraph-number">10.9.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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">IDTypeData::is_arithmetic_phrase</span><span class="plain-syntax">(</span><span class="identifier-syntax">idb</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_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4I.b)"</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">exit_at_once</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">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><a href="4-inv.html#SP6" class="function-link"><span class="function-syntax">Invocations::get_no_tokens</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(4I.b) trying argument %d (prior to this, best possible: %d)\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">outcome</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-inv.html#SP13" class="function-link"><span class="function-syntax">Invocations::set_token_check_to_do</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_3_1" class="named-paragraph-link"><span class="named-paragraph">Type-check a single token from the list</span><span class="named-paragraph-number">10.9.1.1.3.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">exit_at_once</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">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(4I.b) argument type matching %s\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">outcome</span><span class="plain-syntax">==</span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">)?</span><span class="string-syntax">"failed"</span><span class="plain-syntax">:</span><span class="string-syntax">"passed"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1">&#167;10.9.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_3_1" class="paragraph-anchor"></a><b>&#167;10.9.1.1.3.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Type-check a single token from the list</span><span class="named-paragraph-number">10.9.1.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="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ith_spec</span><span class="plain-syntax"> = </span><span class="identifier-syntax">idb</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">type_data</span><span class="plain-syntax">.</span><span class="identifier-syntax">token_sequence</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="identifier-syntax">to_match</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">idb</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">type_data</span><span class="plain-syntax">.</span><span class="identifier-syntax">token_sequence</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="identifier-syntax">construct</span><span class="plain-syntax"> == </span><span class="identifier-syntax">KIND_NAME_IDTC</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Cautiously reparse this as a name of a kind of value</span><span class="named-paragraph-number">10.9.1.1.3.1.1</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">save_kcm</span><span class="plain-syntax"> = </span><span class="identifier-syntax">kind_checker_mode</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind_checker_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">MATCH_KIND_VARIABLES_AS_UNIVERSAL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">create</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="constant-syntax">BEGIN_DASH_MODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DASH_MODE_EXIT</span><span class="plain-syntax">(</span><span class="constant-syntax">ISSUE_PROBLEMS_DMODE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DASH_MODE_CREATE</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">create</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">rv</span><span class="plain-syntax"> = </span><a href="5-dsh.html#SP9" class="function-link"><span class="function-syntax">Dash::typecheck_recursive</span></a><span class="plain-syntax">(</span><a href="4-inv.html#SP7" class="function-link"><span class="function-syntax">Invocations::get_token</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">), </span><span class="identifier-syntax">context</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="constant-syntax">END_DASH_MODE</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">rv</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">NEVER_MATCH:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(4I.b) on %W failed at token %d\n"</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="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP4" class="function-link"><span class="function-syntax">Dash::problems_have_been_issued</span></a><span class="plain-syntax">()) </span><span class="identifier-syntax">exit_at_once</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">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SOMETIMES_MATCH:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(4I.b) on %W qualified at token %d\n"</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="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-inv.html#SP13" class="function-link"><span class="function-syntax">Invocations::set_token_check_to_do</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">ith_spec</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">qualified</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">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind_checker_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">save_kcm</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">create</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">CompileBlocksAndLines::compiling_single_line_block</span><span class="plain-syntax">()) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">IDTypeData::is_a_let_assignment</span><span class="plain-syntax">(</span><span class="identifier-syntax">idb</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_AN_INTERESTING_PROBLEM</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">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_LetCreatedInIf</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 when a temporary value is created "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"inside an 'if ..., ...' or an 'otherwise ...', it only "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"lasts until that line is complete - which means it "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"can never be used for anything, because it goes away "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"as soon as created. To make something more durable, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"create it before the 'if' or 'otherwise'."</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="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-inv.html#SP14" class="function-link"><span class="function-syntax">Invocations::set_token_variable_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">create</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="5-dsh.html#SP10_9_1_1_3">&#167;10.9.1.1.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_3_1_1" class="paragraph-anchor"></a><b>&#167;10.9.1.1.3.1.1. </b>The following is a delicate manoeuvre, but luckily it takes action only very
rarely and in very specific circumstances. We allow a very limited use
of second-order logic in using the name of a kind as if it were a value,
even though Inform is really not set up for this. The point is to allow:
</p>
<blockquote>
<p>let (name - nonexisting variable) be (K - name of kind of word value);</p>
</blockquote>
<p class="commentary">where the "K" parameter would match (1) but not (2), (3) or (4) from:
</p>
<blockquote>
<p>(1) let X be a number;</p>
</blockquote>
<blockquote>
<p>(2) let X be text;</p>
</blockquote>
<blockquote>
<p>(3) let X be 21;</p>
</blockquote>
<blockquote>
<p>(4) let X be \{1, 2, 3\};</p>
</blockquote>
<p class="commentary">What all of this has to do with being <span class="extract"><span class="extract-syntax">UNKNOWN_NT</span></span> is that text parsed in the
expectation of a value will usually not recognise something like "a list
of numbers", so that would be here as <span class="extract"><span class="extract-syntax">UNKNOWN_NT</span></span>. We take the otherwise
unheard-of measure of reparsing the text, but we only impose the result
if the match can definitely be made successfully.
</p>
<p class="commentary">We have to be very careful to take action only on (5) and not (6):
</p>
<blockquote>
<p>(5) let L be a list of scenes;</p>
</blockquote>
<blockquote>
<p>(6) let L be the list of scenes;</p>
</blockquote>
<ul class="items"><li>(5) creates L as an empty list, whereas (6) creates it as the list made up
of all scenes. We can tell these apart since (6) will have a valid phrase
in <span class="extract"><span class="extract-syntax">ith_token</span></span>, an invocation of "the list of K", whereas (5) won't.
</li></ul>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Cautiously reparse this as a name of a kind of value</span><span class="named-paragraph-number">10.9.1.1.3.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEVER_MATCH</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">ith_token</span><span class="plain-syntax"> = </span><a href="4-inv.html#SP10" class="function-link"><span class="function-syntax">Invocations::get_token_as_parsed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(4I.b) thinking about reparsing: $P\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">ith_token</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">warned_already</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">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">ith_token</span><span class="plain-syntax">, </span><span class="identifier-syntax">AMBIGUITY_NT</span><span class="plain-syntax">)) </span><span class="identifier-syntax">ith_token</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ith_token</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">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">ith_token</span><span class="plain-syntax">, </span><span class="identifier-syntax">UNKNOWN_NT</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><a href="2-spc.html#SP3" class="function-link"><span class="function-syntax">Specifications::is_description</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ith_token</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><a href="2-rvl.html#SP21" class="function-link"><span class="function-syntax">Rvalues::is_CONSTANT_construction</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ith_token</span><span class="plain-syntax">, </span><span class="identifier-syntax">CON_property</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><a href="2-spc.html#SP2" class="function-link"><span class="function-syntax">Specifications::is_kind_like</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ith_token</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">IDTypeData::is_a_let_assignment</span><span class="plain-syntax">(</span><span class="identifier-syntax">idb</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">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">ith_token</span><span class="plain-syntax">, </span><span class="identifier-syntax">PHRASE_TO_DECIDE_VALUE_NT</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">ith_token</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">reparsed</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;s-type-expression&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="identifier-syntax">reparsed</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;rp&gt;&gt;</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-spc.html#SP2" class="function-link"><span class="function-syntax">Specifications::is_kind_like</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">reparsed</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">reparsed</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">K</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp; (</span><span class="function-syntax">&lt;k-kind&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">))) </span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;rp&gt;&gt;</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax"> == </span><span class="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;value-property-name&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">ValueProperties::coincides_with_kind</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;&lt;rp&gt;&gt;</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ValueProperties::kind</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;&lt;rp&gt;&gt;</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(4I.b) reparsed as: %u (vs spec $P)\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">ith_spec</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">K</span><span class="plain-syntax">) &amp;&amp; (</span><a href="2-spc.html#SP2" class="function-link"><span class="function-syntax">Specifications::is_kind_like</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ith_spec</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ikind</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ith_spec</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Behaviour::definite</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">Kinds::compatible</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">ikind</span><span class="plain-syntax">) == </span><span class="identifier-syntax">ALWAYS_MATCH</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(4I.b) allows name-of token: $P\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">reparsed</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-inv.html#SP10" class="function-link"><span class="function-syntax">Invocations::set_token_as_parsed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">Node::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">reparsed</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ALWAYS_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">warned_already</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">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_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">ikind</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_NameOfKindMismatch</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 although '%2' is the name of a kind, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"it isn't the name of a kind of %3, which this phrase needs."</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="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">warned_already</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">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_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">ikind</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_BadLocalKOV</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 although '%2' is the name of a kind, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"it isn't a definite kind and is instead a general "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"description which might apply to many different kinds. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"(For example, 'let R be a relation' is vague because it doesn't "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"make clear what R will relate - 'let R be a relation of numbers' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"would be fine.)"</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="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ith_token</span><span class="plain-syntax"> = </span><a href="4-inv.html#SP10" class="function-link"><span class="function-syntax">Invocations::get_token_as_parsed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((!</span><a href="2-spc.html#SP2" class="function-link"><span class="function-syntax">Specifications::is_kind_like</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ith_token</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">warned_already</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</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_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">ith_token</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_NameOfKindIsnt</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 although '%2' does have a meaning, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"it isn't the name of a kind, which this phrase needs."</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="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1_3_1">&#167;10.9.1.1.3.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_4" class="paragraph-anchor"></a><b>&#167;10.9.1.1.4. </b>For templates and the meaning of <span class="extract"><span class="extract-syntax">kind_checker_mode</span></span>, see the section
on "Kind Checking". But basically this handles the matching of an invocation
against a definition like:
</p>
<blockquote>
<p>To remove (N - value of kind K) from (L - list of Ks): ...</p>
</blockquote>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4I.c) Match type templates in the argument specifications</span><span class="named-paragraph-number">10.9.1.1.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4I.c)"</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">exit_at_once</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">kind_variable_declaration</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kvd_marker</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LAST_OBJECT</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_variable_declaration</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">IDTypeData::contains_variables</span><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">idb</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">type_data</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind_variable_declaration</span><span class="plain-syntax"> *</span><span class="identifier-syntax">save_most_recent_interpretation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">most_recent_interpretation</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">pass</span><span class="plain-syntax">, </span><span class="identifier-syntax">save_kcm</span><span class="plain-syntax"> = </span><span class="identifier-syntax">kind_checker_mode</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">pass</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="identifier-syntax">pass</span><span class="plain-syntax"> &lt;= </span><span class="constant-syntax">2</span><span class="plain-syntax">; </span><span class="identifier-syntax">pass</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(4I.c) prototype check pass %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pass</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">Log::aspect_switched_on</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING_DA</span><span class="plain-syntax">)) </span><span class="identifier-syntax">Latticework::show_variables</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">pass</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">kind_checker_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">MATCH_KIND_VARIABLES_INFERRING_VALUES</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">kind_checker_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">MATCH_KIND_VARIABLES_AS_VALUES</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="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><a href="4-inv.html#SP6" class="function-link"><span class="function-syntax">Invocations::get_no_tokens</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Kt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">IDTypeData::token_kind</span><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">idb</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">type_data</span><span class="plain-syntax">), </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Kt</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">idb</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">type_data</span><span class="plain-syntax">.</span><span class="identifier-syntax">token_sequence</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="identifier-syntax">construct</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEW_LOCAL_IDTC</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">token_spec</span><span class="plain-syntax"> = </span><a href="4-inv.html#SP10" class="function-link"><span class="function-syntax">Invocations::get_token_as_parsed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_read</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">token_spec</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Token %d: $P: kind %u: template %u\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">token_spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind_read</span><span class="plain-syntax">, </span><span class="identifier-syntax">Kt</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">Kinds::compatible</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_read</span><span class="plain-syntax">, </span><span class="identifier-syntax">Kt</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">NEVER_MATCH:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(4I.c) failed at token %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP4" class="function-link"><span class="function-syntax">Dash::problems_have_been_issued</span></a><span class="plain-syntax">()) </span><span class="identifier-syntax">exit_at_once</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">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SOMETIMES_MATCH:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> = </span><a href="5-dsh.html#SP7" class="function-link"><span class="function-syntax">Dash::worst_case</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">outcome</span><span class="plain-syntax">, </span><span class="identifier-syntax">SOMETIMES_MATCH</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> we won't use </span><span class="extract"><span class="extract-syntax">with_qualifications</span></span><span class="comment-syntax"> &mdash; we don't know exactly what they are</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(4I.c) dropping to sometimes at token %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">ALWAYS_MATCH:</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">exit_at_once</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">exit_at_once</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">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">pass</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(4I.c) prototype check passed\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">most_recent_interpretation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind_variable_declaration</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kvdm</span><span class="plain-syntax"> = </span><span class="identifier-syntax">kvd_marker</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">kvdm</span><span class="plain-syntax">) </span><span class="identifier-syntax">kvdm</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEXT_OBJECT</span><span class="plain-syntax">(</span><span class="identifier-syntax">kvdm</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind_variable_declaration</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">kvdm</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FIRST_OBJECT</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_variable_declaration</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">kvdm</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kvdm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">most_recent_interpretation</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">most_recent_interpretation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">kvdm</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kvdm</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEXT_OBJECT</span><span class="plain-syntax">(</span><span class="identifier-syntax">kvdm</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind_variable_declaration</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="identifier-syntax">kind_checker_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">save_kcm</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">outcome</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) </span><span class="identifier-syntax">Node::set_kind_variable_declarations</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">most_recent_interpretation</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">most_recent_interpretation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">save_most_recent_interpretation</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::contains</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_kind_resulting</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">), </span><span class="identifier-syntax">CON_KIND_VARIABLE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">changed</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">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::substitute</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_kind_resulting</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">), </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">changed</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">changed</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(4I.c) amended kind returned to %u\n"</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">Node::set_kind_resulting</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</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">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_4_1" class="named-paragraph-link"><span class="named-paragraph">Disallow an undeclared kind variable as return kind</span><span class="named-paragraph-number">10.9.1.1.4.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1">&#167;10.9.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_4_1" class="paragraph-anchor"></a><b>&#167;10.9.1.1.4.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Disallow an undeclared kind variable as return kind</span><span class="named-paragraph-number">10.9.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="constant-syntax">THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM</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_wording</span><span class="plain-syntax">(2, </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">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">BelievedImpossible</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 line %1, you seem to be using '%2' to produce a value, but "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"it's not clear what kind of value this will be. It seems to use "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"a phrase which has been declared wrongly, because the kind it decides "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"is given only by a symbol which isn't otherwise defined."</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">outcome</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1_4">&#167;10.9.1.1.4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_5" class="paragraph-anchor"></a><b>&#167;10.9.1.1.5. </b>Although we don't implement it with prototypes as such, there's a
similar constraint on the arguments of an assignment. If we are checking an
invocation against:
</p>
<blockquote>
<p>To let (t - existing variable) be (u - value): ...</p>
</blockquote>
<p class="commentary">then we have so far checked that argument 0 is indeed the name of a variable
which already exists. But suppose the invocation is
</p>
<blockquote>
<p>let N be "there'll be no mutant enemy";</p>
</blockquote>
<p class="commentary">where N has already been created as a variable of kind "number". This clearly
has to be rejected, as it would violate type-safety. Step (4I.d) therefore
makes sure that all assignments match the kind of the new value against the
kind of the storage item to which it is being written.
</p>
<p class="commentary">A reasonable question might be why we don't implement this using the prototype
system of (4I.c), thus removing a rule from this already-complex algorithm, say by
</p>
<blockquote>
<p>To let (var - K variable) be (val - value of kind K): ...</p>
</blockquote>
<p class="commentary">The answer is that this would indeed work nicely for valid source text, but that
we would get less helpful problem messages in the all-too-likely case of a
mistake having been made.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4I.d) Match kinds in assignment phrases</span><span class="named-paragraph-number">10.9.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="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4I.d)"</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">IDTypeData::is_assignment_phrase</span><span class="plain-syntax">(</span><span class="identifier-syntax">idb</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">target</span><span class="plain-syntax"> = </span><a href="4-inv.html#SP10" class="function-link"><span class="function-syntax">Invocations::get_token_as_parsed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">new_value</span><span class="plain-syntax"> = </span><a href="4-inv.html#SP10" class="function-link"><span class="function-syntax">Invocations::get_token_as_parsed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="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">target_spec</span><span class="plain-syntax"> = </span><span class="identifier-syntax">idb</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">type_data</span><span class="plain-syntax">.</span><span class="identifier-syntax">token_sequence</span><span class="plain-syntax">[0].</span><span class="identifier-syntax">to_match</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">new_value_spec</span><span class="plain-syntax"> = </span><span class="identifier-syntax">idb</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">type_data</span><span class="plain-syntax">.</span><span class="identifier-syntax">token_sequence</span><span class="plain-syntax">[1].</span><span class="identifier-syntax">to_match</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax"> = </span><a href="2-lvl.html#SP3" class="function-link"><span class="function-syntax">Lvalues::get_local_variable_if_any</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">target</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">LocalVariables::protected</span><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEVER_MATCH</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">Kinds::Behaviour::is_object</span><span class="plain-syntax">(</span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">target_spec</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_5_1" class="named-paragraph-link"><span class="named-paragraph">Step (4I.d.1) Police an assignment to an object</span><span class="named-paragraph-number">10.9.1.1.5.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">idb</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">type_data</span><span class="plain-syntax">.</span><span class="identifier-syntax">token_sequence</span><span class="plain-syntax">[0].</span><span class="identifier-syntax">construct</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEW_LOCAL_IDTC</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_5_2" class="named-paragraph-link"><span class="named-paragraph">Step (4I.d.2) Police an assignment to a storage item</span><span class="named-paragraph-number">10.9.1.1.5.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1">&#167;10.9.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_5_1" class="paragraph-anchor"></a><b>&#167;10.9.1.1.5.1. </b>It doesn't always look like an assignment, but a phrase such as:
</p>
<blockquote>
<p>change the Marble Door to open;</p>
</blockquote>
<p class="commentary">has similar type-checking needs.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4I.d.1) Police an assignment to an object</span><span class="named-paragraph-number">10.9.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4I.d.1)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">target_wo</span><span class="plain-syntax"> = </span><a href="2-rvl.html#SP6" class="function-link"><span class="function-syntax">Rvalues::to_object_instance</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">target</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prn</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">make_check</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">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_kind_of_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">new_value_spec</span><span class="plain-syntax">), </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_5_1_1" class="named-paragraph-link"><span class="named-paragraph">Maybe we're changing an object to a value of a kind coinciding with a property</span><span class="named-paragraph-number">10.9.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><a href="2-rvl.html#SP21" class="function-link"><span class="function-syntax">Rvalues::is_CONSTANT_construction</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new_value_spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">CON_property</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_5_1_2" class="named-paragraph-link"><span class="named-paragraph">Maybe we're changing an object to a named either/or property or condition state</span><span class="named-paragraph-number">10.9.1.1.5.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">make_check</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_1_5_1_3" class="named-paragraph-link"><span class="named-paragraph">Check that the property exists and that the object is allowed to have it</span><span class="named-paragraph-number">10.9.1.1.5.1.3</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1_5">&#167;10.9.1.1.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_5_1_1" class="paragraph-anchor"></a><b>&#167;10.9.1.1.5.1.1. </b>There are actually two definitions like this in the Standard Rules:
</p>
<blockquote>
<p>(1) To change (o - object) to (w - value): ...</p>
</blockquote>
<blockquote>
<p>(2) To change (o - object) to (p - property): ...</p>
</blockquote>
<p class="commentary">Here's the code for (1), the less obvious case. This is needed for something like
</p>
<blockquote>
<p>change the canvas to blue;</p>
</blockquote>
<p class="commentary">where "blue" is a constant colour, and "colour" is both a kind and also a
property. (This case really is an assignment &mdash; it assigns the value "blue"
to the colour property of the canvas.)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Maybe we're changing an object to a value of a kind coinciding with a property</span><span class="named-paragraph-number">10.9.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="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4I.d.1.a)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><a href="2-rvl.html#SP5" class="function-link"><span class="function-syntax">Rvalues::to_instance</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new_value</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">I</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEVER_MATCH</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">prn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Properties::property_with_same_name_as</span><span class="plain-syntax">(</span><span class="identifier-syntax">Instances::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">prn</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEVER_MATCH</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">make_check</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="5-dsh.html#SP10_9_1_1_5_1">&#167;10.9.1.1.5.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_5_1_2" class="paragraph-anchor"></a><b>&#167;10.9.1.1.5.1.2. </b>And here's the simpler case, (2). A small quirk here is that it will also pick
up "change the Atrium to spiffy" in the following:
</p>
<blockquote>
<p>Atrium is a room. The Atrium can be spiffy, cool or lame.</p>
</blockquote>
<blockquote>
<p>When play begins: change the Atrium to spiffy.</p>
</blockquote>
<p class="commentary">...where "spiffy" is deemed a property rather than a constant value of a kind
because of the way the condition of the Atrium is declared. This is a little
bit horrid, but works fine in practice. (If we try to accommodate this case
within (1.2.4.1a), which might seem more logical, we run into trouble because
the property name is cast to a property value of <span class="extract"><span class="extract-syntax">self</span></span> when being typechecked
against "value".)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Maybe we're changing an object to a named either/or property or condition state</span><span class="named-paragraph-number">10.9.1.1.5.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4I.d.1.b)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-rvl.html#SP21" class="function-link"><span class="function-syntax">Rvalues::is_CONSTANT_construction</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">CON_property</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">prn</span><span class="plain-syntax"> = </span><a href="2-rvl.html#SP3" class="function-link"><span class="function-syntax">Rvalues::to_property</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new_value</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-dsc.html#SP8" class="function-link"><span class="function-syntax">Descriptions::number_of_adjectives_applied_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new_value</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">adjective</span><span class="plain-syntax"> *</span><span class="identifier-syntax">aph</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AdjectivalPredicates::to_adjective</span><span class="plain-syntax">(</span><a href="2-dsc.html#SP8" class="function-link"><span class="function-syntax">Descriptions::first_unary_predicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new_value</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">AdjectiveAmbiguity::has_enumerative_meaning</span><span class="plain-syntax">(</span><span class="identifier-syntax">aph</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">prn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Properties::property_with_same_name_as</span><span class="plain-syntax">(</span><span class="identifier-syntax">Instances::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">AdjectiveAmbiguity::has_enumerative_meaning</span><span class="plain-syntax">(</span><span class="identifier-syntax">aph</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">AdjectiveAmbiguity::has_either_or_property_meaning</span><span class="plain-syntax">(</span><span class="identifier-syntax">aph</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">prn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AdjectiveAmbiguity::has_either_or_property_meaning</span><span class="plain-syntax">(</span><span class="identifier-syntax">aph</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">make_check</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="5-dsh.html#SP10_9_1_1_5_1">&#167;10.9.1.1.5.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_5_1_3" class="paragraph-anchor"></a><b>&#167;10.9.1.1.5.1.3. </b>We do something quite interesting here, if the object is not explicitly
named: we deliberately allow an assignment which may not be type-safe, and
without even dropping to the "sometimes" level. This is for phrases like so:
</p>
<blockquote>
<p>change the item to closed;</p>
</blockquote>
<p class="commentary">Here the author seems to know what he's doing, and is pretty sure that the
current contents of "item" will accept closure. All we can prove is that
"item" contains an object (or perhaps <span class="extract"><span class="extract-syntax">nothing</span></span>, the non-object). But
we allow the assignment because it will compile to code which will issue
a helpful run-time problem message if it goes wrong.
</p>
<p class="commentary">Now that "change" has been removed, as of January 2011, it looks as if
this case in the type-checker is never exercised.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check that the property exists and that the object is allowed to have it</span><span class="named-paragraph-number">10.9.1.1.5.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">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Property appears to be $Y\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">prn</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">prn</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_AN_INTERESTING_PROBLEM</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_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">target</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">new_value</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">BelievedImpossible</span><span class="plain-syntax">)); </span><span class="comment-syntax"> the parser seems not to allow these</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, asking to change the object '%2'. This would "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"make sense if '%3' were an either/or property like 'open' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"(or perhaps a named property value like 'blue') - but it "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"isn't, so the change makes no sense."</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="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">target_wo</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">prn</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">PropertyPermissions::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">Instances::as_subject</span><span class="plain-syntax">(</span><span class="identifier-syntax">target_wo</span><span class="plain-syntax">), </span><span class="identifier-syntax">prn</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_AN_INTERESTING_PROBLEM</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_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">target</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_property</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">prn</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">BelievedImpossible</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 '%2' is not allowed to have the property '%3'."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1_5_1">&#167;10.9.1.1.5.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_5_2" class="paragraph-anchor"></a><b>&#167;10.9.1.1.5.2. </b>This is more straightforward, with just a tiny glitch to make the rules
tougher on variables which hold text to be parsed. (Because the regular rules
for exchanging the subtly different forms of text which a double-quoted
literal can mean are too generous.)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4I.d.2) Police an assignment to a storage item</span><span class="named-paragraph-number">10.9.1.1.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="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_wanted</span><span class="plain-syntax">, *</span><span class="identifier-syntax">kind_found</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Check assignment of $P to $P\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">new_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">target</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><a href="2-lvl.html#SP8" class="function-link"><span class="function-syntax">Lvalues::get_storage_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">target_spec</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">LOCAL_VARIABLE_NT:</span><span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"the name of"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PROPERTY_VALUE_NT:</span><span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"a property whose kind of value is"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NONLOCAL_VARIABLE_NT:</span><span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"a variable whose kind of value is"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TABLE_ENTRY_NT:</span><span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"a table entry whose kind of value is"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LIST_ENTRY_NT:</span><span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"an entry in a list whose kind of value is"</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="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(6, </span><span class="string-syntax">"a stored value holding"</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">kind_wanted</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">target</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind_found</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new_value</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">new_invl</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_value</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">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">new_invl</span><span class="plain-syntax">, </span><span class="identifier-syntax">INVOCATION_LIST_NT</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">new_inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_ALTERNATIVES</span><span class="plain-syntax">(</span><span class="identifier-syntax">new_inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">new_invl</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::test_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new_inv</span><span class="plain-syntax">, </span><span class="constant-syntax">PASSED_DASHFLAG</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">new_inv</span><span class="plain-syntax">) </span><span class="identifier-syntax">kind_found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_kind_resulting</span><span class="plain-syntax">(</span><span class="identifier-syntax">new_inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Kinds found: %u, wanted: %u\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind_found</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind_wanted</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">K_understanding</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_wanted</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_understanding</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_found</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_understanding</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> || (</span><span class="identifier-syntax">Kinds::compatible</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_found</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind_wanted</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_AN_INTERESTING_PROBLEM</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_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">target</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(3, </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">target</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">new_value</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(5, </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new_value</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_ChangeToWrongValue</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 '%2' is supposed to be "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"%6 %3, so it cannot be set equal to %4, whose kind is %5."</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="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1_5">&#167;10.9.1.1.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_6" class="paragraph-anchor"></a><b>&#167;10.9.1.1.6. </b>Suppose we have something like this:
</p>
<blockquote>
<p>award the current action points;</p>
</blockquote>
<p class="commentary">and we are typechecking <span class="extract"><span class="extract-syntax">found</span></span> as "the current action" (a phrase deciding
a value) against <span class="extract"><span class="extract-syntax">expected</span></span> as "number", the parameter expected in
"award (N - a number) points".
</p>
<p class="commentary">No matter how peculiar this invocation of <span class="extract"><span class="extract-syntax">found</span></span> was, we have now successfully
worked out the kind of the value it would return if compiled, and this is
stored in <span class="extract"><span class="extract-syntax">inv-&gt;kind_resulting</span></span>. We now check to see if this matches the kind
expected &mdash; in this example, it won't, because a stored action does not cast
to a number.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4I.e) Check kind of value returned</span><span class="named-paragraph-number">10.9.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4I.e)"</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">outcome_test</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ALWAYS_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kind_needed</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Checking returned %u against desired %u\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::get_kind_resulting</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">), </span><span class="identifier-syntax">kind_needed</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">outcome_test</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::compatible</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::get_kind_resulting</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">), </span><span class="identifier-syntax">kind_needed</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">outcome_test</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">NEVER_MATCH:</span><span class="plain-syntax"> </span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SOMETIMES_MATCH:</span><span class="plain-syntax"> </span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> = </span><a href="5-dsh.html#SP7" class="function-link"><span class="function-syntax">Dash::worst_case</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">outcome</span><span class="plain-syntax">, </span><span class="identifier-syntax">SOMETIMES_MATCH</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1">&#167;10.9.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_7" class="paragraph-anchor"></a><b>&#167;10.9.1.1.7. </b>The final stage in type-checking a phrase is to ensure that any phrase
options are properly used.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4I.f) Check any phrase options</span><span class="named-paragraph-number">10.9.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4I.f)"</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">outcome</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Node::get_phrase_options_invoked</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cso</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PhraseOptions::parse_invoked_options</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inv</span><span class="plain-syntax">, (</span><span class="identifier-syntax">TEST_DASH_MODE</span><span class="plain-syntax">(</span><span class="constant-syntax">ISSUE_PROBLEMS_DMODE</span><span class="plain-syntax">))?</span><span class="identifier-syntax">FALSE: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">cso</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1">&#167;10.9.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_8" class="paragraph-anchor"></a><b>&#167;10.9.1.1.8. </b>A say phrase which involves a property of something implicitly changes
the scope for any vaguely described properties within the text supplied
as that property (if it is indeed text). We have to mark any such
property, and any such say. For instance, suppose we are typechecking
</p>
<blockquote>
<p>(1) "Oh, look: [initial appearance of the escritoire]"</p>
</blockquote>
<p class="commentary">and the initial appearance in question is:
</p>
<blockquote>
<p>(2) "A small, portable writing desk holding up to [carrying capacity] letters."</p>
</blockquote>
<p class="commentary">Printing text (2), it's important for the <span class="extract"><span class="extract-syntax">self</span></span> object to be the
escritoire, which might not be the case otherwise; so during the printing
of (1), we have to change <span class="extract"><span class="extract-syntax">self</span></span> temporarily and restore it afterwards.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4I.g) Worry about self in say property of</span><span class="named-paragraph-number">10.9.1.1.8</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4I.g)"</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">IDTypeData::is_a_say_phrase</span><span class="plain-syntax">(</span><span class="identifier-syntax">idb</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-inv.html#SP6" class="function-link"><span class="function-syntax">Invocations::get_no_tokens</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">) == </span><span class="constant-syntax">1</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="2-lvl.html#SP8" class="function-link"><span class="function-syntax">Lvalues::get_storage_form</span></a><span class="plain-syntax">(</span><a href="4-inv.html#SP10" class="function-link"><span class="function-syntax">Invocations::get_token_as_parsed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">PROPERTY_VALUE_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><a href="4-inv.html#SP10" class="function-link"><span class="function-syntax">Invocations::get_token_as_parsed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">), </span><span class="identifier-syntax">record_as_self_ANNOT</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-inv.html#SP4" class="function-link"><span class="function-syntax">Invocations::mark_to_save_self</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1">&#167;10.9.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_9" class="paragraph-anchor"></a><b>&#167;10.9.1.1.9. </b>Some phrases are defined with a notation making them allowable only inside
loops, or other control structures; for instance,
</p>
<blockquote>
<p>To break -- in loop: ...</p>
</blockquote>
<p class="commentary">And here is where we check that "break" is indeed used only in a loop.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4I.h) Worry about using a phrase outside of the control structure it belongs to</span><span class="named-paragraph-number">10.9.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="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4I.h)"</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">idb</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">required</span><span class="plain-syntax"> = </span><span class="identifier-syntax">IDTypeData::only_in</span><span class="plain-syntax">(</span><span class="identifier-syntax">idb</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">required</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">Wide::cmp</span><span class="plain-syntax">(</span><span class="identifier-syntax">required</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"loop"</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Required to be inside loop body\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">CodeBlocks::inside_a_loop_body</span><span class="plain-syntax">() == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_AN_INTERESTING_PROBLEM</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">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_CantUseOutsideLoop</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">"%1 makes sense only inside a 'while' or 'repeat' loop."</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="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">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Required to be inside block '%w'\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">required</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">actual</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CodeBlocks::name_of_current_block</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">actual</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Wide::cmp</span><span class="plain-syntax">(</span><span class="identifier-syntax">actual</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"unless"</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="identifier-syntax">actual</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="string-syntax">"if"</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">actual</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">Wide::cmp</span><span class="plain-syntax">(</span><span class="identifier-syntax">required</span><span class="plain-syntax">, </span><span class="identifier-syntax">actual</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_AN_INTERESTING_PROBLEM</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">required</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_CantUseOutsideStructure</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">"%1 makes sense only inside a '%2' block."</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="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1">&#167;10.9.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_10" class="paragraph-anchor"></a><b>&#167;10.9.1.1.10. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4I.i) Disallow any phrases which are now deprecated</span><span class="named-paragraph-number">10.9.1.1.10</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">global_compilation_settings</span><span class="plain-syntax">.</span><span class="identifier-syntax">no_deprecated_features</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4I.i)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">idb</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">idb</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">type_data</span><span class="plain-syntax">.</span><span class="identifier-syntax">now_deprecated</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_AN_INTERESTING_PROBLEM</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">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">BelievedImpossible</span><span class="plain-syntax">)); </span><span class="comment-syntax"> too moving a target to test</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">"'%1' uses a phrase which is now deprecated: you should rephrase "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"to avoid the need for it. I'd normally allow this, but you have "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the 'Use no deprecated features' option set."</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="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1">&#167;10.9.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_11" class="paragraph-anchor"></a><b>&#167;10.9.1.1.11. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4I.j) Cope with failure</span><span class="named-paragraph-number">10.9.1.1.11</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4I.j) failure"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">no_gross_problems_thrown</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">no_gross_problems_thrown_before</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::set_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="constant-syntax">GROSSLY_FAILED_DASHFLAG</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">no_interesting_problems_thrown</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">no_interesting_problems_thrown_before</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::set_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="constant-syntax">INTERESTINGLY_FAILED_DASHFLAG</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">consider_alternatives</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">TEST_DASH_MODE</span><span class="plain-syntax">(</span><span class="constant-syntax">ISSUE_PROBLEMS_DMODE</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><a href="5-dsh.html#SP14" class="function-link"><span class="function-syntax">Dash::failed_one</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">context</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind_needed</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_1">&#167;10.9.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_1_12" class="paragraph-anchor"></a><b>&#167;10.9.1.1.12. </b>Usage statistics are mainly interesting to the writers of Inform, to help us
to get some picture of how much phrases are used across a large corpus of
existing source text (e.g., the documentation examples, or the public
extensions).
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4I.k) Cope with success</span><span class="named-paragraph-number">10.9.1.1.12</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4I.k) success"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::set_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="constant-syntax">PASSED_DASHFLAG</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">qualified</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::set_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="constant-syntax">UNPROVEN_DASHFLAG</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-inv.html#SP3" class="function-link"><span class="function-syntax">Invocations::mark_unproven</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">idb</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">NW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ToPhraseFamily::doc_ref</span><span class="plain-syntax">(</span><span class="identifier-syntax">idb</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">head_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">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">NW</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">pds</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">pds</span><span class="plain-syntax">, </span><span class="string-syntax">"%+W"</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">NW</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">Log::aspect_switched_on</span><span class="plain-syntax">(</span><span class="constant-syntax">PHRASE_USAGE_DA</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DocReferences::doc_mark_used</span><span class="plain-syntax">(</span><span class="identifier-syntax">pds</span><span class="plain-syntax">,</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">inv</span><span class="plain-syntax">)));</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">pds</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="5-dsh.html#SP10_9_1_1">&#167;10.9.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_2" class="paragraph-anchor"></a><b>&#167;10.9.1.2. (4S) Verifying single non-invocation readings. </b>This is much easier, though that's because a lot of the work is delegated
to level 5.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4S) Verify anything else</span><span class="named-paragraph-number">10.9.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4S.a)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_INDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> = </span><a href="5-dsh.html#SP18" class="function-link"><span class="function-syntax">Dash::typecheck_single_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind_needed</span><span class="plain-syntax">, </span><span class="identifier-syntax">condition_context</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_2_1" class="named-paragraph-link"><span class="named-paragraph">Allow listed-in table references only where these are expected</span><span class="named-paragraph-number">10.9.1.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4S.b)"</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">arg</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">arg</span><span class="plain-syntax">; </span><span class="identifier-syntax">arg</span><span class="plain-syntax"> = </span><span class="identifier-syntax">arg</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">outcome</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><a href="5-dsh.html#SP7" class="function-link"><span class="function-syntax">Dash::worst_case</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">outcome</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="5-dsh.html#SP9" class="function-link"><span class="function-syntax">Dash::typecheck_recursive</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">arg</span><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">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</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="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">LIST_ENTRY_NT</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_2_2" class="named-paragraph-link"><span class="named-paragraph">Step (4S.c) Check arguments of a list entry</span><span class="named-paragraph-number">10.9.1.2.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">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">PROPERTY_VALUE_NT</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_2_3" class="named-paragraph-link"><span class="named-paragraph">Step (4S.d) Check arguments of a property value</span><span class="named-paragraph-number">10.9.1.2.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">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">TABLE_ENTRY_NT</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_2_4" class="named-paragraph-link"><span class="named-paragraph">Step (4S.e) Check arguments of a table reference</span><span class="named-paragraph-number">10.9.1.2.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1">&#167;10.9.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_2_1" class="paragraph-anchor"></a><b>&#167;10.9.1.2.1. </b>The "C listed in T" form of table reference is illegal as a general value,
and allowed only in phrases using the <span class="extract"><span class="extract-syntax">table-reference</span></span> token.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Allow listed-in table references only where these are expected</span><span class="named-paragraph-number">10.9.1.2.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">TABLE_ENTRY_NT</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Node::no_children</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">) == </span><span class="constant-syntax">2</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">kind_needed</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (!(</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">context</span><span class="plain-syntax">, </span><span class="identifier-syntax">LVALUE_TR_CONTEXT_NT</span><span class="plain-syntax">)))) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM</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_InexplicitTableEntryAsValue</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this form of table entry can only be used in certain special phrases"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"because it doesn't explicitly refer to a single value. (You can see "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which phrases in the Phrasebook index: it's allowed wherever a 'table "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"entry' is wanted.)"</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">NEVER_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_2">&#167;10.9.1.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_2_2" class="paragraph-anchor"></a><b>&#167;10.9.1.2.2. </b>For a list entry, we have to have a list and an index.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4S.c) Check arguments of a list entry</span><span class="named-paragraph-number">10.9.1.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4S.c)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K1</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><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">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K2</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><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="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::unary_construction_material</span><span class="plain-syntax">(</span><span class="identifier-syntax">K1</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM</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_EntryOfNonList</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"that doesn't make sense to me as a list entry"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"since the entry is taken from something which isn't a list."</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">NEVER_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">K2</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM</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_NonNumericListEntry</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"that doesn't make sense to me as a list entry"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"because the indication of which entry is not a number. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"For instance, 'entry 3 of L' is allowed, but not 'entry "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"\"six\" of L'. (List entries are numbered 1, 2, 3, ...)"</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">NEVER_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_2">&#167;10.9.1.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_2_3" class="paragraph-anchor"></a><b>&#167;10.9.1.2.3. </b>For a property value, we have to have a property and an owner (perhaps an
object, perhaps a value). If the owner is a value, we need to police the
availability of the property carefully, since no run-time checking can help
us there.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4S.d) Check arguments of a property value</span><span class="named-paragraph-number">10.9.1.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4S.d)"</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">the_property</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">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K1</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">the_property</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::get_construct</span><span class="plain-syntax">(</span><span class="identifier-syntax">K1</span><span class="plain-syntax">) != </span><span class="identifier-syntax">CON_property</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_2_3_1" class="named-paragraph-link"><span class="named-paragraph">Issue a "not a property" problem message</span><span class="named-paragraph-number">10.9.1.2.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prn</span><span class="plain-syntax"> = </span><a href="2-rvl.html#SP3" class="function-link"><span class="function-syntax">Rvalues::to_property</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">the_property</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">prn</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">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"null property name in type checking"</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">Properties::is_either_or</span><span class="plain-syntax">(</span><span class="identifier-syntax">prn</span><span class="plain-syntax">)) </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_2_3_2" class="named-paragraph-link"><span class="named-paragraph">Issue a "not a value property" problem message</span><span class="named-paragraph-number">10.9.1.2.3.2</span></a></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">the_owner</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="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K2</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">the_owner</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">K2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><a href="2-spc.html#SP3" class="function-link"><span class="function-syntax">Specifications::is_description</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">the_owner</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP10_9_1_2_3_3" class="named-paragraph-link"><span class="named-paragraph">Issue a problem message for being too vague about the owner</span><span class="named-paragraph-number">10.9.1.2.3.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">owning_subject</span><span class="plain-syntax"> = </span><span class="identifier-syntax">InferenceSubjects::from_specification</span><span class="plain-syntax">(</span><span class="identifier-syntax">the_owner</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">owning_subject</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">owning_subject</span><span class="plain-syntax"> = </span><span class="identifier-syntax">KindSubjects::from_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">K2</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">PropertyPermissions::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">owning_subject</span><span class="plain-syntax">, </span><span class="identifier-syntax">prn</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</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">Kinds::Behaviour::is_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">K2</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> ((</span><a href="2-rvl.html#SP6" class="function-link"><span class="function-syntax">Rvalues::is_object</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">the_owner</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="2-rvl.html#SP8" class="function-link"><span class="function-syntax">Rvalues::is_self_object_constant</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">the_owner</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="5-dsh.html#SP10_9_1_2_3_4" class="named-paragraph-link"><span class="named-paragraph">Issue a problem message for not being allowed this property</span><span class="named-paragraph-number">10.9.1.2.3.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_2">&#167;10.9.1.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_2_3_1" class="paragraph-anchor"></a><b>&#167;10.9.1.2.3.1. </b>Inform constructs property-value specifications quite carefully, and I think
it's only possible for the typechecker to see one where the property isn't
a property when recovering from other problems.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a "not a property" problem message</span><span class="named-paragraph-number">10.9.1.2.3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM</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_wording</span><span class="plain-syntax">(2, </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">Problems::quote_wording</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">the_property</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">BelievedImpossible</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 sentence %1, it looks as if you intend '%2' to be a property "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"of something, but there is no such property as '%3'."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_2_3">&#167;10.9.1.2.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_2_3_2" class="paragraph-anchor"></a><b>&#167;10.9.1.2.3.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a "not a value property" problem message</span><span class="named-paragraph-number">10.9.1.2.3.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM</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_wording</span><span class="plain-syntax">(2, </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">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_EitherOrAsValue</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 sentence %1, it looks as if you intend '%2' to be the value "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"of a property of something, but that property has no value: it's "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"something which an object either is or is not."</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="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_2_3">&#167;10.9.1.2.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_2_3_3" class="paragraph-anchor"></a><b>&#167;10.9.1.2.3.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem message for being too vague about the owner</span><span class="named-paragraph-number">10.9.1.2.3.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM</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_wording</span><span class="plain-syntax">(2, </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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">owner_quoted</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><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">the_owner</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="2-dsc.html#SP9" class="function-link"><span class="function-syntax">Descriptions::get_quantifier</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">the_owner</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(3, </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">the_owner</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">the_owner</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">the_owner</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">owner_quoted</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">"Owner tree is $T\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">the_owner</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_PropertyOfKind2</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">owner_quoted</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">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">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"In the sentence %1, it looks as if you intend '%2' to be a property, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"but '%3' is not specific enough about who or what the owner is. "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"In the sentence %1, it looks as if you intend to look up a property "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"of something, but '%3' is not specific enough about who or what "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the owner is. "</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">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="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"In the sentence %1, it looks as if you intend '%2' to be a property, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"but you're not specific enough about who or what the owner is. "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"In the sentence %1, it looks as if you intend to look up a property "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"of something, but you're not specific enough about who or what "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the owner is. "</span><span class="plain-syntax">);</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">"%PSometimes this mistake is made because Inform mostly doesn't understand "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the English language habit of referring to something indefinite by a "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"common noun - for instance, writing 'change the carrying capacity of "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the container to 10' throws Inform because it doesn't understand "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"that 'the container' means one which has been discussed recently."</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="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_2_3">&#167;10.9.1.2.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_2_3_4" class="paragraph-anchor"></a><b>&#167;10.9.1.2.3.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem message for not being allowed this property</span><span class="named-paragraph-number">10.9.1.2.3.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM</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_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">prn</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_subject</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">owning_subject</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_LookedUpForbiddenProperty</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 sentence %1, you seem to be looking up the '%2' property, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"but '%3' is not allowed to have that property. "</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="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1_2_3">&#167;10.9.1.2.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_2_4" class="paragraph-anchor"></a><b>&#167;10.9.1.2.4. </b>For a table entry, we have to have a list and an index.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (4S.e) Check arguments of a table reference</span><span class="named-paragraph-number">10.9.1.2.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(4S.e)"</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::no_children</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">) == </span><span class="constant-syntax">4</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">col_kind</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><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="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">col_contents_kind</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::unary_construction_material</span><span class="plain-syntax">(</span><span class="identifier-syntax">col_kind</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">key_kind</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><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">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Kinds: col %u, contents %u, key %u\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">col_kind</span><span class="plain-syntax">, </span><span class="identifier-syntax">col_contents_kind</span><span class="plain-syntax">, </span><span class="identifier-syntax">key_kind</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Kinds::get_construct</span><span class="plain-syntax">(</span><span class="identifier-syntax">col_kind</span><span class="plain-syntax">) != </span><span class="identifier-syntax">CON_table_column</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">col_contents_kind</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM</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">BelievedImpossible</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"that doesn't make sense to me as a table entry"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"since the entry is taken from something which isn't a table."</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">NEVER_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::compatible</span><span class="plain-syntax">(</span><span class="identifier-syntax">key_kind</span><span class="plain-syntax">, </span><span class="identifier-syntax">col_contents_kind</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM</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_kind</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">col_contents_kind</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">key_kind</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_TableCorrFruitless</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 sentence %1, you seem to be looking up a corresponding "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"entry in a table: but it's fruitless to go looking for %3 "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"in a column where each entry contains %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="identifier-syntax">NEVER_MATCH</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="5-dsh.html#SP10_9_1_2">&#167;10.9.1.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_9_1_3" class="paragraph-anchor"></a><b>&#167;10.9.1.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Unknown found text occurs as a command</span><span class="named-paragraph-number">10.9.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="constant-syntax">THIS_IS_A_GROSS_PROBLEM</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;structural-phrase-problem-diagnosis&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="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">Wordings::mismatched_brackets</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">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_UnpairedBrackets</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this is a phrase which I don't recognise"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"perhaps because it uses brackets '(' and ')' or braces '{' and '}' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"in a way that doesn't make sense to me. Each open '(' or '{' has "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"to have a matching ')' or '}'."</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_UnknownPhrase</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this is a phrase which I don't recognise"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"possibly because it is one you meant to define but never got round "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"to, or because the wording is wrong (see the Phrasebook section of "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the Index to check). Alternatively, it may be that the text "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"immediately previous to this was a definition whose ending, normally "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"a full stop, is missing?"</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP10_9_1">&#167;10.9.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>"Diagnosis" nonterminals are used to parse syntax which is already known
to be invalid: they simply choose between problem messages. This one picks
up on misuse of structural phrases.
</p>
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;structural-phrase-problem-diagnosis&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">continue</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="5-dsh.html#SP11_1" class="named-paragraph-link"><span class="named-paragraph">Issue PM_WrongContinue problem</span><span class="named-paragraph-number">11.1</span></a></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="SP11_1" class="paragraph-anchor"></a><b>&#167;11.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_WrongContinue problem</span><span class="named-paragraph-number">11.1</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">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_WrongContinue</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this is a phrase which I don't recognise"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and which isn't defined. Perhaps you wanted the phrase which "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"would skip to the next repetition of a loop, since that's "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"written 'continue' in some programming languages (such as C "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and Inform 6)? If so, what you want is 'next'."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP11">&#167;11</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. Arithmetic operands. </b>The following works out the kind of an operand for an arithmetic operation,
which because of polymorphism is not as straightforward as it looks.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="function-syntax">Dash::fix_arithmetic_operand</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">Dash::fix_arithmetic_operand</span></span>:<br/><a href="5-dsh.html#SP10_9_1_1_2_2_1">&#167;10.9.1.1.2.2.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">operand</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">operand</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">, </span><span class="identifier-syntax">UNKNOWN_NT</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</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_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">operand</span><span class="plain-syntax">) != </span><span class="identifier-syntax">RVALUE_CONTEXT_NT</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"arithmetic operand not an rvalue"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">expected</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">check</span><span class="plain-syntax"> = </span><span class="identifier-syntax">operand</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">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">check</span><span class="plain-syntax">, </span><span class="identifier-syntax">AMBIGUITY_NT</span><span class="plain-syntax">)) </span><span class="identifier-syntax">check</span><span class="plain-syntax"> = </span><span class="identifier-syntax">check</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><a href="2-rvl.html#SP21" class="function-link"><span class="function-syntax">Rvalues::is_CONSTANT_construction</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">check</span><span class="plain-syntax">, </span><span class="identifier-syntax">CON_property</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prn</span><span class="plain-syntax"> = </span><a href="2-rvl.html#SP3" class="function-link"><span class="function-syntax">Rvalues::to_property</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">check</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">Properties::is_either_or</span><span class="plain-syntax">(</span><span class="identifier-syntax">prn</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">expected</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ValueProperties::kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">prn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_kind_required_by_context</span><span class="plain-syntax">(</span><span class="identifier-syntax">operand</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_kind_required_by_context</span><span class="plain-syntax">(</span><span class="identifier-syntax">operand</span><span class="plain-syntax">, </span><span class="identifier-syntax">expected</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="constant-syntax">BEGIN_DASH_MODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DASH_MODE_EXIT</span><span class="plain-syntax">(</span><span class="constant-syntax">ISSUE_PROBLEMS_DMODE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DASH_MODE_CREATE</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">rv</span><span class="plain-syntax"> = </span><a href="5-dsh.html#SP9" class="function-link"><span class="function-syntax">Dash::typecheck_recursive</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">operand</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="constant-syntax">END_DASH_MODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_kind_required_by_context</span><span class="plain-syntax">(</span><span class="identifier-syntax">operand</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">rv</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</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">return</span><span class="plain-syntax"> </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">operand</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. Local variable markers. </b>Branches (4A) and (4I) both make use of the following code, which is
applied to any invocation surviving Dash.
</p>
<p class="commentary">Here's the usual way a local variable is made. One invocation we matched is
for the phrase whose prototype reads:
</p>
<blockquote>
<p>To let (T - nonexisting variable) be (V - value): ...</p>
</blockquote>
<p class="commentary">To be definite, let's suppose we are working on:
</p>
<blockquote>
<p>let the magic word be "Shazam [turn count] times!";</p>
</blockquote>
<p class="commentary">The checking code above accepted "magic word" as a new name, and marked
token 0 in the invocation as one where a new variable will need to be
created &mdash; which is done if and when the invocation is ever compiled.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::set_up_any_local_required</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">Dash::set_up_any_local_required</span></span>:<br/><a href="5-dsh.html#SP10_9_2_3_2">&#167;10.9.2.3.2</a>, <a href="5-dsh.html#SP10_9_1_1">&#167;10.9.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">inv</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0, </span><span class="identifier-syntax">N</span><span class="plain-syntax"> = </span><a href="4-inv.html#SP6" class="function-link"><span class="function-syntax">Invocations::get_no_tokens</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">N</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><a href="4-inv.html#SP14" class="function-link"><span class="function-syntax">Invocations::get_token_variable_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">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">i</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">N</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">2</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">IDTypeData::is_a_let_assignment</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_phrase_invoked</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">))))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP13_1" class="named-paragraph-link"><span class="named-paragraph">Infer the kind of the new variable</span><span class="named-paragraph-number">13.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">changed</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">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::substitute</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">changed</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">changed</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(4A.c.1) Local var amended to %u\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-inv.html#SP14" class="function-link"><span class="function-syntax">Invocations::set_token_variable_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">ALWAYS_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13_1" class="paragraph-anchor"></a><b>&#167;13.1. </b>The following code is used to work out a good kind for the new variable,
instead of "value", based on looking at token 1 &mdash; the value being assigned.
In the example above, we look at this initial value,
</p>
<blockquote>
<p>"Shazam [turn count] times!"</p>
</blockquote>
<p class="commentary">and decide that K should be "text".
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Infer the kind of the new variable</span><span class="named-paragraph-number">13.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">val</span><span class="plain-syntax"> = </span><a href="4-inv.html#SP10" class="function-link"><span class="function-syntax">Invocations::get_token_as_parsed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">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">val</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">initial_value</span><span class="plain-syntax"> = </span><a href="4-inv.html#SP10" class="function-link"><span class="function-syntax">Invocations::get_token_as_parsed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="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">iv_spec</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_phrase_invoked</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">)-&gt;</span><span class="identifier-syntax">type_data</span><span class="plain-syntax">.</span><span class="identifier-syntax">token_sequence</span><span class="plain-syntax">[1].</span><span class="identifier-syntax">to_match</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">initial_value</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP13_1_1" class="named-paragraph-link"><span class="named-paragraph">Where no kind was explicitly stated, infer this from the supplied initial value</span><span class="named-paragraph-number">13.1.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP13">&#167;13</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP13_1_1" class="paragraph-anchor"></a><b>&#167;13.1.1. </b>Unusually, it's legal for the initial value to be a kind &mdash;
</p>
<blockquote>
<p>let the magic digraph be a text;</p>
</blockquote>
<p class="commentary">This doesn't give us an initial value as such, but it explicitly tells us the
kind, which is good enough.
</p>
<p class="commentary">Otherwise, we either know the kind already from polymorphism calculations, or
we can work it out by seeing what the initial value evaluates to. As usual,
we "round up to objects"; if the let-value is a kind of object, we make
the variable have kind "object", rather than some subkind.
</p>
<p class="commentary">We make one exception to allow lines like &mdash;
</p>
<blockquote>
<p>let X be a one-to-one relation of numbers to men;</p>
</blockquote>
<p class="commentary">where the adjective "one-to-one" forces the right hand side to be description
of a relation.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Where no kind was explicitly stated, infer this from the supplied initial value</span><span class="named-paragraph-number">13.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">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">seems_to_be</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><a href="2-spc.html#SP2" class="function-link"><span class="function-syntax">Specifications::is_kind_like</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">iv_spec</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">initial_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">CONSTANT_NT</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_kind_of_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">initial_value</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::get_construct</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CON_description</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">DK</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::unary_construction_material</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">Kinds::get_construct</span><span class="plain-syntax">(</span><span class="identifier-syntax">DK</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CON_relation</span><span class="plain-syntax">) </span><span class="identifier-syntax">seems_to_be</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DK</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">seems_to_be</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">seems_to_be</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">initial_value</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOCAL_VARIABLES</span><span class="plain-syntax">, </span><span class="string-syntax">"New variable %W from $P ($P) seems to be: %u\n"</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">initial_value</span><span class="plain-syntax">, </span><span class="identifier-syntax">iv_spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">seems_to_be</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">seems_to_be</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="5-dsh.html#SP13_1_1_1" class="named-paragraph-link"><span class="named-paragraph">Fail: the initial value of the local is unknown</span><span class="named-paragraph-number">13.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">Kinds::get_construct</span><span class="plain-syntax">(</span><span class="identifier-syntax">seems_to_be</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CON_list_of</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">Kinds::unary_construction_material</span><span class="plain-syntax">(</span><span class="identifier-syntax">seems_to_be</span><span class="plain-syntax">), </span><span class="identifier-syntax">K_nil</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP13_1_1_2" class="named-paragraph-link"><span class="named-paragraph">Fail: the initial value of the local is the empty list</span><span class="named-paragraph-number">13.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">Kinds::Behaviour::definite</span><span class="plain-syntax">(</span><span class="identifier-syntax">seems_to_be</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="5-dsh.html#SP13_1_1_3" class="named-paragraph-link"><span class="named-paragraph">Fail: the initial value can't be stored</span><span class="named-paragraph-number">13.1.1.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(4A.c.1) Local variable seems to have kind: %u\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">seems_to_be</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">seems_to_be</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Behaviour::is_subkind_of_object</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">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">Latticework::super</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">), </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Latticework::super</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">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(4A.c.1) Local variable inferred to have kind: %u\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP13_1">&#167;13.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP13_1_1_1" class="paragraph-anchor"></a><b>&#167;13.1.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Fail: the initial value of the local is unknown</span><span class="named-paragraph-number">13.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="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</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_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">initial_value</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">BelievedImpossible</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 %1 tries to use 'let' to give a temporary name to a value, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"but the value ('%2') is one that I can't understand."</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="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP13_1_1">&#167;13.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP13_1_1_2" class="paragraph-anchor"></a><b>&#167;13.1.1.2. </b>Bet you didn't think of this one. Actually, the kind of the list can also
collapse to just "value" if the entries are incompatible, so we call the
relevant code to issue a better problem message if it can.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Fail: the initial value of the local is the empty list</span><span class="named-paragraph-number">13.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="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</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">pc</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="3-ll.html#SP9" class="function-link"><span class="function-syntax">Lists::check_one</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">initial_value</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">pc</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">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">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_CantLetEmptyList</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 %1 tries to use 'let' to give a temporary name to the "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"empty list '{ }', but because it's empty, I can't tell what kind of "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"value the list should have. Try 'let X be a list of numbers' (or "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"whatever) instead."</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="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP13_1_1">&#167;13.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP13_1_1_3" class="paragraph-anchor"></a><b>&#167;13.1.1.3. </b>And some kinds are just forbidden in storage:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Fail: the initial value can't be stored</span><span class="named-paragraph-number">13.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="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</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">BelievedImpossible</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this isn't a definite kind"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and is instead a general description which might apply to many "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"different kinds, so I can't see how to create this named value. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"(For example, 'let R be a relation' is vague because it doesn't "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"make clear what R will relate - 'let R be a relation of numbers' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"would be fine.)"</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">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP13_1_1">&#167;13.1.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. Problems, problems, problems. </b>We are now in a situation where Dash has certainly failed, and on every
possible alternative reading, so it would be legitimate to return <span class="extract"><span class="extract-syntax">NEVER_MATCH</span></span>
here, which would likely result in some anodyne problem message from higher
up in Dash.
</p>
<p class="commentary">But we want to produce more helpful problem messages than that. It's not
entirely clear how best to do this. Often, when a node fails, it fails for
seven different reasons &mdash; each different possibility fails for a different
cause. We want, somehow, to guess which was the most likely to have been
intended and to report the problem with that one.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::failed_one</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">Dash::failed_one</span></span>:<br/><a href="5-dsh.html#SP10_9_1_1_11">&#167;10.9.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">inv</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">context</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_needed</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">list</span><span class="plain-syntax">[1];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">list</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="5-dsh.html#SP14" class="function-link"><span class="function-syntax">Dash::failed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">context</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind_needed</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">PM_BadIntermediateKind_wording</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING_INIT</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::failed</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">Dash::failed</span></span>:<br/><a href="5-dsh.html#SP10_9_2_4">&#167;10.9.2.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">list_of_possible_readings</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_of_possible_readings</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">context</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_needed</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP4" class="function-link"><span class="function-syntax">Dash::problems_have_been_issued</span></a><span class="plain-syntax">()) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEVER_MATCH</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_inv_in_group</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_failing_interestingly</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_not_failing_grossly</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">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">SW</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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">list_includes_lets</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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">nongross_count</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="5-dsh.html#SP14_1" class="named-paragraph-link"><span class="named-paragraph">Scan through the invocations in the problematic group, gathering information</span><span class="named-paragraph-number">14.1</span></a></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">most_likely_to_have_been_intended</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="5-dsh.html#SP14_2" class="named-paragraph-link"><span class="named-paragraph">Decide which invocation is the one most likely to have been intended</span><span class="named-paragraph-number">14.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc_before</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">first_failing_interestingly</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP14_3" class="named-paragraph-link"><span class="named-paragraph">Re-type-check the first interesting invocation, allowing interesting problems this time</span><span class="named-paragraph-number">14.3</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">most_likely_to_have_been_intended</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP14_4" class="named-paragraph-link"><span class="named-paragraph">Re-type-check the tokens of the most likely invocation with silence off</span><span class="named-paragraph-number">14.4</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> == </span><span class="identifier-syntax">pc_before</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">SW</span><span class="plain-syntax">)) </span><span class="function-syntax">&lt;failed-text-substitution-diagnosis&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">SW</span><span class="plain-syntax">);</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="5-dsh.html#SP14_5" class="named-paragraph-link"><span class="named-paragraph">Issue a problem for a regular phrase with multiple failed possibilities</span><span class="named-paragraph-number">14.5</span></a></span><span class="plain-syntax">;</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">NEVER_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14_1" class="paragraph-anchor"></a><b>&#167;14.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Scan through the invocations in the problematic group, gathering information</span><span class="named-paragraph-number">14.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ref</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">ref</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">no_of_possible_readings</span><span class="plain-syntax">; </span><span class="identifier-syntax">ref</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">list_of_possible_readings</span><span class="plain-syntax">[</span><span class="identifier-syntax">ref</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::test_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="constant-syntax">INTERESTINGLY_FAILED_DASHFLAG</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">first_failing_interestingly</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="identifier-syntax">first_failing_interestingly</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">first_inv_in_group</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">first_inv_in_group</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">id_body</span><span class="plain-syntax"> *</span><span class="identifier-syntax">idb</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_phrase_invoked</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">idb</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">IDTypeData::is_a_let_assignment</span><span class="plain-syntax">(</span><span class="identifier-syntax">idb</span><span class="plain-syntax">)) </span><span class="identifier-syntax">list_includes_lets</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><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::test_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">, </span><span class="constant-syntax">GROSSLY_FAILED_DASHFLAG</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">first_not_failing_grossly</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inv</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">IDTypeData::is_a_say_X_phrase</span><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">idb</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">type_data</span><span class="plain-syntax">))) </span><span class="identifier-syntax">SW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">inv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">nongross_count</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP14">&#167;14</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP14_2" class="paragraph-anchor"></a><b>&#167;14.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Decide which invocation is the one most likely to have been intended</span><span class="named-paragraph-number">14.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">first_failing_interestingly</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">most_likely_to_have_been_intended</span><span class="plain-syntax"> = </span><span class="identifier-syntax">first_failing_interestingly</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">nongross_count</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">list_includes_lets</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">most_likely_to_have_been_intended</span><span class="plain-syntax"> = </span><span class="identifier-syntax">first_not_failing_grossly</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">nongross_count</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">most_likely_to_have_been_intended</span><span class="plain-syntax"> = </span><span class="identifier-syntax">first_not_failing_grossly</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">nongross_count</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">first_inv_in_group</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">most_likely_to_have_been_intended</span><span class="plain-syntax"> = </span><span class="identifier-syntax">first_inv_in_group</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP14">&#167;14</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP14_3" class="paragraph-anchor"></a><b>&#167;14.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Re-type-check the first interesting invocation, allowing interesting problems this time</span><span class="named-paragraph-number">14.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="constant-syntax">BEGIN_DASH_MODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DASH_MODE_ENTER</span><span class="plain-syntax">(</span><span class="constant-syntax">ISSUE_INTERESTING_PROBLEMS_DMODE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DASH_MODE_CREATE</span><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="5-dsh.html#SP9" class="function-link"><span class="function-syntax">Dash::typecheck_recursive</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">first_failing_interestingly</span><span class="plain-syntax">, </span><span class="identifier-syntax">context</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="constant-syntax">END_DASH_MODE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP14">&#167;14</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP14_4" class="paragraph-anchor"></a><b>&#167;14.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Re-type-check the tokens of the most likely invocation with silence off</span><span class="named-paragraph-number">14.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ec</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="constant-syntax">BEGIN_DASH_MODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DASH_MODE_ENTER</span><span class="plain-syntax">(</span><span class="constant-syntax">ISSUE_PROBLEMS_DMODE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DASH_MODE_CREATE</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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><a href="4-inv.html#SP6" class="function-link"><span class="function-syntax">Invocations::get_no_tokens</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">most_likely_to_have_been_intended</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><a href="5-dsh.html#SP9" class="function-link"><span class="function-syntax">Dash::typecheck_recursive</span></a><span class="plain-syntax">(</span><a href="4-inv.html#SP7" class="function-link"><span class="function-syntax">Invocations::get_token</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">most_likely_to_have_been_intended</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">), </span><span class="identifier-syntax">context</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">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">ec</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">problem_count</span><span class="plain-syntax"> == </span><span class="identifier-syntax">ec</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Try again in local problems mode\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="constant-syntax">BEGIN_DASH_MODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DASH_MODE_ENTER</span><span class="plain-syntax">(</span><span class="constant-syntax">ISSUE_LOCAL_PROBLEMS_DMODE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DASH_MODE_CREATE</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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><a href="4-inv.html#SP6" class="function-link"><span class="function-syntax">Invocations::get_no_tokens</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">most_likely_to_have_been_intended</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><a href="5-dsh.html#SP9" class="function-link"><span class="function-syntax">Dash::typecheck_recursive</span></a><span class="plain-syntax">(</span><a href="4-inv.html#SP7" class="function-link"><span class="function-syntax">Invocations::get_token</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">most_likely_to_have_been_intended</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">), </span><span class="identifier-syntax">context</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">problem_count</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">ec</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="constant-syntax">END_DASH_MODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="constant-syntax">END_DASH_MODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">problem_count</span><span class="plain-syntax"> == </span><span class="identifier-syntax">ec</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_kind_resulting</span><span class="plain-syntax">(</span><span class="identifier-syntax">most_likely_to_have_been_intended</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">kind_needed</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">) &amp;&amp; (</span><span class="identifier-syntax">W</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Kinds::compatible</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</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">PW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">list_of_possible_readings</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!(</span><span class="identifier-syntax">Wordings::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_BadIntermediateKind_wording</span><span class="plain-syntax">, </span><span class="identifier-syntax">PW</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PM_BadIntermediateKind_wording</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PW</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_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">PW</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">W</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_BadIntermediateKind</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 %1, the phrase '%2' doesn't seem to fit: I was hoping it would "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"be %4, but in fact it's %3."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEVER_MATCH</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">problem_count</span><span class="plain-syntax"> == </span><span class="identifier-syntax">ec</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Try again in gross problems mode\n$T\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">most_likely_to_have_been_intended</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="constant-syntax">BEGIN_DASH_MODE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DASH_MODE_ENTER</span><span class="plain-syntax">(</span><span class="constant-syntax">ISSUE_GROSS_PROBLEMS_DMODE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DASH_MODE_CREATE</span><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="5-dsh.html#SP9" class="function-link"><span class="function-syntax">Dash::typecheck_recursive</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">most_likely_to_have_been_intended</span><span class="plain-syntax">, </span><span class="identifier-syntax">context</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="constant-syntax">END_DASH_MODE</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">problem_count</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">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">"the ingredients in this phrase do not fit it"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and I am confused enough by this that I can't give a very helpful "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"problem message. Sorry about that."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP14">&#167;14</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP14_5" class="paragraph-anchor"></a><b>&#167;14.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem for a regular phrase with multiple failed possibilities</span><span class="named-paragraph-number">14.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">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_AllInvsFailed</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::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"You wrote %1, which I tried to match against several possible phrase "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"definitions. None of them worked."</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="5-dsh.html#SP14">&#167;14</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. </b>The following chooses a problem message for a text substitution which is
unrecognised.
</p>
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;failed-text-substitution-diagnosis&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">a</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">list</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">of</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-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="5-dsh.html#SP15_1" class="named-paragraph-link"><span class="named-paragraph">Issue PM_SayAList problem</span><span class="named-paragraph-number">15.1</span></a></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="5-dsh.html#SP15_2" class="named-paragraph-link"><span class="named-paragraph">Issue last-resort failed ts problem</span><span class="named-paragraph-number">15.2</span></a></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="SP15_1" class="paragraph-anchor"></a><b>&#167;15.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_SayAList problem</span><span class="named-paragraph-number">15.1</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">StandardProblems::sentence_in_detail_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_SayAList</span><span class="plain-syntax">), </span><span class="identifier-syntax">W</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this asked to say 'a list of...'"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which I read as being a general description applying to some "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"lists and not others, so it's not something which can be said. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"(Maybe you meant 'the list of...' instead? That normally makes "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"a definite list of whatever matches the '...' part.)"</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP15">&#167;15</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP15_2" class="paragraph-anchor"></a><b>&#167;15.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue last-resort failed ts problem</span><span class="named-paragraph-number">15.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">StandardProblems::sentence_in_detail_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="identifier-syntax">W</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this asked to say something which I do not recognise"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"either as a value or as one of the possible text substitutions."</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP15">&#167;15</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. </b>In the final checklist of doomed possibility, the code to quote an
invocation in a problem message will call the following routine for each
parsed token. This remembers the token so that it can be explained in notes
at the end of the big list; but each word range is remembered only once,
for brevity. We don't gloss the meanings of literal constants like <span class="extract"><span class="extract-syntax">26</span></span>
or <span class="extract"><span class="extract-syntax">"frog"</span></span> since these are glaringly obvious.
</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">Dash::note_inv_token_text</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">new_name</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inv_token_problem_token</span><span class="plain-syntax"> *</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">, </span><span class="reserved-syntax">inv_token_problem_token</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::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">problematic_text</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">new_name</span><span class="plain-syntax">) </span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">new_name</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">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">itpt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">inv_token_problem_token</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">problematic_text</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">itpt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">new_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_name</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">AMBIGUITY_NT</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="identifier-syntax">down</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">as_parsed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">; </span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">already_described</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><a href="2-rvl.html#SP21" class="function-link"><span class="function-syntax">Rvalues::is_CONSTANT_of_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><a href="2-rvl.html#SP21" class="function-link"><span class="function-syntax">Rvalues::is_CONSTANT_of_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_text</span><span class="plain-syntax">))) </span><span class="identifier-syntax">itpt</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">already_described</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. </b>This last little grammar diagnoses problems with a condition, and helps to
construct a problem message which will (usually) show which part of a compound
condition caused the trouble:
</p>
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;condition-problem-diagnosis&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;condition-problem-part&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;condition-problem-part-tail&gt;</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"> { R[1] | R[2], - }</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;condition-problem-part&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> { pass 1 }</span>
<span class="Preform-function-syntax">&lt;condition-problem-part-tail&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">and/or</span><span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;condition-problem-diagnosis&gt;</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"> { pass 1 }</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">,/and/or</span><span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;condition-problem-diagnosis&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> { pass 1 }</span>
<span class="Preform-function-syntax">&lt;condition-problem-part&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;s-condition&gt;</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"> { 0, - }; </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP17_1" class="named-paragraph-link"><span class="named-paragraph">Quote this-condition-okay segment</span><span class="named-paragraph-number">17.1</span></a></span><span class="Preform-constant-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;s-value&gt;</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"> { INVALID_CP_BIT, - }; </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP17_2" class="named-paragraph-link"><span class="named-paragraph">Quote this-condition-value segment</span><span class="named-paragraph-number">17.2</span></a></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-constant-syntax">begins/ends</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"> { WHENWHILE_CP_BIT+INVALID_CP_BIT, - }; </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP17_3" class="named-paragraph-link"><span class="named-paragraph">Quote scene-begins-or-ends segment</span><span class="named-paragraph-number">17.3</span></a></span><span class="Preform-constant-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">when/while</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"> { WHENWHILE_CP_BIT+INVALID_CP_BIT, - }; </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP17_4" class="named-paragraph-link"><span class="named-paragraph">Quote this-condition-bad segment</span><span class="named-paragraph-number">17.4</span></a></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"> { INVALID_CP_BIT, - }; </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP17_4" class="named-paragraph-link"><span class="named-paragraph">Quote this-condition-bad segment</span><span class="named-paragraph-number">17.4</span></a></span><span class="Preform-constant-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="SP17_1" class="paragraph-anchor"></a><b>&#167;17.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Quote this-condition-okay segment</span><span class="named-paragraph-number">17.1</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">preform_lookahead_mode</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">W</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="string-syntax">"'%4' was okay; "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP17">&#167;17</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP17_2" class="paragraph-anchor"></a><b>&#167;17.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Quote this-condition-value segment</span><span class="named-paragraph-number">17.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">preform_lookahead_mode</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">W</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">"'%4' only made sense as a value, which can't be used as a condition; "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP17">&#167;17</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP17_3" class="paragraph-anchor"></a><b>&#167;17.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Quote scene-begins-or-ends segment</span><span class="named-paragraph-number">17.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">preform_lookahead_mode</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">W</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">"'%4' did not make sense as a condition, but looked as if it might "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"be a way to specify a beginning or end for a scene - but such things "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"can't be divided by 'or'; "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP17">&#167;17</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP17_4" class="paragraph-anchor"></a><b>&#167;17.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Quote this-condition-bad segment</span><span class="named-paragraph-number">17.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">preform_lookahead_mode</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">W</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="string-syntax">"'%4' did not make sense; "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP17">&#167;17</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. (5) Single nodes. </b>Here we typecheck a single non-invocation node on its own terms, ignoring
any children it may have.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::typecheck_single_node</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Dash::typecheck_single_node</span></span>:<br/><a href="5-dsh.html#SP10_9_1_2">&#167;10.9.1.2</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="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">condition_context</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(5)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Kind expected: %u, condition expected: %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">, </span><span class="identifier-syntax">condition_context</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">outcome</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ALWAYS_MATCH</span><span class="plain-syntax">; </span><span class="comment-syntax"> drops to </span><span class="extract"><span class="extract-syntax">SOMETIMES_MATCH</span></span><span class="comment-syntax"> if a need for run-time checking is realised</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-rvl.html#SP8" class="function-link"><span class="function-syntax">Rvalues::is_nothing_object_constant</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Kinds::Behaviour::is_subkind_of_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP18_1" class="named-paragraph-link"><span class="named-paragraph">Disallow "nothing" as a match for a description requiring a kind of object</span><span class="named-paragraph-number">18.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP18_2" class="named-paragraph-link"><span class="named-paragraph">Step (5.a) Deal with the UNKNOWN_NT</span><span class="named-paragraph-number">18.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP18_3" class="named-paragraph-link"><span class="named-paragraph">Step (5.b) Deal with bare property names</span><span class="named-paragraph-number">18.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP18_4" class="named-paragraph-link"><span class="named-paragraph">Step (5.c) Deal with any attached proposition</span><span class="named-paragraph-number">18.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP18_5" class="named-paragraph-link"><span class="named-paragraph">Step (5.d) Apply miscellaneous other coercions</span><span class="named-paragraph-number">18.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP18_6" class="named-paragraph-link"><span class="named-paragraph">Step (5.e) The Main Rule of Type-Checking</span><span class="named-paragraph-number">18.6</span></a></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">outcome</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP18_1" class="paragraph-anchor"></a><b>&#167;18.1. </b>"You can't have/ Something for nothing," as Canadian power-trio Rush tell
us with the air of having just made a great discovery; well, you can't have
"nothing" for something, either &mdash;
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Disallow "nothing" as a match for a description requiring a kind of object</span><span class="named-paragraph-number">18.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="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</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_wording</span><span class="plain-syntax">(2, </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">Problems::quote_kind</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">kind_expected</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_NothingForSomething</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 '%2' is literally no thing, and it consequently does "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"not count as %3."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP18">&#167;18</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_2" class="paragraph-anchor"></a><b>&#167;18.2. Rule (5.a). </b>In all cases, unknown text in <span class="extract"><span class="extract-syntax">found</span></span> is incorrect. We can produce
any of more than twenty different problem messages here, in an attempt to be
helpful about what exactly is wrong.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">SAY_UTSHAPE</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">LIST_UTSHAPE</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">NO_UTSHAPE</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (5.a) Deal with the UNKNOWN_NT</span><span class="named-paragraph-number">18.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(5.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">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</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="constant-syntax">THIS_IS_A_GROSS_PROBLEM</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">"(5.a) problem message:\nfound: $Texpected: %u"</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">IF_MODULE</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_stored_action</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP18_2_1" class="named-paragraph-link"><span class="named-paragraph">Unknown found text occurs as an action to try</span><span class="named-paragraph-number">18.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</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_wording</span><span class="plain-syntax">(2, </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">condition_context</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(3, </span><span class="string-syntax">"a condition"</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">kind_expected</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">kind_expected</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">shape</span><span class="plain-syntax"> = </span><span class="constant-syntax">NO_UTSHAPE</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">current_sentence</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="function-syntax">&lt;unknown-text-shape&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">shape</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;r&gt;&gt;</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">shape</span><span class="plain-syntax"> == </span><span class="constant-syntax">NO_UTSHAPE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="function-syntax">&lt;unknown-text-shape&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">shape</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;r&gt;&gt;</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">preceding</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="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">preceding</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (((</span><span class="identifier-syntax">TextSubstitutions::currently_compiling</span><span class="plain-syntax">()) || (</span><span class="identifier-syntax">shape</span><span class="plain-syntax"> == </span><span class="constant-syntax">SAY_UTSHAPE</span><span class="plain-syntax">))) &amp;&amp;</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">preceding</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">current_sentence</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> || (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">preceding</span><span class="plain-syntax">) == </span><span class="identifier-syntax">COMMA_V</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP18_2_2" class="named-paragraph-link"><span class="named-paragraph">Unknown found text occurs as a text substitution</span><span class="named-paragraph-number">18.2.2</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">condition_context</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">shape</span><span class="plain-syntax"> == </span><span class="constant-syntax">LIST_UTSHAPE</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP18_2_3" class="named-paragraph-link"><span class="named-paragraph">Issue a problem message for a compound condition which has gone bad</span><span class="named-paragraph-number">18.2.3</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP18_2_4" class="named-paragraph-link"><span class="named-paragraph">Issue a problem message for miscellaneous suspicious wordings</span><span class="named-paragraph-number">18.2.4</span></a></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">NEVER_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP18">&#167;18</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_2_1" class="paragraph-anchor"></a><b>&#167;18.2.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Unknown found text occurs as an action to try</span><span class="named-paragraph-number">18.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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">spec</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">K2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="5-dsh.html#SP24" class="function-link"><span class="function-syntax">Dash::clear_validation_case</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="function-syntax">&lt;action-pattern&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="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP24" class="function-link"><span class="function-syntax">Dash::get_validation_case</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">spec</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">K</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">K2</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_UnknownTryAction1</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_wording</span><span class="plain-syntax">(2, </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">Problems::quote_wording</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(5, </span><span class="identifier-syntax">K2</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 '%2' is not an action I can try. This looks as "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"if it might be because it contains something of the wrong kind. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"My best try involved seeing if '%3' could be %4, which might have "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"made sense, but it turned out to be %5."</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="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_UnknownTryAction2</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"this is not an action I recognise"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"or else is malformed in a way I can't see how to sort out."</span><span class="plain-syntax">);</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">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP18_2">&#167;18.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. </b>The &lt;unknown-text-shape&gt; is used purely in diagnosing problems; it helps
to decide, for instance, whether the errant phrase was intended to be a text
substitution or not.
</p>
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;unknown-text-shape&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">say</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-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"> { SAY_UTSHAPE, - }</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">and/or</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-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"> { LIST_UTSHAPE, - }</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"> { NO_UTSHAPE, - }</span>
<span class="Preform-function-syntax">&lt;unknown-text-substitution-problem-diagnosis&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-reserved-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="5-dsh.html#SP19_1" class="named-paragraph-link"><span class="named-paragraph">Issue PM_SayComma problem</span><span class="named-paragraph-number">19.1</span></a></span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">unicode</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-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="5-dsh.html#SP19_2" class="named-paragraph-link"><span class="named-paragraph">Issue PM_SayUnicode problem</span><span class="named-paragraph-number">19.2</span></a></span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">condition</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="5-dsh.html#SP19_4" class="named-paragraph-link"><span class="named-paragraph">Issue PM_SayUnknownCondition problem</span><span class="named-paragraph-number">19.4</span></a></span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">otherwise/else</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="5-dsh.html#SP19_3" class="named-paragraph-link"><span class="named-paragraph">Issue PM_SayElseMisplaced problem</span><span class="named-paragraph-number">19.3</span></a></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="5-dsh.html#SP19_5" class="named-paragraph-link"><span class="named-paragraph">Issue PM_SayUnknown problem</span><span class="named-paragraph-number">19.5</span></a></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="SP19_1" class="paragraph-anchor"></a><b>&#167;19.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_SayComma problem</span><span class="named-paragraph-number">19.1</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">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_SayComma</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 line %1, I was expecting that '%2' would be something to "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'say', but unexpectedly it began with a comma. The usual form is "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"just 'say \"text\"', perhaps with some substitutions in square "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"brackets within the quoted text, but no commas."</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="5-dsh.html#SP19">&#167;19</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP19_2" class="paragraph-anchor"></a><b>&#167;19.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_SayUnicode problem</span><span class="named-paragraph-number">19.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">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_SayUnicode</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 line %1, I was expecting that '%2' would be something to "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'say', but it didn't look like any form of 'say' that I know. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"So I tried to read '%2' as a Unicode character, which seemed "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"likely because of the word 'unicode', but that didn't work either. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"%PUnicode characters can be written either using their decimal "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"numbers - for instance, 'Unicode 2041' - or with their standard "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"names - 'Unicode Latin small ligature oe'. For efficiency reasons "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"these names are only available if you ask for them; to make them "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"available, you need to 'Include Unicode Character Names by Graham "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Nelson' or, if you really need more, 'Include Unicode Full "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Character Names by Graham Nelson'."</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="5-dsh.html#SP19">&#167;19</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP19_3" class="paragraph-anchor"></a><b>&#167;19.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_SayElseMisplaced problem</span><span class="named-paragraph-number">19.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::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_SayElseMisplaced</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 line %1, I was expecting that '%2' would be something to "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'say', but unexpectedly I found an 'otherwise' (or 'else'). That "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"would be fine inside an '[if ...]' part of the text, but doesn't "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"make sense on its own."</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="5-dsh.html#SP19">&#167;19</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP19_4" class="paragraph-anchor"></a><b>&#167;19.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_SayUnknownCondition problem</span><span class="named-paragraph-number">19.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">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_SayUnknownCondition</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 line %1, I was expecting that '%2' would be something to "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'say', but it didn't look like any form of 'say' that I know. So "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"I tried to read '%2' as a value of some kind (because it's legal "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"to say values), but couldn't make sense of it that way either. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"%PSometimes this happens because punctuation has gone wrong - "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"for instance, if you've omitted a semicolon or full stop at the "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"end of the 'say' phrase."</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">"%PNames which end in 'condition' often represent the current "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"state of something which can be in any one of three or more "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"states. This will only be the case if you have explicitly said "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"so, with a line like 'The rocket is either dry, fuelled or launched.' - "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"in which case the value 'rocket condition' will always be one "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"of 'dry', 'fuelled' or 'launched'. Note that all of this only "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"applies to a list of three or more possibilities - a thing can "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"have any number of either/or properties. For instance, a "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"container is open or closed, but it also transparent or opaque. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Neither of these counts as its 'condition'."</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="5-dsh.html#SP19">&#167;19</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP19_5" class="paragraph-anchor"></a><b>&#167;19.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_SayUnknown problem</span><span class="named-paragraph-number">19.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">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_SayUnknown</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 line %1, I was expecting that '%2' would be something to "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'say', but it didn't look like any form of 'say' that I know. So "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"I tried to read '%2' as a value of some kind (because it's legal "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"to say values), but couldn't make sense of it that way either. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"%PSometimes this happens because punctuation has gone wrong - "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"for instance, if you've omitted a semicolon or full stop at the "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"end of the 'say' phrase."</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="5-dsh.html#SP19">&#167;19</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_2_2" class="paragraph-anchor"></a><b>&#167;18.2.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Unknown found text occurs as a text substitution</span><span class="named-paragraph-number">18.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="function-syntax">&lt;unknown-text-substitution-problem-diagnosis&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>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP18_2">&#167;18.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_2_3" class="paragraph-anchor"></a><b>&#167;18.2.3. </b>It's a bit unenlightening when an entire condition is rejected as
unknown if, in fact, only one of perhaps many clauses is broken. We
therefore produce quite an elaborate problem message which goes through
the clauses, summing up their status in turn:
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">INVALID_CP_BIT</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">WHENWHILE_CP_BIT</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem message for a compound condition which has gone bad</span><span class="named-paragraph-number">18.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::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_CompoundConditionFailed</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 sentence %1, I was expecting that '%2' would be a condition. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"It didn't make sense as one long phrase, but because it was divided up by "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'and'/'or', I tried breaking it down into smaller conditions, but "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"that didn't work either. "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="function-syntax">&lt;condition-problem-diagnosis&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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">dubious</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;r&gt;&gt;</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">dubious</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">INVALID_CP_BIT</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">"so I ran out of ideas."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"but that combination of conditions isn't allowed to be joined "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"together with 'and' or 'or', because that would just be too confusing. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"%PFor example, 'if the player is carrying a container or a "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"supporter' has an obvious meaning in English, but Inform reads "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"it as two different conditions glued together: 'if the player is "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"carrying a container', and also 'a supporter'. The meaning of "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the first is obvious. The second part is true if the current "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"item under discussion is a supporter - for instance, the noun of "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the current action, or the item to which a definition applies. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Both of these conditions are useful in different circumstances, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"but combining them in one condition like this makes a very "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"misleading line of text. So Inform disallows it."</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">dubious</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">WHENWHILE_CP_BIT</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">"%PI notice there's a 'when' or 'while' being used as the opening "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"word of one of those conditions, though; maybe that's the problem?"</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="5-dsh.html#SP18_2">&#167;18.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. </b>These are cases where the wording used in the source text suggests some
common misunderstanding.
</p>
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;unknown-value-problem-diagnosis&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">turns</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="5-dsh.html#SP20_1" class="named-paragraph-link"><span class="named-paragraph">Issue PM_NumberOfTurns problem</span><span class="named-paragraph-number">20.1</span></a></span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">is/are</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">out</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">of</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">play</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="5-dsh.html#SP20_2" class="named-paragraph-link"><span class="named-paragraph">Issue PM_OutOfPlay problem</span><span class="named-paragraph-number">20.2</span></a></span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">unicode</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-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="5-dsh.html#SP20_5" class="named-paragraph-link"><span class="named-paragraph">Issue PM_MidTextUnicode problem</span><span class="named-paragraph-number">20.5</span></a></span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">condition</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="5-dsh.html#SP20_6" class="named-paragraph-link"><span class="named-paragraph">Issue PM_UnknownCondition problem</span><span class="named-paragraph-number">20.6</span></a></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="5-dsh.html#SP20_8" class="named-paragraph-link"><span class="named-paragraph">Issue PM_Unknown problem</span><span class="named-paragraph-number">20.8</span></a></span>
<span class="Preform-function-syntax">&lt;unknown-use-option-diagnosis&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">^option</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="5-dsh.html#SP20_3" class="named-paragraph-link"><span class="named-paragraph">Issue PM_OptionlessOption problem</span><span class="named-paragraph-number">20.3</span></a></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="5-dsh.html#SP20_8" class="named-paragraph-link"><span class="named-paragraph">Issue PM_Unknown problem</span><span class="named-paragraph-number">20.8</span></a></span>
<span class="Preform-function-syntax">&lt;unknown-activity-diagnosis&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">of</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="5-dsh.html#SP20_4" class="named-paragraph-link"><span class="named-paragraph">Issue PM_ActivityOf problem</span><span class="named-paragraph-number">20.4</span></a></span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">for</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="5-dsh.html#SP20_7" class="named-paragraph-link"><span class="named-paragraph">Issue PM_ActivityWithFor problem</span><span class="named-paragraph-number">20.7</span></a></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="5-dsh.html#SP20_8" class="named-paragraph-link"><span class="named-paragraph">Issue PM_Unknown problem</span><span class="named-paragraph-number">20.8</span></a></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="SP20_1" class="paragraph-anchor"></a><b>&#167;20.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_NumberOfTurns problem</span><span class="named-paragraph-number">20.1</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">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_NumberOfTurns</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP20_1_1" class="named-paragraph-link"><span class="named-paragraph">Issue the generic unknown wording message</span><span class="named-paragraph-number">20.1.1</span></a></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">"%PPerhaps by 'turns' you meant the number of turns of play to date? "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"If so, try 'turn count' instead."</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="5-dsh.html#SP20">&#167;20</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP20_2" class="paragraph-anchor"></a><b>&#167;20.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_OutOfPlay problem</span><span class="named-paragraph-number">20.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">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_OutOfPlay</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP20_1_1" class="named-paragraph-link"><span class="named-paragraph">Issue the generic unknown wording message</span><span class="named-paragraph-number">20.1.1</span></a></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">"%PPeople sometimes say that things or people removed from all "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"rooms are 'out of play', but Inform uses the adjective "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'off-stage' - for instance, 'if the ball is off-stage'. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"If you would like 'out of play' to work, you could always "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"write 'Definition: A thing is out of play if it is off-stage.' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Then the two would be equivalent."</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="5-dsh.html#SP20">&#167;20</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP20_3" class="paragraph-anchor"></a><b>&#167;20.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_OptionlessOption problem</span><span class="named-paragraph-number">20.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::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_OptionlessOption</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP20_1_1" class="named-paragraph-link"><span class="named-paragraph">Issue the generic unknown wording message</span><span class="named-paragraph-number">20.1.1</span></a></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">"%PThe names of use options, on the rare occasions when they "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"appear as values, always end with the word 'option' - for "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"instance, we have to write 'American dialect option' not "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'American dialect'. As your text here doesn't end with the "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"word 'option', perhaps you've forgotten this arcane rule?"</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="5-dsh.html#SP20">&#167;20</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP20_4" class="paragraph-anchor"></a><b>&#167;20.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_ActivityOf problem</span><span class="named-paragraph-number">20.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">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_ActivityOf</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP20_1_1" class="named-paragraph-link"><span class="named-paragraph">Issue the generic unknown wording message</span><span class="named-paragraph-number">20.1.1</span></a></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">"%PActivity names rarely end with 'of': for instance, when we talk "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"about 'printing the name of something', properly speaking "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the activity is called 'printing the name'. Maybe that's it?"</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="5-dsh.html#SP20">&#167;20</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP20_5" class="paragraph-anchor"></a><b>&#167;20.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_MidTextUnicode problem</span><span class="named-paragraph-number">20.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">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_MidTextUnicode</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP20_1_1" class="named-paragraph-link"><span class="named-paragraph">Issue the generic unknown wording message</span><span class="named-paragraph-number">20.1.1</span></a></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">"%PMaybe you intended this to produce a Unicode character? "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Unicode characters can be written either using their decimal "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"numbers - for instance, 'Unicode 2041' - or with their standard "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"names - 'Unicode Latin small ligature oe'. For efficiency reasons "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"these names are only available if you ask for them; to make them "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"available, you need to 'Include Unicode Character Names by Graham "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Nelson' or, if you really need more, 'Include Unicode Full "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Character Names by Graham Nelson'."</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="5-dsh.html#SP20">&#167;20</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP20_6" class="paragraph-anchor"></a><b>&#167;20.6. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_UnknownCondition problem</span><span class="named-paragraph-number">20.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">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_UnknownCondition</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP20_1_1" class="named-paragraph-link"><span class="named-paragraph">Issue the generic unknown wording message</span><span class="named-paragraph-number">20.1.1</span></a></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">"%PNames which end in 'condition' often represent the current "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"state of something which can be in any one of three or more "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"states. Names like this only work if you've declared them, with "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"a line like 'The rocket is either dry, fuelled or launched.' - "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"in which case the value 'rocket condition' will always be one "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"of 'dry', 'fuelled' or 'launched'. Maybe you forgot to declare "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"something like this, or mis-spelled the name of the owner?"</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="5-dsh.html#SP20">&#167;20</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP20_7" class="paragraph-anchor"></a><b>&#167;20.7. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_ActivityWithFor problem</span><span class="named-paragraph-number">20.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::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_ActivityWithFor</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP20_1_1" class="named-paragraph-link"><span class="named-paragraph">Issue the generic unknown wording message</span><span class="named-paragraph-number">20.1.1</span></a></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">"%PWere you by any chance meaning to refer to an activity by name, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"and used the word 'for' at the end of that name? If so, try removing "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"just the word 'for'."</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="5-dsh.html#SP20">&#167;20</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP20_8" class="paragraph-anchor"></a><b>&#167;20.8. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_Unknown problem</span><span class="named-paragraph-number">20.8</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">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_Unknown</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP20_1_1" class="named-paragraph-link"><span class="named-paragraph">Issue the generic unknown wording message</span><span class="named-paragraph-number">20.1.1</span></a></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="5-dsh.html#SP20">&#167;20</a> (three times).</li></ul>
<p class="commentary firstcommentary"><a id="SP20_1_1" class="paragraph-anchor"></a><b>&#167;20.1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue the generic unknown wording message</span><span class="named-paragraph-number">20.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">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"In the sentence %1, I was expecting to read %3, but instead found some "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"text that I couldn't understand - '%2'. "</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP20_1">&#167;20.1</a>, <a href="5-dsh.html#SP20_2">&#167;20.2</a>, <a href="5-dsh.html#SP20_3">&#167;20.3</a>, <a href="5-dsh.html#SP20_4">&#167;20.4</a>, <a href="5-dsh.html#SP20_5">&#167;20.5</a>, <a href="5-dsh.html#SP20_6">&#167;20.6</a>, <a href="5-dsh.html#SP20_7">&#167;20.7</a>, <a href="5-dsh.html#SP20_8">&#167;20.8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_2_4" class="paragraph-anchor"></a><b>&#167;18.2.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem message for miscellaneous suspicious wordings</span><span class="named-paragraph-number">18.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">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_use_option</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="function-syntax">&lt;unknown-use-option-diagnosis&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="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::get_construct</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CON_activity</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="function-syntax">&lt;unknown-activity-diagnosis&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="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="function-syntax">&lt;unknown-value-problem-diagnosis&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>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP18_2">&#167;18.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_3" class="paragraph-anchor"></a><b>&#167;18.3. Rule (5.b). </b>This is all concerned with a shorthand far more convenient to an Inform author
than it is to us &mdash; where a property's name is used without any indication of
its owner.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (5.b) Deal with bare property names</span><span class="named-paragraph-number">18.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(5.b)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::get_construct</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">) != </span><span class="identifier-syntax">CON_property</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">check</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">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">check</span><span class="plain-syntax">, </span><span class="identifier-syntax">AMBIGUITY_NT</span><span class="plain-syntax">)) </span><span class="identifier-syntax">check</span><span class="plain-syntax"> = </span><span class="identifier-syntax">check</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><a href="2-rvl.html#SP21" class="function-link"><span class="function-syntax">Rvalues::is_CONSTANT_construction</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">check</span><span class="plain-syntax">, </span><span class="identifier-syntax">CON_property</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prn</span><span class="plain-syntax"> = </span><a href="2-rvl.html#SP3" class="function-link"><span class="function-syntax">Rvalues::to_property</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">check</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP18_3_1" class="named-paragraph-link"><span class="named-paragraph">Step (5.b.2) If a bare property name is used where we expect a value, coerce it if the kinds allow</span><span class="named-paragraph-number">18.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP18">&#167;18</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_3_1" class="paragraph-anchor"></a><b>&#167;18.3.1. </b>But more often we want a value which just happens in this case to come
from a property. For instance, in a text routine printing a description
like "The cedarwood box could hold [carrying capacity in words]
item[s].", we want "carrying capacity" to be a number value, and we
treat it as if it read "carrying capacity of the cedarwood box".
</p>
<p class="commentary">We don't coerce if the property holds a relation, because letting a variable
be a description of a relation tries to create a local relation on the
stack frame, and this is unlikely to be what anyone wanted.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (5.b.2) If a bare property name is used where we expect a value, coerce it if the kinds allow</span><span class="named-paragraph-number">18.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(5.b.2)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(5.b.2a)"</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">Properties::is_value_property</span><span class="plain-syntax">(</span><span class="identifier-syntax">prn</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(5.b.2b)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_if_coerced</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ValueProperties::kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">prn</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">verdict</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::compatible</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_if_coerced</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind_expected</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">verdict</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(5.b.2c)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP18_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Coerce into a property of the "self" object</span><span class="named-paragraph-number">18.3.1.1</span></a></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">verdict</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Kinds::get_construct</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CON_description</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::get_construct</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_if_coerced</span><span class="plain-syntax">) != </span><span class="identifier-syntax">CON_relation</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(5.b.2) coercing to description\n"</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">become</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::from_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kind_if_coerced</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">become</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::copy_in_place</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><a href="2-dsc.html#SP6" class="function-link"><span class="function-syntax">Descriptions::to_rvalue</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">become</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">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(5.b.2) declining to cast into property value form\n"</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">verdict</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP18_3">&#167;18.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_3_1_1" class="paragraph-anchor"></a><b>&#167;18.3.1.1. </b>The tricky part is working out what the implicitly meant object is, a
classic donkey anaphora-style problem in linguistics. We don't even begin
to solve that here: indeed the decision is taken rather indirectly, because
we simply compile code which uses Inform 6's <span class="extract"><span class="extract-syntax">self</span></span> variable to refer to
the owner. The I6 library and our own run-time code conspire to ensure that
<span class="extract"><span class="extract-syntax">self</span></span> is always equal to something sensible.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Coerce into a property of the "self" object</span><span class="named-paragraph-number">18.3.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">was</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</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">pr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::duplicate</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">pr</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</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">become</span><span class="plain-syntax"> = </span><a href="2-lvl.html#SP6" class="function-link"><span class="function-syntax">Lvalues::new_PROPERTY_VALUE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pr</span><span class="plain-syntax">, </span><a href="2-rvl.html#SP7" class="function-link"><span class="function-syntax">Rvalues::new_self_object_constant</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::copy</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">become</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">next_alternative</span><span class="plain-syntax"> = </span><span class="identifier-syntax">was</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(5.b) coercing PROPERTY to PROPERTY VALUE: $P\n"</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="5-dsh.html#SP18_3_1">&#167;18.3.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_4" class="paragraph-anchor"></a><b>&#167;18.4. Rule (5.c). </b>An unchecked SP can contain a proposition which, though valid as a
predicate calculus sentence, makes no sense for type reasons: for instance,
"the Orange Room is 10" compiles to a valid sentence but one in which the
binary predicate for equality is applied to incomparable SPs. To type-check,
we must prove that any proposition needed is valid on these grounds, and we
delegate that to "Type Check Propositions.w".
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (5.c) Deal with any attached proposition</span><span class="named-paragraph-number">18.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(5.c)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">desired_to</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::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">TEST_PROPOSITION_NT</span><span class="plain-syntax">)) </span><span class="identifier-syntax">desired_to</span><span class="plain-syntax"> = </span><span class="string-syntax">"be a condition"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-dsc.html#SP7" class="function-link"><span class="function-syntax">Descriptions::is_complex</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)) </span><span class="identifier-syntax">desired_to</span><span class="plain-syntax"> = </span><span class="string-syntax">"be a description"</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">desired_to</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">TypecheckPropositions::type_check</span><span class="plain-syntax">(</span><a href="2-spc.html#SP4" class="function-link"><span class="function-syntax">Specifications::to_proposition</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">TypecheckPropositions::tc_no_problem_reporting</span><span class="plain-syntax">())</span>
<span class="plain-syntax"> == </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(5.c) on $P failed proposition type-checking: $D\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><a href="2-spc.html#SP4" class="function-link"><span class="function-syntax">Specifications::to_proposition</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="constant-syntax">THIS_IS_A_GROSS_PROBLEM</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TypecheckPropositions::type_check</span><span class="plain-syntax">(</span><a href="2-spc.html#SP4" class="function-link"><span class="function-syntax">Specifications::to_proposition</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">TypecheckPropositions::tc_problem_reporting</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="identifier-syntax">desired_to</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">NEVER_MATCH</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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(5.c) Okay!"</span><span class="plain-syntax">); }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP18">&#167;18</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_5" class="paragraph-anchor"></a><b>&#167;18.5. Rule (5.d). </b>Something of a grab-bag, this one. What these three situations have in common
is that all use the typechecker to clarify ambiguities in syntax.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (5.d) Apply miscellaneous other coercions</span><span class="named-paragraph-number">18.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">IF_MODULE</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP18_5_1" class="named-paragraph-link"><span class="named-paragraph">Step (5.d.1) Coerce TEST ACTION to constant action</span><span class="named-paragraph-number">18.5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP18_5_2" class="named-paragraph-link"><span class="named-paragraph">Step (5.d.2) Coerce constant TEXT and TEXT ROUTINE to UNDERSTANDING</span><span class="named-paragraph-number">18.5.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP18_5_3" class="named-paragraph-link"><span class="named-paragraph">Step (5.d.3) Coerce a description to a value, if we expect a noun-like description</span><span class="named-paragraph-number">18.5.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP18_5_4" class="named-paragraph-link"><span class="named-paragraph">Step (5.d.4) Reject plausible but wrong uses due to use of inline-only types in phrases</span><span class="named-paragraph-number">18.5.4</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP18">&#167;18</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_5_1" class="paragraph-anchor"></a><b>&#167;18.5.1. </b>An action pattern can be an action if specific enough, and this is
crucial: it enables phrases such as "try taking the box" to work. When
such phrases are type-checked, they expect the argument to be a constant
action value, which is a specific action.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (5.d.1) Coerce TEST ACTION to constant action</span><span class="named-paragraph-number">18.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(5.d.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">AConditions::is_action_TEST_VALUE</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::compatible</span><span class="plain-syntax">(</span><span class="identifier-syntax">K_stored_action</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">explicit_action</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ea</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_constant_explicit_action</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ea</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">action_pattern</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ap</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_constant_action_pattern</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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">failure_code</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">ea</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ExplicitActions::from_action_pattern</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">failure_code</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">failure_code</span><span class="plain-syntax"> == </span><span class="identifier-syntax">UNDERSPECIFIC_EA_FAILURE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM</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_wording</span><span class="plain-syntax">(2, </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">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_ActionNotSpecific</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 '%2' is too vague to describe a specific action. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"%PIt has to be an exact instruction about what is being done, and "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"to what. For instance, 'taking the box' is fine, but 'dropping or "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"taking something openable' is not."</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="identifier-syntax">NEVER_MATCH</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">failure_code</span><span class="plain-syntax"> == </span><span class="identifier-syntax">OVERSPECIFIC_EA_FAILURE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM</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_wording</span><span class="plain-syntax">(2, </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">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_ActionTooSpecific</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 '%2' imposes too many restrictions on the "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"action to be carried out, by saying something about the "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"circumstances which you can't guarantee will be true. "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"%PSometimes this problem appears because I've misread text like "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'in ...' as a clause saying that the action takes place in a "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"particular room, when in fact it was part of the name of one of "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the items involved. If that's the problem, try using 'let' to "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"create a simpler name for it, and then rewrite the 'try' to use "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"that simpler name - the ambiguity should then vanish."</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="identifier-syntax">NEVER_MATCH</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">Node::copy_in_place</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="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="identifier-syntax">Node::set_kind_of_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_stored_action</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_constant_explicit_action</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">ea</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_constant_action_pattern</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">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Coerced to sa: $P\n"</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">ALWAYS_MATCH</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">condition_context</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">CONSTANT_NT</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::compatible</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_stored_action</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">val</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::duplicate</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::copy_in_place</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEST_VALUE_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">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">val</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">val</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"Coerced back again to sa: $P\n"</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">ALWAYS_MATCH</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="5-dsh.html#SP18_5">&#167;18.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_5_2" class="paragraph-anchor"></a><b>&#167;18.5.2. </b>The following applies only to literal text in double-quotes, which might
or might not include text substitutions in square brackets: if we check it
against "understanding", then we are trying to interpret it as a grammar
to parse rather than text to print. We need to coerce since these have very
different representations at run-time.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (5.d.2) Coerce constant TEXT and TEXT ROUTINE to UNDERSTANDING</span><span class="named-paragraph-number">18.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="identifier-syntax">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(5.d.2)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-rvl.html#SP21" class="function-link"><span class="function-syntax">Rvalues::is_CONSTANT_of_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_text</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">K_understanding</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_understanding</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::set_kind_of_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_understanding</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP18_5">&#167;18.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_5_3" class="paragraph-anchor"></a><b>&#167;18.5.3. </b>Another ambiguity is that the text "women who are in lighted rooms" in:
</p>
<blockquote>
<p>let N be the number of women who are in lighted rooms;</p>
</blockquote>
<p class="commentary">...is parsed as a description, a condition. But in
fact it's a noun here &mdash; it has to be a value, in fact, which can go into
the "number of..." phrase as an argument. We make this happen by coercing
it to a constant value, using the "description of..." constructor.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (5.d.3) Coerce a description to a value, if we expect a noun-like description</span><span class="named-paragraph-number">18.5.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(5.d.3)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">domain</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">Kinds::get_construct</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CON_description</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">domain</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::unary_construction_material</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_expected</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">domain</span><span class="plain-syntax">) &amp;&amp; (</span><a href="2-spc.html#SP3" class="function-link"><span class="function-syntax">Specifications::is_description</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">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(5.d.3) requiring description of %u\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">domain</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(5.d.3) finding description of %u\n"</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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">made_match</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">Kinds::compatible</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">domain</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) </span><span class="identifier-syntax">made_match</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="5-dsh.html#SP18_5_3_2" class="named-paragraph-link"><span class="named-paragraph">Throw out the wrong sort of description with a seldom-seen problem message</span><span class="named-paragraph-number">18.5.3.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">quantifier</span><span class="plain-syntax"> *</span><span class="identifier-syntax">q</span><span class="plain-syntax"> = </span><a href="2-dsc.html#SP9" class="function-link"><span class="function-syntax">Descriptions::get_quantifier</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="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">q</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">q</span><span class="plain-syntax"> != </span><span class="identifier-syntax">not_exists_quantifier</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">q</span><span class="plain-syntax"> != </span><span class="identifier-syntax">for_all_quantifier</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP18_5_3_1" class="named-paragraph-link"><span class="named-paragraph">Issue a problem message for a quantified proposition in the description</span><span class="named-paragraph-number">18.5.3.1</span></a></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">as_con</span><span class="plain-syntax"> = </span><a href="2-dsc.html#SP6" class="function-link"><span class="function-syntax">Descriptions::to_rvalue</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">as_con</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="5-dsh.html#SP18_5_3_3" class="named-paragraph-link"><span class="named-paragraph">Issue a problem message for a malformed proposition in the description</span><span class="named-paragraph-number">18.5.3.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Node::copy_in_place</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">as_con</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">ALWAYS_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP18_5">&#167;18.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_5_3_1" class="paragraph-anchor"></a><b>&#167;18.5.3.1. </b>This is for undescriptive descriptions, really.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem message for a quantified proposition in the description</span><span class="named-paragraph-number">18.5.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="constant-syntax">THIS_IS_AN_INTERESTING_PROBLEM</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_wording</span><span class="plain-syntax">(2, </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">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_BadQuantifierInDescription</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 %1 you wrote the description '%2' in the context of a value, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"but descriptions used that way are not allowed to talk about "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"quantities. For example, it's okay to write 'an even number' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"as a description value, but not 'three numbers' or 'most numbers'."</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="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP18_5_3">&#167;18.5.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_5_3_2" class="paragraph-anchor"></a><b>&#167;18.5.3.2. </b>The following message is seldom seen since most phrases using descriptions
are set up with two parallel versions. As every description matches exactly one
of these, there won't be a problem. But just in case the user has intentionally
defined a phrase for only one case:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Throw out the wrong sort of description with a seldom-seen problem message</span><span class="named-paragraph-number">18.5.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">made_match</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</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_wording</span><span class="plain-syntax">(2, </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">Problems::quote_kind</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">domain</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">BelievedImpossible</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 line %1, the text '%2' seems to be a description of %3, but "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"a description of %4 was required."</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="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP18_5_3">&#167;18.5.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_5_3_3" class="paragraph-anchor"></a><b>&#167;18.5.3.3. </b>I can't see an easy proof that this can never occur, but nor can I make it
happen. The problem message is just in case someone finds a way. It appears
if the description has a proposition with other than one free variable, once
any universal quantifier ("all", etc.) is removed.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue a problem message for a malformed proposition in the description</span><span class="named-paragraph-number">18.5.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="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</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_wording</span><span class="plain-syntax">(2, </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">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">BelievedImpossible</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 line %1, the text '%2' is given where a description of a collection "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"of things or values was required. For instance, 'rooms which contain "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"something', or 'closed containers' - note that there is no need to say "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"'all' or 'every' in this context, as that is understood already."</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="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP18_5_3">&#167;18.5.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_5_4" class="paragraph-anchor"></a><b>&#167;18.5.4. </b>It might look as if this ought to be checked when phrase definitions are
made; the trouble is, "action", "condition" and so on are valid
in phrase definitions, but only in inline-defined ones. We don't want to get
into all that here, because the message is aimed more at Inform novices who
have made an understandable confusion.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (5.d.4) Reject plausible but wrong uses due to use of inline-only types in phrases</span><span class="named-paragraph-number">18.5.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><a href="2-lvl.html#SP8" class="function-link"><span class="function-syntax">Lvalues::is_lvalue</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">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</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_wording</span><span class="plain-syntax">(2, </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">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">BelievedImpossible</span><span class="plain-syntax">)); </span><span class="comment-syntax"> screened out at definition time</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 line %1, '%2' ought to be a value, but isn't - there must be "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"something fishy about the way it was created. %P"</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Usually this happens because it is one of the named items in "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"a phrase definition, but stood for a chunk of text which can't "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"be a value - for instance, 'To marvel at (feat - an action)' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"doesn't make 'feat' a value. (Calling it a 'stored action' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"would have been fine; and similarly, if you want something "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"which is either true or false, use 'truth state' not 'condition'.)"</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="identifier-syntax">NEVER_MATCH</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="5-dsh.html#SP18_5">&#167;18.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_6" class="paragraph-anchor"></a><b>&#167;18.6. Rule (5.e). </b>The "main rule" is, as we shall see, that <span class="extract"><span class="extract-syntax">p</span></span> should have the same
species as <span class="extract"><span class="extract-syntax">expected</span></span>, or if <span class="extract"><span class="extract-syntax">expected</span></span> give no species then at least it
should have the same family. The two exceptional cases are when <span class="extract"><span class="extract-syntax">expected</span></span>
is a description such as "an even number", or the name of a kind of value
such as "a scene", in which case we allow <span class="extract"><span class="extract-syntax">p</span></span> if it's a value which
meets these requirements.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (5.e) The Main Rule of Type-Checking</span><span class="named-paragraph-number">18.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">exceptional_case</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="5-dsh.html#SP18_6_1" class="named-paragraph-link"><span class="named-paragraph">Step (5.e.2) Exception: when expecting a generic or actual CONSTANT</span><span class="named-paragraph-number">18.6.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">exceptional_case</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="5-dsh.html#SP18_6_2" class="named-paragraph-link"><span class="named-paragraph">Step (5.e.3) Main rule</span><span class="named-paragraph-number">18.6.2</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP18">&#167;18</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_6_1" class="paragraph-anchor"></a><b>&#167;18.6.1. </b>Now for the related, but slightly simpler, case of matching the name of a
kind. Suppose we are parsing "award 5 points" against
</p>
<blockquote>
<p>To award (N - a number) points: ...</p>
</blockquote>
<p class="commentary">Here <span class="extract"><span class="extract-syntax">p</span></span> will be the actual constant value 5, and <span class="extract"><span class="extract-syntax">expected</span></span> the
generic constant value with kind "number".
</p>
<p class="commentary">A phrase which returns a value must have its own return value's kind
checked. Unfortunately we can't do that yet: we want to wait until
recursive type-checking has removed incorrect invocations before drawing a
conclusion about the return kind of the phrase.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (5.e.2) Exception: when expecting a generic or actual CONSTANT</span><span class="named-paragraph-number">18.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(5.e.2)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">) &amp;&amp; (</span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::is_value</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">PHRASE_TO_DECIDE_VALUE_NT</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"(5.e.2) exempting phrase from return value checking for now\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::compatible</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</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">kind_expected</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">NEVER_MATCH:</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP18_6_1_1" class="named-paragraph-link"><span class="named-paragraph">Fail with a mismatched value problem message</span><span class="named-paragraph-number">18.6.1.1</span></a></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">SOMETIMES_MATCH:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">outcome</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SOMETIMES_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING</span><span class="plain-syntax">, </span><span class="string-syntax">"dropping to sometimes level\n"</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">outcome</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="identifier-syntax">ALWAYS_MATCH:</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="identifier-syntax">exceptional_case</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="5-dsh.html#SP18_6">&#167;18.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_6_1_1" class="paragraph-anchor"></a><b>&#167;18.6.1.1. </b>This is the error message a typical C compiler's type-checker would issue;
it says the value has the wrong kind.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Fail with a mismatched value problem message</span><span class="named-paragraph-number">18.6.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="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</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">"Offending subtree: $T\n"</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">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_wording</span><span class="plain-syntax">(2, </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">Problems::quote_kind</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">LOCAL_VARIABLE_NT</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_constant_local_variable</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">Problems::quote_kind</span><span class="plain-syntax">(4, </span><span class="identifier-syntax">LocalVariables::kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">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_LocalMismatch</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 '%2' is a temporary name for %4 (created by 'let' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"or 'repeat'), whereas I was expecting to find %3 there."</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_sayable_value</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(4, </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</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">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_AllSayInvsFailed</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::empty</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">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"You wrote %1, but that only works for sayable values, that is, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"values which I can display in text form. '%2' isn't one of those "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"values: it's %4, a kind which isn't sayable."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"You wrote %1, but that only works for sayable values, that is, "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"values which I can display in text form. This isn't one of those "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"values: it's %4, a kind which isn't sayable."</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="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Found: %u; Expected: %u\n"</span><span class="plain-syntax">, </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</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">kind_expected</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind</span><span class="plain-syntax">(4, </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</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">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_TypeMismatch</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::empty</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">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"You wrote %1, but that has the wrong kind of value: %4 rather than %3."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"You wrote %1, but '%2' has the wrong kind of value: %4 rather than %3."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP18_6_1">&#167;18.6.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_6_2" class="paragraph-anchor"></a><b>&#167;18.6.2. </b>We now apply the main rule, supposing that neither of the exceptional cases
has intervened to stop us getting here. The found and expected specifications
must have the same family and, unless the expected species is <span class="extract"><span class="extract-syntax">UNKNOWN_NT</span></span>, the
same species as well.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Step (5.e.3) Main rule</span><span class="named-paragraph-number">18.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">LOG_DASH</span><span class="plain-syntax">(</span><span class="string-syntax">"(5.e.3)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">condition_context</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">condition_found</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><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::is_condition</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)) </span><span class="identifier-syntax">condition_found</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">condition_found</span><span class="plain-syntax"> != </span><span class="identifier-syntax">condition_context</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-spc.html#SP3" class="function-link"><span class="function-syntax">Specifications::is_description</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP18_6_2_1" class="named-paragraph-link"><span class="named-paragraph">Fail with a warning about literal descriptions</span><span class="named-paragraph-number">18.6.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="5-dsh.html#SP18_6_2_2" class="named-paragraph-link"><span class="named-paragraph">Fail with a catch-all typechecking problem message</span><span class="named-paragraph-number">18.6.2.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP18_6">&#167;18.6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_6_2_1" class="paragraph-anchor"></a><b>&#167;18.6.2.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Fail with a warning about literal descriptions</span><span class="named-paragraph-number">18.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="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-dsc.html#SP7" class="function-link"><span class="function-syntax">Descriptions::is_complex</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="constant-syntax">THIS_IS_AN_INTERESTING_PROBLEM</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_wording</span><span class="plain-syntax">(2, </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">Problems::quote_kind</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind_of</span><span class="plain-syntax">(4, </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_GenericDescription</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 '%2' is used in a context where I'd expect to see "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"a (single) specific example of %3. Although what you wrote did "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"make sense as a description, it could refer to many different "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"values or to none, so it wasn't specific enough."</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="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="constant-syntax">THIS_IS_AN_INTERESTING_PROBLEM</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_wording</span><span class="plain-syntax">(2, </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">Problems::quote_kind</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind_of</span><span class="plain-syntax">(4, </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_LiteralDescriptionAsValue</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 '%2' is used in a context where I'd expect to see "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"a (single) specific example of %3, not a description."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-spc.html#SP2" class="function-link"><span class="function-syntax">Specifications::is_kind_like</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">), </span><span class="identifier-syntax">K_time</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">" %P(If you meant the current time, this is called 'time "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"of day' in Inform to avoid confusing it with the various "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"other meanings that the word 'time' can have.)"</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="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP18_6_2">&#167;18.6.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_6_2_2" class="paragraph-anchor"></a><b>&#167;18.6.2.2. </b>This is the general-purpose Problem message to which the type-checker
resorts when it has nothing more specific to say.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Fail with a catch-all typechecking problem message</span><span class="named-paragraph-number">18.6.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="constant-syntax">THIS_IS_AN_ORDINARY_PROBLEM</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_wording</span><span class="plain-syntax">(2, </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">Problems::quote_kind</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">kind_expected</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind_of</span><span class="plain-syntax">(4, </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">BelievedImpossible</span><span class="plain-syntax">)); </span><span class="comment-syntax"> at any rate I haven't seen it lately</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 '%2' seems to be %4, whereas I was expecting to "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"find %3 there."</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="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP18_6_2">&#167;18.6.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>&#167;21. Ambiguity testing flags. </b>To avoid filling the parse tree with unnecessary annotations, we apply these
only when resolving ambiguities, in (4A) above.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">PASSED_DASHFLAG</span><span class="plain-syntax"> </span><span class="constant-syntax">0x00000001</span><span class="plain-syntax"> </span><span class="comment-syntax"> once type-checked: did this pass type checking?</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">UNPROVEN_DASHFLAG</span><span class="plain-syntax"> </span><span class="constant-syntax">0x00000002</span><span class="plain-syntax"> </span><span class="comment-syntax"> once type-checked: will this need run-time checking?</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">GROSSLY_FAILED_DASHFLAG</span><span class="plain-syntax"> </span><span class="constant-syntax">0x00000004</span><span class="plain-syntax"> </span><span class="comment-syntax"> once type-checked: oh, this one failed big time</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">TESTED_DASHFLAG</span><span class="plain-syntax"> </span><span class="constant-syntax">0x00000008</span><span class="plain-syntax"> </span><span class="comment-syntax"> has been type-checked</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">INTERESTINGLY_FAILED_DASHFLAG</span><span class="plain-syntax"> </span><span class="constant-syntax">0x00000010</span><span class="plain-syntax"> </span><span class="comment-syntax"> an interesting problem message could be produced about the way this failed</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::reading_passed</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">Dash::reading_passed</span></span>:<br/><a href="5-dsh.html#SP9_1_1_3_1_2">&#167;9.1.1.3.1.2</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><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::test_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">PASSED_DASHFLAG</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::test_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">TESTED_DASHFLAG</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</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">return</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">char</span><span class="plain-syntax"> *</span><span class="function-syntax">Dash::verdict_to_text</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">Dash::verdict_to_text</span></span>:<br/><a href="5-dsh.html#SP10_9_2_2">&#167;10.9.2.2</a><br/>Invocations - <a href="4-inv.html#SP18">&#167;18</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><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">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"(no node)"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">verdict</span><span class="plain-syntax"> = </span><span class="string-syntax">"untested"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::test_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">TESTED_DASHFLAG</span><span class="plain-syntax">)) </span><span class="identifier-syntax">verdict</span><span class="plain-syntax"> = </span><span class="string-syntax">"failed"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::test_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">INTERESTINGLY_FAILED_DASHFLAG</span><span class="plain-syntax">)) </span><span class="identifier-syntax">verdict</span><span class="plain-syntax"> = </span><span class="string-syntax">"interesting"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::test_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">GROSSLY_FAILED_DASHFLAG</span><span class="plain-syntax">)) </span><span class="identifier-syntax">verdict</span><span class="plain-syntax"> = </span><span class="string-syntax">"gross"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::test_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">PASSED_DASHFLAG</span><span class="plain-syntax">)) </span><span class="identifier-syntax">verdict</span><span class="plain-syntax"> = </span><span class="string-syntax">"proven"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::test_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">UNPROVEN_DASHFLAG</span><span class="plain-syntax">)) </span><span class="identifier-syntax">verdict</span><span class="plain-syntax"> = </span><span class="string-syntax">"unproven"</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">verdict</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="function-syntax">Dash::quick_verdict_to_text</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">Dash::quick_verdict_to_text</span></span>:<br/><a href="5-dsh.html#SP10_9_2_2">&#167;10.9.2.2</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><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">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"?"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">verdict</span><span class="plain-syntax"> = </span><span class="string-syntax">"-"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::test_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">TESTED_DASHFLAG</span><span class="plain-syntax">)) </span><span class="identifier-syntax">verdict</span><span class="plain-syntax"> = </span><span class="string-syntax">"f"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::test_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">INTERESTINGLY_FAILED_DASHFLAG</span><span class="plain-syntax">)) </span><span class="identifier-syntax">verdict</span><span class="plain-syntax"> = </span><span class="string-syntax">"i"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::test_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">GROSSLY_FAILED_DASHFLAG</span><span class="plain-syntax">)) </span><span class="identifier-syntax">verdict</span><span class="plain-syntax"> = </span><span class="string-syntax">"g"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::test_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">PASSED_DASHFLAG</span><span class="plain-syntax">)) </span><span class="identifier-syntax">verdict</span><span class="plain-syntax"> = </span><span class="string-syntax">"p"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP22" class="function-link"><span class="function-syntax">Dash::test_flag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">UNPROVEN_DASHFLAG</span><span class="plain-syntax">)) </span><span class="identifier-syntax">verdict</span><span class="plain-syntax"> = </span><span class="string-syntax">"u"</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">verdict</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP22" class="paragraph-anchor"></a><b>&#167;22. </b>The bitmap holding the results of typechecking:
</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">Dash::set_flag</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">Dash::set_flag</span></span>:<br/><a href="5-dsh.html#SP10_9_2_2_1">&#167;10.9.2.2.1</a>, <a href="5-dsh.html#SP10_9_1_1">&#167;10.9.1.1</a>, <a href="5-dsh.html#SP10_9_1_1_11">&#167;10.9.1.1.11</a>, <a href="5-dsh.html#SP10_9_1_1_12">&#167;10.9.1.1.12</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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">flag</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">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to set flag for null p"</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">bm</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">epistemological_status_ANNOT</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">epistemological_status_ANNOT</span><span class="plain-syntax">, </span><span class="identifier-syntax">bm</span><span class="plain-syntax"> | </span><span class="identifier-syntax">flag</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">Dash::clear_flags</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">Dash::clear_flags</span></span>:<br/><a href="5-dsh.html#SP10_9_2_1_1">&#167;10.9.2.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><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">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to clear flags for null 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">epistemological_status_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="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::clear_flag</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">flag</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">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to clear flag for null p"</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">bm</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">epistemological_status_ANNOT</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">epistemological_status_ANNOT</span><span class="plain-syntax">, </span><span class="identifier-syntax">bm</span><span class="plain-syntax"> &amp; (~</span><span class="identifier-syntax">flag</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::test_flag</span><button class="popup" onclick="togglePopup('usagePopup18')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup18">Usage of <span class="code-font"><span class="function-syntax">Dash::test_flag</span></span>:<br/><a href="5-dsh.html#SP10_9_2_2">&#167;10.9.2.2</a>, <a href="5-dsh.html#SP10_9_2_3_1">&#167;10.9.2.3.1</a>, <a href="5-dsh.html#SP10_9_1_1_5_2">&#167;10.9.1.1.5.2</a>, <a href="5-dsh.html#SP14_1">&#167;14.1</a>, <a href="5-dsh.html#SP21">&#167;21</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="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">flag</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">bm</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">p</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">epistemological_status_ANNOT</span><span class="plain-syntax">)):0;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bm</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">flag</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>&#167;23. </b>A convenience sometimes needed for checking conditional clauses, like the
"when..." attached to action patterns:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::validate_conditional_clause</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">spec</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">spec</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</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">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">UNKNOWN_NT</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</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><a href="5-dsh.html#SP8" class="function-link"><span class="function-syntax">Dash::check_condition</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP24" class="paragraph-anchor"></a><b>&#167;24. </b>The exceptional treatment of the "property" kind below is to allow
"examining scenery" to be an action pattern, where an either/or property
has a name which is really a noun rather than an adjective, luring people
into treating it as such.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">last_spec_failing_to_validate</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">last_kind_failing_to_validate</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">last_kind_found_failing_to_validate</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::clear_validation_case</span><button class="popup" onclick="togglePopup('usagePopup19')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup19">Usage of <span class="code-font"><span class="function-syntax">Dash::clear_validation_case</span></span>:<br/><a href="5-dsh.html#SP18_2_1">&#167;18.2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_spec_failing_to_validate</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">last_kind_failing_to_validate</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">last_kind_found_failing_to_validate</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="function-syntax">Dash::get_validation_case</span><button class="popup" onclick="togglePopup('usagePopup20')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup20">Usage of <span class="code-font"><span class="function-syntax">Dash::get_validation_case</span></span>:<br/><a href="5-dsh.html#SP18_2_1">&#167;18.2.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">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> **</span><span class="identifier-syntax">set_K</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> **</span><span class="identifier-syntax">set_K2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">spec</span><span class="plain-syntax"> = </span><span class="identifier-syntax">last_spec_failing_to_validate</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">set_K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">last_kind_failing_to_validate</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">set_K2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">last_kind_found_failing_to_validate</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((*</span><span class="identifier-syntax">spec</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (*</span><span class="identifier-syntax">set_K</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</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">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::validate_parameter</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</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">vts</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kind_found</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">spec</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="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">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">UNKNOWN_NT</span><span class="plain-syntax">)) </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">DontValidate</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-spc.html#SP3" class="function-link"><span class="function-syntax">Specifications::is_description</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pcalc_prop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prop</span><span class="plain-syntax"> = </span><a href="2-dsc.html#SP1" class="function-link"><span class="function-syntax">Descriptions::to_proposition</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">prop</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Binding::number_free</span><span class="plain-syntax">(</span><span class="identifier-syntax">prop</span><span class="plain-syntax">) != </span><span class="constant-syntax">1</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-spc.html#SP3" class="function-link"><span class="function-syntax">Specifications::is_description</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">)) </span><a href="5-dsh.html#SP8" class="function-link"><span class="function-syntax">Dash::check_condition</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><a href="5-dsh.html#SP8" class="function-link"><span class="function-syntax">Dash::check_value</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">); </span><span class="comment-syntax"> to force a generic return kind to be evaluated</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind_found</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Kinds::get_construct</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_found</span><span class="plain-syntax">) == </span><span class="identifier-syntax">CON_property</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Kinds::Behaviour::is_object</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">return</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">K_understanding</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_found</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_snippet</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_understanding</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</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">K_understanding</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_understanding</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">CONSTANT_NT</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_found</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_text</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">DontValidate</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">vts</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::from_kind</span></a><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><a href="5-dsh.html#SP26" class="function-link"><span class="function-syntax">Dash::compatible_with_description</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">vts</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">K_understanding</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_understanding</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">CONSTANT_NT</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">vts</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::from_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K_snippet</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-dsh.html#SP26" class="function-link"><span class="function-syntax">Dash::compatible_with_description</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">vts</span><span class="plain-syntax">) != </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</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">Kinds::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">kind_found</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_value</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="comment-syntax"> pick up later in type-checking</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">DontValidate</span><span class="plain-syntax">;</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">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DontValidate:</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_spec_failing_to_validate</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_kind_failing_to_validate</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">last_kind_found_failing_to_validate</span><span class="plain-syntax"> = </span><span class="identifier-syntax">kind_found</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">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP25" class="paragraph-anchor"></a><b>&#167;25. </b>This is the state of the <span class="extract"><span class="extract-syntax">***</span></span> pseudo-phrase used for debugging:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">verbose_checking_state</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::tracing_phrases</span><button class="popup" onclick="togglePopup('usagePopup21')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup21">Usage of <span class="code-font"><span class="function-syntax">Dash::tracing_phrases</span></span>:<br/><a href="5-dsh.html#SP28_1">&#167;28.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</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">text</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">text</span><span class="plain-syntax">[0])) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">LT</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">LT</span><span class="plain-syntax">, </span><span class="string-syntax">"%w"</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Log::set_aspect_from_command_line</span><span class="plain-syntax">(</span><span class="identifier-syntax">LT</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">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">LT</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">verbose_checking_state</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">verbose_checking_state</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">verbose_checking_state</span><span class="plain-syntax">)?</span><span class="identifier-syntax">FALSE: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">verbose_checking_state</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::set_all_aspects</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">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Log::set_aspect</span><span class="plain-syntax">(</span><span class="identifier-syntax">MATCHING_DA</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">Log::set_aspect</span><span class="plain-syntax">(</span><span class="identifier-syntax">KIND_CHECKING_DA</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">Log::set_aspect</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOCAL_VARIABLES_DA</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP26" class="paragraph-anchor"></a><b>&#167;26. Value checking. </b>The following adapts the above test to attempt to match two specifications
together: for example, to match "12" against "even number". This, rather
surprisingly, returns <span class="extract"><span class="extract-syntax">SOMETIMES_MATCH</span></span>, since we find that the kinds
are guaranteed &mdash; 12 is indeed a number &mdash; but Inform doesn't "know" the
meaning of the word "even", only that it's a test which will be applied
at run time.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::compatible_with_description</span><button class="popup" onclick="togglePopup('usagePopup22')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup22">Usage of <span class="code-font"><span class="function-syntax">Dash::compatible_with_description</span></span>:<br/><a href="5-dsh.html#SP10_5">&#167;10.5</a>, <a href="5-dsh.html#SP24">&#167;24</a><br/>Specifications - <a href="2-spc.html#SP9_5">&#167;9.5</a><br/>Descriptions - <a href="2-dsc.html#SP12_2">&#167;12.2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from_spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to_spec</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">KIND_CHECKING</span><span class="plain-syntax">, </span><span class="string-syntax">"[Can we match from: $P to: $P?]\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">from_spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">to_spec</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">from_spec</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::to_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">to_spec</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">result</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEVER_MATCH</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">from</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">to</span><span class="plain-syntax">)) </span><span class="identifier-syntax">result</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Kinds::compatible</span><span class="plain-syntax">(</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="identifier-syntax">to</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">to</span><span class="plain-syntax">) </span><span class="identifier-syntax">result</span><span class="plain-syntax"> = </span><span class="identifier-syntax">SOMETIMES_MATCH</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-dsc.html#SP7" class="function-link"><span class="function-syntax">Descriptions::is_qualified</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">to_spec</span><span class="plain-syntax">)) || (</span><a href="2-dsc.html#SP5" class="function-link"><span class="function-syntax">Descriptions::to_instance</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">to_spec</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax"> = </span><a href="5-dsh.html#SP7" class="function-link"><span class="function-syntax">Dash::worst_case</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">result</span><span class="plain-syntax">, </span><span class="identifier-syntax">SOMETIMES_MATCH</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">result</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">ALWAYS_MATCH:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">KIND_CHECKING</span><span class="plain-syntax">, </span><span class="string-syntax">"[Always]\n"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">SOMETIMES_MATCH:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">KIND_CHECKING</span><span class="plain-syntax">, </span><span class="string-syntax">"[Sometimes]\n"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">NEVER_MATCH:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">KIND_CHECKING</span><span class="plain-syntax">, </span><span class="string-syntax">"[Never]\n"</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP27" class="paragraph-anchor"></a><b>&#167;27. Ambiguous alternatives. </b></p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">AMBIGUITY_JOIN_SYNTAX_CALLBACK</span><span class="plain-syntax"> </span><a href="5-dsh.html#SP27" class="function-link"><span class="function-syntax">Dash::ambiguity_join</span></a>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::ambiguity_join</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">existing</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">reading</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-spc.html#SP1" class="function-link"><span class="function-syntax">Specifications::is_phrasal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">reading</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">reading</span><span class="plain-syntax">) == </span><span class="identifier-syntax">Node::get_type</span><span class="plain-syntax">(</span><span class="identifier-syntax">existing</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><a href="5-dsh.html#SP27" class="function-link"><span class="function-syntax">Dash::add_pr_inv</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">existing</span><span class="plain-syntax">, </span><span class="identifier-syntax">reading</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">TRUE</span><span class="plain-syntax">;</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">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">Dash::add_pr_inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">reading</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">N</span><span class="plain-syntax"> = </span><span class="identifier-syntax">reading</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">next_N</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">N</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">N</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax">):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">N</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax"> = </span><span class="identifier-syntax">next_N</span><span class="plain-syntax">, </span><span class="identifier-syntax">next_N</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">N</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">N</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax">):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="5-dsh.html#SP27" class="function-link"><span class="function-syntax">Dash::add_single_pr_inv</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">N</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Dash::add_single_pr_inv</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">N</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><span class="identifier-syntax">E</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="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-inv.html#SP17" class="function-link"><span class="function-syntax">Invocations::same_phrase_and_tokens</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">N</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">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">E</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-inv.html#SP17" class="function-link"><span class="function-syntax">Invocations::same_phrase_and_tokens</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">N</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="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax"> = </span><span class="identifier-syntax">N</span><span class="plain-syntax">; </span><span class="identifier-syntax">N</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP28" class="paragraph-anchor"></a><b>&#167;28. Internal testing. </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">Dash::perform_dash_internal_test</span><button class="popup" onclick="togglePopup('usagePopup23')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup23">Usage of <span class="code-font"><span class="function-syntax">Dash::perform_dash_internal_test</span></span>:<br/>Values Module - <a href="1-vm.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_test_case</span><span class="plain-syntax"> *</span><span class="identifier-syntax">itc</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">full</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">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">itc</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">text_supplying_the_case</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP28_1" class="named-paragraph-link"><span class="named-paragraph">Perform a Dash internal test</span><span class="named-paragraph-number">28.1</span></a></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">Dash::perform_dashlog_internal_test</span><button class="popup" onclick="togglePopup('usagePopup24')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup24">Usage of <span class="code-font"><span class="function-syntax">Dash::perform_dashlog_internal_test</span></span>:<br/>Values Module - <a href="1-vm.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_test_case</span><span class="plain-syntax"> *</span><span class="identifier-syntax">itc</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">full</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">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">itc</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">text_supplying_the_case</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="5-dsh.html#SP28_1" class="named-paragraph-link"><span class="named-paragraph">Perform a Dash internal test</span><span class="named-paragraph-number">28.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP28_1" class="paragraph-anchor"></a><b>&#167;28.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Perform a Dash internal test</span><span class="named-paragraph-number">28.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">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">test_tree</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">last_alt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="function-syntax">&lt;s-value-uncached&gt;-&gt;</span><span class="identifier-syntax">multiplicitous</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="function-syntax">&lt;s-value-uncached&gt;-&gt;</span><span class="identifier-syntax">ins</span><span class="plain-syntax">.</span><span class="identifier-syntax">watched</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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</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">T</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="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">T</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">W</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="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;k-kind&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">)) </span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;rp&gt;&gt;</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;s-value-uncached&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;rp&gt;&gt;</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">last_alt</span><span class="plain-syntax">) </span><span class="identifier-syntax">last_alt</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_alternative</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">test_tree</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">last_alt</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">n</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Failed to parse: %W\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="function-syntax">&lt;s-value-uncached&gt;-&gt;</span><span class="identifier-syntax">multiplicitous</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="function-syntax">&lt;s-value-uncached&gt;-&gt;</span><span class="identifier-syntax">ins</span><span class="plain-syntax">.</span><span class="identifier-syntax">watched</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">n</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">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">holder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">AMBIGUITY_NT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">holder</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">test_tree</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">test_tree</span><span class="plain-syntax"> = </span><span class="identifier-syntax">holder</span><span class="plain-syntax">;</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">"$m\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">test_tree</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Dash: value of kind %u\n"</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">full</span><span class="plain-syntax">) </span><a href="5-dsh.html#SP25" class="function-link"><span class="function-syntax">Dash::tracing_phrases</span></a><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">rv</span><span class="plain-syntax"> = </span><a href="5-dsh.html#SP8" class="function-link"><span class="function-syntax">Dash::check_value</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">test_tree</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">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">trv</span><span class="plain-syntax"> = </span><span class="string-syntax">"ALWAYS"</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">rv</span><span class="plain-syntax"> == </span><span class="identifier-syntax">SOMETIMES_MATCH</span><span class="plain-syntax">) </span><span class="identifier-syntax">trv</span><span class="plain-syntax"> = </span><span class="string-syntax">"SOMETIMES"</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">rv</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NEVER_MATCH</span><span class="plain-syntax">) </span><span class="identifier-syntax">trv</span><span class="plain-syntax"> = </span><span class="string-syntax">"NEVER"</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">"Result: %s\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">trv</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">full</span><span class="plain-syntax">) </span><a href="5-dsh.html#SP25" class="function-link"><span class="function-syntax">Dash::tracing_phrases</span></a><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">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"$m\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">test_tree</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-dsh.html#SP28">&#167;28</a> (twice).</li></ul>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="4-pi.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-vm.html">1</a></li><li class="progresschapter"><a href="2-spc.html">2</a></li><li class="progresschapter"><a href="3-pl.html">3</a></li><li class="progresschapter"><a href="4-ets.html">4</a></li><li class="progresscurrentchapter">5</li><li class="progresscurrent">dsh</li><li class="progressnextoff">&#10095;</li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>