mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 22:14:23 +03:00
771 lines
92 KiB
HTML
771 lines
92 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>2/pl2</title>
|
|
<meta name="viewport" content="width=device-width initial-scale=1">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
</head>
|
|
<body>
|
|
<nav role="navigation">
|
|
<h1><a href="../webs.html">Sources</a></h1>
|
|
<ul>
|
|
<li><a href="../compiler.html"><b>compiler tools</b></a></li>
|
|
<li><a href="../other.html">other tools</a></li>
|
|
<li><a href="../extensions.html">extensions and kits</a></li>
|
|
<li><a href="../units.html">unit test tools</a></li>
|
|
</ul>
|
|
<h2>Compiler Webs</h2>
|
|
<ul>
|
|
<li><a href="../inbuild/index.html">inbuild</a></li>
|
|
<li><a href="../inform7/index.html">inform7</a></li>
|
|
<li><a href="../inter/index.html">inter</a></li>
|
|
</ul>
|
|
<h2>Inbuild Modules</h2>
|
|
<ul>
|
|
<li><a href="../inbuild-module/index.html">inbuild</a></li>
|
|
<li><a href="../arch-module/index.html">arch</a></li>
|
|
<li><a href="../words-module/index.html">words</a></li>
|
|
<li><a href="../syntax-module/index.html">syntax</a></li>
|
|
<li><a href="../html-module/index.html">html</a></li>
|
|
</ul>
|
|
<h2>Inform7 Modules</h2>
|
|
<ul>
|
|
<li><a href="../core-module/index.html">core</a></li>
|
|
<li><a href="../problems-module/index.html">problems</a></li>
|
|
<li><a href="../inflections-module/index.html">inflections</a></li>
|
|
<li><a href="../linguistics-module/index.html">linguistics</a></li>
|
|
<li><a href="../kinds-module/index.html">kinds</a></li>
|
|
<li><a href="../if-module/index.html">if</a></li>
|
|
<li><a href="../multimedia-module/index.html">multimedia</a></li>
|
|
<li><a href="../index-module/index.html">index</a></li>
|
|
</ul>
|
|
<h2>Inter Modules</h2>
|
|
<ul>
|
|
<li><a href="../inter-module/index.html">inter</a></li>
|
|
<li><a href="../building-module/index.html">building</a></li>
|
|
<li><a href="../codegen-module/index.html">codegen</a></li>
|
|
</ul>
|
|
<h2>Foundation</h2>
|
|
<ul>
|
|
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
|
|
</ul>
|
|
|
|
|
|
</nav>
|
|
<main role="main">
|
|
|
|
<!--Weave of '2/pl3' generated by 7-->
|
|
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Modules</a></li><li><a href="index.html">problems</a></li><li><a href="index.html#2">Chapter 2: Problems</a></li><li><b>Problems, Level 3</b></li></ul><p class="purpose">Here we provide some convenient semi-standardised problem messages, which also serve as examples of how to use the Level 2 problem message routines.</p>
|
|
|
|
<ul class="toc"><li><a href="#SP4">§4. Nodal errors</a></li><li><a href="#SP8">§8. Sigils</a></li><li><a href="#SP11">§11. Handmade problems</a></li><li><a href="#SP12">§12. Limit problems</a></li><li><a href="#SP13">§13. Problem messages unlocated in the source text</a></li><li><a href="#SP15">§15. Problem messages keyed to positions in the source text</a></li><li><a href="#SP20">§20. Definition problems</a></li><li><a href="#SP21">§21. Creating the Problems report</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. </b>The following internal errors should never occur, whatever the provocation:
|
|
if they do, they are symptoms of incorrect code in NI.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The internal error "functions" used by the rest of NI are in fact macros,
|
|
in order that they can supply the current filename and line number
|
|
automatically to the actual internal error functions. The result is, for
|
|
instance,
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Problem. An internal error has occurred: Unknown verb code. The current sentence is "A room is a kind"; the error was detected at line 133 of "Chapter 5/Traverse for Objects.w". This should never happen, and I am now halting in abject failure.</p>
|
|
|
|
</blockquote>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="identifier">internal_error_tree_unsafe</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">) </span><span class="functiontext">Problems::Issue::internal_error_tu_fn</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">__FILE__</span><span class="plain">, </span><span class="identifier">__LINE__</span><span class="plain">)</span>
|
|
<span class="definitionkeyword">define</span> <span class="identifier">internal_error_if_node_type_wrong</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">Y</span><span class="plain">) </span><span class="functiontext">Problems::Issue::nodal_check</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">Y</span><span class="plain">, </span><span class="identifier">__FILE__</span><span class="plain">, </span><span class="identifier">__LINE__</span><span class="plain">)</span>
|
|
<span class="definitionkeyword">define</span> <span class="identifier">internal_error_on_node_type</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">) </span><span class="functiontext">Problems::Issue::internal_error_on_node_type_fn</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">__FILE__</span><span class="plain">, </span><span class="identifier">__LINE__</span><span class="plain">)</span>
|
|
</pre>
|
|
<p class="inwebparagraph"><a id="SP2"></a><b>§2. </b>Internal errors are generated much like any other problem message, except
|
|
that we use a variant form of the "end" routine which salvages what it can
|
|
from the wreckage, then either forces a crash (to make the stack backtrace
|
|
visible in a debugger) or simply exits to the operating system with error
|
|
code 1:
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::internal_error_end</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="functiontext">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="functiontext">Problems::write_reports</span><span class="plain">(</span><span class="identifier">TRUE</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">debugger_mode</span><span class="plain">) </span><span class="functiontext">Problems::Fatal::force_crash</span><span class="plain">();</span>
|
|
<span class="functiontext">Problems::Fatal::exit</span><span class="plain">(1);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Problems::Issue::internal_error_end is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b>And now for the functions which the above macros invoke. There are two
|
|
versions: one which cites the current sentence, and another which doesn't,
|
|
for use if either there is no current sentence (because NI wasn't traversing
|
|
the parse tree at the time) or if the parse tree is unsafe — it's possible
|
|
that the internal error occurred during parse tree construction, so we need
|
|
to be cautious.
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::internal_error_fn</span><span class="plain">(</span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">filename</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">linenum</span><span class="plain">) {</span>
|
|
<span class="identifier">internal_error_thrown</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_sentence</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<span class="functiontext">Problems::Issue::internal_error_tu_fn</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">filename</span><span class="plain">, </span><span class="identifier">linenum</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="functiontext">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(2, </span><span class="identifier">p</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(3, </span><span class="identifier">filename</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_number</span><span class="plain">(4, &</span><span class="identifier">linenum</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_begin</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"An internal error has occurred: %2. The current sentence is %1; the "</span>
|
|
<span class="string">"error was detected at line %4 of \"%3\". This should never happen, "</span>
|
|
<span class="string">"and I am now halting in abject failure."</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::Issue::internal_error_end</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::internal_error_tu_fn</span><span class="plain">(</span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">filename</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">linenum</span><span class="plain">) {</span>
|
|
<span class="identifier">internal_error_thrown</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(1, </span><span class="identifier">p</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(2, </span><span class="identifier">filename</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_number</span><span class="plain">(3, &</span><span class="identifier">linenum</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_begin</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"An internal error has occurred: %1. The error was detected at "</span>
|
|
<span class="string">"line %3 of \"%2\". This should never happen, and I am now halting "</span>
|
|
<span class="string">"in abject failure."</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::Issue::internal_error_end</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::internal_error_tu_fn_S</span><span class="plain">(</span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">filename</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">linenum</span><span class="plain">) {</span>
|
|
<span class="identifier">internal_error_thrown</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="functiontext">Problems::quote_stream</span><span class="plain">(1, </span><span class="identifier">p</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(2, </span><span class="identifier">filename</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_number</span><span class="plain">(3, &</span><span class="identifier">linenum</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_begin</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="string">""</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"An internal error has occurred: %1. The error was detected at "</span>
|
|
<span class="string">"line %3 of \"%2\". This should never happen, and I am now halting "</span>
|
|
<span class="string">"in abject failure."</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::Issue::internal_error_end</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Problems::Issue::internal_error_fn is used in <a href="#SP4">§4</a>.</p>
|
|
|
|
<p class="endnote">The function Problems::Issue::internal_error_tu_fn is used in <a href="#SP1">§1</a>, <a href="#SP6">§6</a>.</p>
|
|
|
|
<p class="endnote">The function Problems::Issue::internal_error_tu_fn_S is used in <a href="#SP4">§4</a>, <a href="#SP5">§5</a>, <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. Nodal errors. </b>Very many routines are designed to work only on nodes within the parse
|
|
tree of a particular node type. If NI is in working order, then they will
|
|
never be called at any other nodes; but it seems best to check this. Any
|
|
failure of such an invariant produces a form of internal error called a
|
|
"nodal error".
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::nodal_error_fn</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pn</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">filename</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">linenum</span><span class="plain">) {</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Internal nodal error at:\n"</span><span class="plain">);</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$T\n"</span><span class="plain">, </span><span class="identifier">pn</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::Issue::internal_error_fn</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">filename</span><span class="plain">, </span><span class="identifier">linenum</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::nodal_error_fn_S</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pn</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">filename</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">linenum</span><span class="plain">) {</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Internal nodal error at:\n"</span><span class="plain">);</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$T\n"</span><span class="plain">, </span><span class="identifier">pn</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::Issue::internal_error_tu_fn_S</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">filename</span><span class="plain">, </span><span class="identifier">linenum</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Problems::Issue::nodal_error_fn appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function Problems::Issue::nodal_error_fn_S is used in <a href="#SP5">§5</a>, <a href="#SP6">§6</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§5. </b>Here is a convenient function to check said invariant.
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::nodal_check</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pn</span><span class="plain">, </span><span class="identifier">node_type_t</span><span class="plain"> </span><span class="identifier">node_type_required</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">filename</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">linenum</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pn</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">internal_message</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">internal_message</span><span class="plain">, </span><span class="string">"NULL node found where type %s expected"</span><span class="plain">,</span>
|
|
<span class="identifier">ParseTree::get_type_name</span><span class="plain">(</span><span class="identifier">node_type_required</span><span class="plain">));</span>
|
|
<span class="functiontext">Problems::Issue::internal_error_tu_fn_S</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">internal_message</span><span class="plain">, </span><span class="identifier">filename</span><span class="plain">, </span><span class="identifier">linenum</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">internal_message</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">) != </span><span class="identifier">node_type_required</span><span class="plain">) {</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">internal_message</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">internal_message</span><span class="plain">, </span><span class="string">"Node of type %s found where type %s expected"</span><span class="plain">,</span>
|
|
<span class="identifier">ParseTree::get_type_name</span><span class="plain">(</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">)),</span>
|
|
<span class="identifier">ParseTree::get_type_name</span><span class="plain">(</span><span class="identifier">node_type_required</span><span class="plain">));</span>
|
|
<span class="functiontext">Problems::Issue::nodal_error_fn_S</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">pn</span><span class="plain">, </span><span class="identifier">internal_message</span><span class="plain">, </span><span class="identifier">filename</span><span class="plain">, </span><span class="identifier">linenum</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">internal_message</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Problems::Issue::nodal_check is used in <a href="#SP1">§1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§6. </b>Nodal errors also turn up as the default clauses in switch statements which
|
|
act on various selections of node types, and those use the <code class="display"><span class="extract">internal_error_on_node_type</span></code>
|
|
macro, which invokes the following:
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::internal_error_on_node_type_fn</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">,</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pn</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">filename</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">linenum</span><span class="plain">) {</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">internal_message</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pn</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
|
|
<span class="functiontext">Problems::Issue::internal_error_tu_fn</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="string">"Unexpected NULL node found"</span><span class="plain">, </span><span class="identifier">filename</span><span class="plain">, </span><span class="identifier">linenum</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">internal_message</span><span class="plain">, </span><span class="string">"Unexpectedly found node of type %s"</span><span class="plain">,</span>
|
|
<span class="identifier">ParseTree::get_type_name</span><span class="plain">(</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">pn</span><span class="plain">)));</span>
|
|
<span class="functiontext">Problems::Issue::nodal_error_fn_S</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">pn</span><span class="plain">, </span><span class="identifier">internal_message</span><span class="plain">, </span><span class="identifier">filename</span><span class="plain">, </span><span class="identifier">linenum</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">internal_message</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Problems::Issue::internal_error_on_node_type_fn is used in <a href="#SP1">§1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§7. </b>The following routines are relics of an era of horrific, primordial upheaval,
|
|
when the S-parser was being debugged. An S-subtree is a portion of the parse
|
|
tree which represents a proposition.
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">latest_s_subtree</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::s_subtree_error_set_position</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
|
|
<span class="identifier">latest_s_subtree</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::s_subtree_error</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">mess</span><span class="plain">) {</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">internal_message</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">internal_message</span><span class="plain">, </span><span class="string">"S-subtree error: %s"</span><span class="plain">, </span><span class="identifier">mess</span><span class="plain">);</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">internal_message</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">latest_s_subtree</span><span class="plain">) </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Applied to the subtree:\n$T"</span><span class="plain">, </span><span class="identifier">latest_s_subtree</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::Issue::internal_error_tu_fn_S</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">internal_message</span><span class="plain">, </span><span class="identifier">__FILE__</span><span class="plain">, </span><span class="identifier">__LINE__</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">internal_message</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Problems::Issue::s_subtree_error_set_position appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function Problems::Issue::s_subtree_error appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. Sigils. </b>Every problem message in Inform is identified by a sigil, a short
|
|
alphanumeric symbol. The <code class="display"><span class="extract">_p_</span></code> notation is used to write these;
|
|
see almost every section in later chapters for examples. The naming rules
|
|
for sigils are as follows:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<ul class="items"><li>(a) A problem which is thought never to be generated has the sigil
|
|
<code class="display"><span class="extract">BelievedImpossible</span></code>. Inform is quite defensively coded, so there are several
|
|
dozen of these — they are safety nets to catch cases we didn't think of.
|
|
</li></ul>
|
|
<ul class="items"><li>(b) A problem which either cannot be tested by <code class="display"><span class="extract">intest</span></code>, or is just impracticable
|
|
to do so, has the sigil <code class="display"><span class="extract">Untestable</span></code>.
|
|
</li></ul>
|
|
<ul class="items"><li>(c) A problem which can be tested, but for which nobody has yet written a
|
|
test case, has the sigil <code class="display"><span class="extract">...</span></code> (these are gradually declining in number, and
|
|
eventually, of course, will disappear altogether).
|
|
</li></ul>
|
|
<ul class="items"><li>(d) Otherwise a problem should have a unique sigil beginning <code class="display"><span class="extract">C</span></code> and then the
|
|
chapter number in which it is found: say, <code class="display"><span class="extract">PM_NoSuchHieroglyph</span></code>. The sigil
|
|
should have the same name as an <code class="display"><span class="extract">intest</span></code> test case which demonstrates the
|
|
problem.
|
|
</li></ul>
|
|
<ul class="items"><li>(e) A sigil which ends <code class="display"><span class="extract">-G</span></code> should be used for those few problems which appear
|
|
only when the virtual machine is Glulx.
|
|
</li></ul>
|
|
<p class="inwebparagraph">It would be easy for all this to fall out of sync, or for us just to lose track
|
|
of odd cases, since there are more than 750 problem messages; so a shell script
|
|
called <code class="display"><span class="extract">listproblems.sh</span></code> exists to verify that the above rules have been
|
|
adhered to.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9"></a><b>§9. </b>As can be seen, <code class="display"><span class="extract">_p_</span></code> is a macro expanding to the sigil's name in double
|
|
quotes followed by the source section and line number at which it is generated.
|
|
This provides three function arguments matching the <code class="display"><span class="extract">SIGIL_ARGUMENTS</span></code> prototype,
|
|
which appears as a pseudo-argument in all of the problem routines below.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Each such routine should either <code class="display"><span class="extract">ACT_ON_SIGIL</span></code> itself or else pass over to
|
|
another problem routine, using <code class="display"><span class="extract">PASS_SIGIL</span></code> as the pseudo-argument.
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">sigil</span><span class="plain">) #</span><span class="identifier">sigil</span><span class="plain">, </span><span class="identifier">__FILE__</span><span class="plain">, </span><span class="identifier">__LINE__</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">SIGIL_ARGUMENTS</span><span class="plain"> </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">sigil</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">file</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">line</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">ACT_ON_SIGIL</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Problem %s issued from %s, line %d\n"</span><span class="plain">, </span><span class="identifier">sigil</span><span class="plain">, </span><span class="identifier">file</span><span class="plain">, </span><span class="identifier">line</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">telemetry_recording</span><span class="plain">) {</span>
|
|
<span class="functiontext">Telemetry::ensure_telemetry_file</span><span class="plain">();</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">telmy</span><span class="plain">, </span><span class="string">"Problem %s issued from %s, line %d\n"</span><span class="plain">, </span><span class="identifier">sigil</span><span class="plain">, </span><span class="identifier">file</span><span class="plain">, </span><span class="identifier">line</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sigil_of_latest_unlinked_problem</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">sigil_of_latest_unlinked_problem</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Str::clear</span><span class="plain">(</span><span class="identifier">sigil_of_latest_unlinked_problem</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sigil_of_latest_problem</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">sigil_of_latest_problem</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Str::clear</span><span class="plain">(</span><span class="identifier">sigil_of_latest_problem</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">sigil_of_latest_unlinked_problem</span><span class="plain">, </span><span class="string">"%s"</span><span class="plain">, </span><span class="identifier">sigil</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">sigil_of_latest_problem</span><span class="plain">, </span><span class="string">"%s"</span><span class="plain">, </span><span class="identifier">sigil</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">sigil_of_required_problem</span><span class="plain">, </span><span class="identifier">sigil_of_latest_problem</span><span class="plain">))</span>
|
|
<span class="identifier">sigil_of_required_problem_found</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">echo_problem_message_sigils</span><span class="plain">) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDERR</span><span class="plain">, </span><span class="string">"Problem__ %S\n"</span><span class="plain">, </span><span class="identifier">sigil_of_latest_problem</span><span class="plain">);</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">PASS_SIGIL</span><span class="plain"> </span><span class="identifier">sigil</span><span class="plain">, </span><span class="identifier">file</span><span class="plain">, </span><span class="identifier">line</span>
|
|
</pre>
|
|
|
|
<pre class="display">
|
|
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">sigil_of_latest_unlinked_problem</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">sigil_of_latest_problem</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::problem_documentation_links</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">sigil_of_latest_unlinked_problem</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">DOCUMENTATION_REFERENCES_PRESENT</span>
|
|
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">chap</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">sec</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">leaf</span><span class="plain"> = </span><span class="identifier">Index::DocReferences::link_if_possible_once</span><span class="plain">(</span><span class="identifier">sigil_of_latest_unlinked_problem</span><span class="plain">, &</span><span class="identifier">chap</span><span class="plain">, &</span><span class="identifier">sec</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">leaf</span><span class="plain">) {</span>
|
|
<span class="identifier">HTMLFiles::open_para</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="constant">2</span><span class="plain">, </span><span class="string">"tight"</span><span class="plain">);</span>
|
|
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"a"</span><span class="plain">, </span><span class="string">"href=inform:/%w.html"</span><span class="plain">, </span><span class="identifier">leaf</span><span class="plain">);</span>
|
|
<span class="identifier">HTML_TAG_WITH</span><span class="plain">(</span><span class="string">"img"</span><span class="plain">, </span><span class="string">"border=0 src=inform:/doc_images/help.png"</span><span class="plain">);</span>
|
|
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"a"</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&nbsp;"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">chap</span><span class="plain">) && (</span><span class="identifier">sec</span><span class="plain">)) {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"<i>See the manual: %w &gt; %w</i>"</span><span class="plain">, </span><span class="identifier">chap</span><span class="plain">, </span><span class="identifier">sec</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"<i>See the manual.</i>"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">telemetry_recording</span><span class="plain">) {</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">telmy</span><span class="plain">, </span><span class="string">"See the manual: %w > %w\n\n"</span><span class="plain">, </span><span class="identifier">chap</span><span class="plain">, </span><span class="identifier">sec</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span>
|
|
<span class="identifier">Str::clear</span><span class="plain">(</span><span class="identifier">sigil_of_latest_unlinked_problem</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">Problems::Issue::latest_sigil</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">sigil_of_latest_problem</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Problems::Issue::problem_documentation_links is used in 2/pl2 (<a href="2-pl2.html#SP9">§9</a>).</p>
|
|
|
|
<p class="endnote">The function Problems::Issue::latest_sigil appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10"></a><b>§10. </b>The command-line switch <code class="display"><span class="extract">-sigils</span></code> causes the following flag to be set,
|
|
which in turn causes the sigil of any problem to be echoed to standard output
|
|
(i.e., printed). This is useful in testing, as it makes it easier to be sure
|
|
that the test case <code class="display"><span class="extract">PM_NoSuchHieroglyph.txt</span></code> does indeed generate the
|
|
problem <code class="display"><span class="extract">PM_NoSuchHieroglyph</span></code>, and so on.
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">echo_problem_message_sigils</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11"></a><b>§11. Handmade problems. </b>Those made without using the convenient shorthand forms below:
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">SIGIL_ARGUMENTS</span><span class="plain">) {</span>
|
|
<span class="constant">ACT_ON_SIGIL</span>
|
|
<span class="functiontext">Problems::issue_problem_begin</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="string">""</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Problems::Issue::handmade_problem appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12"></a><b>§12. Limit problems. </b>Running out of memory, irretrievably: the politest kind of fatal error,
|
|
though let's face it, fatal is fatal.
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::limit_problem</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">SIGIL_ARGUMENTS</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">what_has_run_out</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">how_many</span><span class="plain">) {</span>
|
|
<span class="constant">ACT_ON_SIGIL</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(1, </span><span class="identifier">what_has_run_out</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_number</span><span class="plain">(2, &</span><span class="identifier">how_many</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_begin</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="string">""</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"I have run out of memory for %1 - there's room for %2, but no more. "</span>
|
|
<span class="string">"This is a 'hard limit', hard in the sense of deadlines, or luck: "</span>
|
|
<span class="string">"there is no getting around it. You will need to rewrite your source "</span>
|
|
<span class="string">"text so that it needs fewer %1."</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="functiontext">Problems::write_reports</span><span class="plain">(</span><span class="identifier">FALSE</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::Fatal::exit</span><span class="plain">(1);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::memory_allocation_problem</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">SIGIL_ARGUMENTS</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">what_has_run_out</span><span class="plain">) {</span>
|
|
<span class="constant">ACT_ON_SIGIL</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(1, </span><span class="identifier">what_has_run_out</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_begin</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="string">""</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"I am unable to persuade this computer to let me have memory in "</span>
|
|
<span class="string">"which to store the %1. This rarely happens on a modern desktop or laptop, "</span>
|
|
<span class="string">"but might occur on a small handheld device - if so, it may be a "</span>
|
|
<span class="string">"symptom that the device isn't powerful enough to run me. (See how "</span>
|
|
<span class="string">"I pass the blame?)"</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="functiontext">Problems::write_reports</span><span class="plain">(</span><span class="identifier">FALSE</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::Fatal::exit</span><span class="plain">(1);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Problems::Issue::limit_problem appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function Problems::Issue::memory_allocation_problem appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP13"></a><b>§13. Problem messages unlocated in the source text. </b>And now the regular problem messages, the ones which are not my fault.
|
|
We begin with lexical problems happening when the run is hardly begun:
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::lexical_problem</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">SIGIL_ARGUMENTS</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">message</span><span class="plain">, </span><span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">concerning</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">exp</span><span class="plain">) {</span>
|
|
<span class="constant">ACT_ON_SIGIL</span>
|
|
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">lexical_explanation</span><span class="plain"> =</span>
|
|
<span class="string">"This is a low-level problem happening when I am still reading in the "</span>
|
|
<span class="string">"source. Such problems sometimes arise because I have been told to "</span>
|
|
<span class="string">"read a source file which is not text at all."</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">exp</span><span class="plain"> != </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">lexical_explanation</span><span class="plain"> = </span><span class="identifier">exp</span><span class="plain">;</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(1, </span><span class="identifier">message</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">concerning</span><span class="plain">) </span><span class="functiontext">Problems::quote_wide_text</span><span class="plain">(2, </span><span class="identifier">concerning</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_sentence</span><span class="plain">) </span><span class="functiontext">Problems::quote_source</span><span class="plain">(2, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Problems::quote_text</span><span class="plain">(2, </span><span class="string">"<text generated internally>"</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(3, </span><span class="identifier">lexical_explanation</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_begin</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">lexical_explanation</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"%1: %2%L.%%%| %3"</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::lexical_problem_S</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">SIGIL_ARGUMENTS</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">message</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">concerning</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">exp</span><span class="plain">) {</span>
|
|
<span class="constant">ACT_ON_SIGIL</span>
|
|
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">lexical_explanation</span><span class="plain"> =</span>
|
|
<span class="string">"This is a low-level problem happening when I am still reading in the "</span>
|
|
<span class="string">"source. Such problems sometimes arise because I have been told to "</span>
|
|
<span class="string">"read a source file which is not text at all."</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">exp</span><span class="plain"> != </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">lexical_explanation</span><span class="plain"> = </span><span class="identifier">exp</span><span class="plain">;</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(1, </span><span class="identifier">message</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">concerning</span><span class="plain">) </span><span class="functiontext">Problems::quote_stream</span><span class="plain">(2, </span><span class="identifier">concerning</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_sentence</span><span class="plain">) </span><span class="functiontext">Problems::quote_source</span><span class="plain">(2, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Problems::quote_text</span><span class="plain">(2, </span><span class="string">"<text generated internally>"</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(3, </span><span class="identifier">lexical_explanation</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_begin</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">lexical_explanation</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"%1: %2%L.%%%| %3"</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Problems::Issue::lexical_problem appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function Problems::Issue::lexical_problem_S appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14"></a><b>§14. </b>Clearly lexical problems cannot cite positions in the source text, and some
|
|
other problems can't either, so:
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::unlocated_problem</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">SIGIL_ARGUMENTS</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">message</span><span class="plain">) {</span>
|
|
<span class="constant">ACT_ON_SIGIL</span>
|
|
<span class="identifier">do_not_locate_problems</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="functiontext">Problems::issue_problem_begin</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">message</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_segment</span><span class="plain">(</span><span class="identifier">message</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="identifier">do_not_locate_problems</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::unlocated_problem_on_file</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">SIGIL_ARGUMENTS</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">message</span><span class="plain">, </span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">) {</span>
|
|
<span class="constant">ACT_ON_SIGIL</span>
|
|
<span class="identifier">do_not_locate_problems</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, </span><span class="string">"%f"</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_stream</span><span class="plain">(1, </span><span class="identifier">fn</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_begin</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">message</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_segment</span><span class="plain">(</span><span class="identifier">message</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">);</span>
|
|
<span class="identifier">do_not_locate_problems</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Problems::Issue::unlocated_problem appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function Problems::Issue::unlocated_problem_on_file appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15"></a><b>§15. Problem messages keyed to positions in the source text. </b>The following routine is used to produce more than 300 different problem
|
|
messages, making it the most prolific of all the problem routines: perhaps
|
|
that isn't surprising, since it simply quotes the entire sentence at fault
|
|
(which is always the current sentence) and issues a message.
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">SIGIL_ARGUMENTS</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">message</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">explanation</span><span class="plain">) {</span>
|
|
<span class="constant">ACT_ON_SIGIL</span>
|
|
<span class="functiontext">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(2, </span><span class="identifier">message</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(3, </span><span class="identifier">explanation</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_begin</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">explanation</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"You wrote %1: %Sagain, %%%Lbut %%%2%|, %3"</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Problems::Issue::sentence_problem is used in <a href="#SP18">§18</a>, <a href="#SP19">§19</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP16"></a><b>§16. </b>And a variant which adds a note in a subsequent paragraph.
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::sentence_problem_with_note</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">SIGIL_ARGUMENTS</span><span class="plain">,</span>
|
|
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">message</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">explanation</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">note</span><span class="plain">) {</span>
|
|
<span class="constant">ACT_ON_SIGIL</span>
|
|
<span class="functiontext">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(2, </span><span class="identifier">message</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(3, </span><span class="identifier">explanation</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(4, </span><span class="identifier">note</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_begin</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">explanation</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"You wrote %1: %Sagain, %%%Lbut %%%2%|, %3 %P%4"</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Problems::Issue::sentence_problem_with_note appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP17"></a><b>§17. </b>And this is a variant which draws particular attention to a word range
|
|
which is part of the current sentence.
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::sentence_in_detail_problem</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">SIGIL_ARGUMENTS</span><span class="plain">,</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">message</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">explanation</span><span class="plain">) {</span>
|
|
<span class="constant">ACT_ON_SIGIL</span>
|
|
<span class="functiontext">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(2, </span><span class="identifier">message</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(3, </span><span class="identifier">explanation</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_wording</span><span class="plain">(4, </span><span class="identifier">W</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_begin</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">explanation</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"You wrote %1, and in particular '%4': %Sagain, %%%Lbut %%%2%|, %3"</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Problems::Issue::sentence_in_detail_problem appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP18"></a><b>§18. </b>A not always helpful problem message which is needed in several places, and
|
|
therefore is kept here:
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::negative_sentence_problem</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">SIGIL_ARGUMENTS</span><span class="plain">) {</span>
|
|
<span class="functiontext">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">PASS_SIGIL</span><span class="plain">,</span>
|
|
<span class="string">"assertions about the initial state of play must be positive, not negative"</span><span class="plain">,</span>
|
|
<span class="string">"so 'The cat is an animal' is fine but not 'The cat is not a container'. "</span>
|
|
<span class="string">"I have only very feeble powers of deduction - sometimes the implications "</span>
|
|
<span class="string">"of a negative statement are obvious to a human reader, but not to me."</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Problems::Issue::negative_sentence_problem appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP19"></a><b>§19. </b>This is a much more elaborate form of the standard <code class="display"><span class="extract">Problems::Issue::sentence_problem</span></code>,
|
|
used when an assertion sentence has gone wrong. Experience from the early
|
|
builds of the Public Beta showed that many people tried syntaxes which
|
|
Inform did not recognise, and which cause Inform to misread the primary
|
|
verb of the sentence. It would then issue a Problem — because the sentence
|
|
would be peculiar — but this problem report would itself be odd, and
|
|
make little sense to the user. So we look to see if the current sentence
|
|
is an assertion with a primary verb: and if it is, we hunt through it
|
|
for alternative verbs which might have been intended, and try to produce
|
|
a message which diagnoses the problem rather better.
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">LINGUISTICS_MODULE</span>
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::assertion_problem</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">SIGIL_ARGUMENTS</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">message</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">explanation</span><span class="plain">) {</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">RTW</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">; </span><span class="comment">"rather than" text</span>
|
|
<span class="constant">ACT_ON_SIGIL</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">current_sentence</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">current_sentence</span><span class="plain">-></span><span class="identifier">down</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) ||</span>
|
|
<span class="plain">(</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">-></span><span class="identifier">down</span><span class="plain">) != </span><span class="identifier">AVERB_NT</span><span class="plain">)) {</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"(Assertion error reverting to sentence error.)\n"</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">PASS_SIGIL</span><span class="plain">, </span><span class="identifier">message</span><span class="plain">, </span><span class="identifier">explanation</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"(Assertion error: looking for alternative verbs in <%W>.)\n"</span><span class="plain">,</span>
|
|
<span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">));</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">AW</span><span class="plain"> = </span><span class="identifier">Wordings::trim_both_ends</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">));</span>
|
|
<span class="identifier">LOOP_THROUGH_WORDING</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">AW</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">i</span><span class="plain"> != </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">-></span><span class="identifier">down</span><span class="plain">))) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Word::unexpectedly_upper_case</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> = <</span><span class="identifier">meaningful</span><span class="plain">-</span><span class="identifier">nonimperative</span><span class="plain">-</span><span class="identifier">verb</span><span class="plain">>(</span><span class="identifier">Wordings::from</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">), </span><span class="identifier">i</span><span class="plain">));</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain"> > </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">RTW</span><span class="plain"> = </span><span class="identifier">Wordings::new</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="functiontext">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(2, </span><span class="identifier">message</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(3, </span><span class="identifier">explanation</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_begin</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">explanation</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"You wrote %1: %Sagain, %%%Lbut %%%2%|, %3"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">RTW</span><span class="plain">)) {</span>
|
|
<span class="functiontext">Problems::quote_wording</span><span class="plain">(4, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">-></span><span class="identifier">down</span><span class="plain">));</span>
|
|
<span class="functiontext">Problems::quote_wording</span><span class="plain">(5, </span><span class="identifier">RTW</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_segment</span><span class="plain">( </span><span class="comment">see also PM_AmbiguousVerb</span>
|
|
<span class="string">" %P(It may help to know that I am reading the primary verb here "</span>
|
|
<span class="string">"as '%4', not '%5'.)"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="functiontext">Problems::Issue::diagnose_further</span><span class="plain">();</span>
|
|
<span class="functiontext">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::diagnose_further</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_sentence</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::empty</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">))) </span><span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">sqc</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_THROUGH_WORDING</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">)) </span><span class="identifier">sqc</span><span class="plain"> += </span><span class="identifier">Word::singly_quoted</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sqc</span><span class="plain"> >= </span><span class="constant">2</span><span class="plain">)</span>
|
|
<span class="functiontext">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">" %P(I notice what look like single quotation marks in this "</span>
|
|
<span class="string">"sentence. If you meant to write some quoted text, it needs to "</span>
|
|
<span class="string">"be in double quotes, \"like this\" and not 'like this'.)"</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">control_structure_phrase</span><span class="plain"> *</span><span class="identifier">csp</span><span class="plain"> =</span>
|
|
<span class="identifier">ControlStructures::detect</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">current_sentence</span><span class="plain">));</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">csp</span><span class="plain">)</span>
|
|
<span class="functiontext">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">" %P(The way this sentence starts makes me think it might have been "</span>
|
|
<span class="string">"intended as part of a rule rather than being a statement about the "</span>
|
|
<span class="string">"the way things are at the beginning of play. For example, 'If the "</span>
|
|
<span class="string">"player is in the Penalty Zone, say \"An alarm sounds.\" is not "</span>
|
|
<span class="string">"allowed: it has to be put in the form of a rule showing Inform "</span>
|
|
<span class="string">"what circumstances apply - for example 'Every turn: if the player is "</span>
|
|
<span class="string">"in the Penalty Zone, say \"An alarm sounds.\")"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Problems::Issue::assertion_problem appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function Problems::Issue::diagnose_further appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20"></a><b>§20. Definition problems. </b>Sentence problems are a nuisance for "Definition:" definitions, because
|
|
those usually occur when the current sentence is rather unhelpfully just the
|
|
word "Definition" alone. So we use this routine instead:
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::definition_problem</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">SIGIL_ARGUMENTS</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">q</span><span class="plain">,</span>
|
|
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">message</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">explanation</span><span class="plain">) {</span>
|
|
<span class="constant">ACT_ON_SIGIL</span>
|
|
<span class="functiontext">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">q</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(2, </span><span class="identifier">message</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(3, </span><span class="identifier">explanation</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_begin</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">explanation</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"You gave as a definition %1: %Sagain, %%%Lbut %%%2%|, %3"</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::adjective_problem</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="constant">SIGIL_ARGUMENTS</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">IX</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">D</span><span class="plain">,</span>
|
|
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">message</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">explanation</span><span class="plain">) {</span>
|
|
<span class="constant">ACT_ON_SIGIL</span>
|
|
<span class="functiontext">Problems::quote_wording</span><span class="plain">(1, </span><span class="identifier">IX</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">D</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(3, </span><span class="identifier">message</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_text</span><span class="plain">(4, </span><span class="identifier">explanation</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_source</span><span class="plain">(5, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_begin</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">explanation</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"In %5 you defined an adjective by '%1' intending that "</span>
|
|
<span class="string">"it would apply to '%2': %Sagain, %%%Lbut %%%3%|, %4"</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Problems::Issue::definition_problem appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function Problems::Issue::adjective_problem appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP21"></a><b>§21. Creating the Problems report. </b>We are at last able to print the text which appears at the top of the
|
|
Problems report; and this completes the code for errors. In my end is my beginning.
|
|
</p>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::start_problems_report</span><span class="plain">(</span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">) {</span>
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">PROBLEMS_INITIAL_REPORTER</span>
|
|
<span class="identifier">PROBLEMS_INITIAL_REPORTER</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">);</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Problems::Issue::issue_problems_banner</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">verdict</span><span class="plain">) {</span>
|
|
<span class="identifier">HTML::comment</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"BANNER BEGINS"</span><span class="plain">);</span>
|
|
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"table"</span><span class="plain">, </span><span class="string">"cellspacing=\"3\" border=\"0\" width=\"100%%\""</span><span class="plain">);</span>
|
|
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"tr"</span><span class="plain">, </span><span class="string">"id=\"surround0\""</span><span class="plain">);</span>
|
|
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"td"</span><span class="plain">, </span><span class="string">"style=\"width:100%%\""</span><span class="plain">);</span>
|
|
<span class="identifier">HTML::comment</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"HEADING BEGINS"</span><span class="plain">);</span>
|
|
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"div"</span><span class="plain">, </span><span class="string">"class=\"headingbox%s\""</span><span class="plain">, </span><span class="identifier">verdict</span><span class="plain">);</span>
|
|
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"div"</span><span class="plain">, </span><span class="string">"class=\"headingtext\""</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Report on Translation: %s"</span><span class="plain">, </span><span class="identifier">verdict</span><span class="plain">);</span>
|
|
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"div"</span><span class="plain">);</span>
|
|
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"div"</span><span class="plain">, </span><span class="string">"class=\"headingrubric\""</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Produced by %B (build %B)"</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
|
|
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"div"</span><span class="plain">);</span>
|
|
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"div"</span><span class="plain">);</span>
|
|
<span class="identifier">HTML::comment</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"HEADING ENDS"</span><span class="plain">);</span>
|
|
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"td"</span><span class="plain">);</span>
|
|
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"tr"</span><span class="plain">);</span>
|
|
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"table"</span><span class="plain">);</span>
|
|
<span class="identifier">HTML::comment</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"BANNER ENDS"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Problems::Issue::start_problems_report appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function Problems::Issue::issue_problems_banner appears nowhere else.</p>
|
|
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><a href="2-pl2.html">Back to 'Problems, Level 2'</a></li><li><i>(This section ends Chapter 2: Problems.)</i></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|