1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-09 02:24:21 +03:00
inform7/docs/values-module/4-aots.html

453 lines
69 KiB
HTML
Raw Normal View History

2019-03-17 14:40:57 +02:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
2020-04-14 19:56:54 +03:00
<title>Architecture of the S-Parser</title>
2020-05-03 03:20:55 +03:00
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
2020-03-19 02:11:25 +02:00
<meta name="viewport" content="width=device-width initial-scale=1">
2019-03-17 14:40:57 +02:00
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
2020-05-03 03:01:21 +03:00
2020-05-03 03:20:55 +03:00
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
2020-05-03 03:01:21 +03:00
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
2020-05-03 03:20:55 +03:00
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
2020-05-09 01:13:45 +03:00
<link href="../docs-assets/Preform-Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
2020-04-14 19:56:54 +03:00
2019-03-17 14:40:57 +02:00
</head>
2020-05-03 03:01:21 +03:00
<body class="commentary-font">
2020-03-19 02:11:25 +02:00
<nav role="navigation">
2020-04-14 19:56:54 +03:00
<h1><a href="../index.html">
2020-05-03 18:34:53 +03:00
<img src="../docs-assets/Inform.png" height=72">
2020-04-14 19:56:54 +03:00
</a></h1>
<ul><li><a href="../compiler.html">compiler tools</a></li>
2020-03-19 02:11:25 +02:00
<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>
2020-04-14 19:56:54 +03:00
</ul><h2>Compiler Webs</h2><ul>
2020-03-19 02:11:25 +02:00
<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>
2020-04-14 19:56:54 +03:00
</ul><h2>Inbuild Modules</h2><ul>
<li><a href="../supervisor-module/index.html">supervisor</a></li>
</ul><h2>Inform7 Modules</h2><ul>
2020-08-26 12:52:50 +03:00
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../assertions-module/index.html">assertions</a></li>
<li><a href="index.html"><span class="selectedlink">values</span></a></li>
<li><a href="../knowledge-module/index.html">knowledge</a></li>
<li><a href="../imperative-module/index.html">imperative</a></li>
<li><a href="../runtime-module/index.html">runtime</a></li>
2020-03-19 02:11:25 +02:00
<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>
2020-04-14 19:56:54 +03:00
</ul><h2>Inter Modules</h2><ul>
<li><a href="../bytecode-module/index.html">bytecode</a></li>
2020-03-19 02:11:25 +02:00
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
2020-05-20 02:02:28 +03:00
</ul><h2>Services</h2><ul>
2020-04-14 19:56:54 +03:00
<li><a href="../arch-module/index.html">arch</a></li>
2020-08-20 01:36:18 +03:00
<li><a href="../calculus-module/index.html">calculus</a></li>
2020-04-14 19:56:54 +03:00
<li><a href="../html-module/index.html">html</a></li>
2020-05-20 02:02:28 +03:00
<li><a href="../inflections-module/index.html">inflections</a></li>
2020-08-20 01:36:18 +03:00
<li><a href="../kinds-module/index.html">kinds</a></li>
2020-05-20 02:02:28 +03:00
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
2020-08-20 01:36:18 +03:00
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../words-module/index.html">words</a></li>
2020-03-19 02:11:25 +02:00
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
2020-04-14 19:56:54 +03:00
</ul>
2020-03-19 02:11:25 +02:00
</nav>
<main role="main">
2020-05-03 03:01:21 +03:00
<!--Weave of 'Architecture of the S-Parser' generated by Inweb-->
<div class="breadcrumbs">
2021-02-05 02:15:21 +02:00
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7</a></li><li><a href="index.html">values</a></li><li><a href="index.html#4">Chapter 4: The S-Parser</a></li><li><b>Architecture of the S-Parser</b></li></ul></div>
2020-05-03 03:01:21 +03:00
<p class="purpose">Top-level structure of the S-parser, which turns text into S-nodes.</p>
2019-03-17 14:40:57 +02:00
2020-08-26 12:52:50 +03:00
<ul class="toc"><li><a href="4-aots.html#SP1">&#167;1. Introduction</a></li><li><a href="4-aots.html#SP3">&#167;3. Top-level nonterminals</a></li><li><a href="4-aots.html#SP11">&#167;11. The cache</a></li><li><a href="4-aots.html#SP15">&#167;15. Void phrases</a></li></ul><hr class="tocbar">
2019-03-17 14:40:57 +02:00
2020-08-18 00:57:45 +03:00
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Introduction. </b>The purpose of the S-parser is to turn excerpts of text into specification
2019-03-17 14:40:57 +02:00
nodes. Nonterminals here almost all have names beginning with the "s-" prefix,
which indicates that their results are S-nodes.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">The simplest nonterminal in the S-grammar is &lt;s-plain-text&gt;, which
2019-03-17 14:40:57 +02:00
accepts any non-empty piece of text. (The same can be said exactly of
2020-07-27 02:27:32 +03:00
&lt;np-unparsed&gt;, and the difference is purely to do with how Inform stores
the results: &lt;np-unparsed&gt; makes nodes in the main parse tree, a rather
2019-03-17 14:40:57 +02:00
permanent structure, whereas &lt;s-plain-text&gt; makes an S-node.)
</p>
2020-05-09 01:13:45 +03:00
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;s-plain-text&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">internal</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{</span>
2020-08-26 12:52:50 +03:00
<span class="Preform-plain-syntax"> ==&gt; { -, </span><a href="2-spc.html#SP10" class="function-link"><span class="Preform-function-syntax">Specifications::new_UNKNOWN</span></a><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">) };</span>
2020-05-09 01:13:45 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-17 13:51:27 +03:00
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
2020-08-18 00:57:45 +03:00
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>And here is a curious variation, which is needed because equations are
2019-03-17 14:40:57 +02:00
parsed with completely different spacing rules, and don't respect words. It
matches any non-empty text where one of the words contains an equals sign
as one of its characters: thus
</p>
<blockquote>
<p>V = fl</p>
</blockquote>
<blockquote>
<p>F=ma</p>
</blockquote>
2020-05-03 03:01:21 +03:00
<p class="commentary">both match this, the first example being three words long, the second only one.
2019-03-17 14:40:57 +02:00
</p>
2020-05-09 01:13:45 +03:00
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;s-plain-text-with-equals&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">internal</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">LOOP_THROUGH_WORDING</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">i</span><span class="Preform-plain-syntax">, </span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">) {</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">wchar_t</span><span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">p</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">Lexer::word_raw_text</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">i</span><span class="Preform-plain-syntax">);</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">for</span><span class="Preform-plain-syntax"> (</span><span class="Preform-reserved-syntax">int</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">j</span><span class="Preform-plain-syntax">=0; </span><span class="Preform-identifier-syntax">p</span><span class="Preform-plain-syntax">[</span><span class="Preform-identifier-syntax">j</span><span class="Preform-plain-syntax">]; </span><span class="Preform-identifier-syntax">j</span><span class="Preform-plain-syntax">++)</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><span class="Preform-identifier-syntax">p</span><span class="Preform-plain-syntax">[</span><span class="Preform-identifier-syntax">j</span><span class="Preform-plain-syntax">] == </span><span class="Preform-character-syntax">'='</span><span class="Preform-plain-syntax">) {</span>
2020-08-26 12:52:50 +03:00
<span class="Preform-plain-syntax"> ==&gt; { -, </span><a href="2-spc.html#SP10" class="function-link"><span class="Preform-function-syntax">Specifications::new_UNKNOWN</span></a><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">) };</span>
2020-05-09 01:13:45 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> }</span>
<span class="Preform-plain-syntax"> }</span>
2020-07-28 21:19:38 +03:00
<span class="Preform-plain-syntax"> ==&gt; { </span><span class="Preform-identifier-syntax">fail</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">nonterminal</span><span class="Preform-plain-syntax"> };</span>
2020-05-09 01:13:45 +03:00
<span class="Preform-plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-17 13:51:27 +03:00
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
2020-08-18 00:57:45 +03:00
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. Top-level nonterminals. </b>These five nonterminals are the most useful and powerful, so they're the
2019-03-17 14:40:57 +02:00
main junction between the S-parser and the rest of Inform.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">These are coded as internals for efficiency's sake. We will often reparse the
2019-03-17 14:40:57 +02:00
same wording over and over, so we cache the results. But &lt;s-value&gt; matches
exactly the same text as &lt;s-value-uncached&gt;, and so on for the other four.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">&lt;s-value&gt; looks for source text which can be evaluated &mdash; a constant, a
2019-03-17 14:40:57 +02:00
variable or other storage object, or a phrase to decide a value.
</p>
2020-05-09 01:13:45 +03:00
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;s-value&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">internal</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{</span>
2020-08-26 12:52:50 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">parse_node</span><span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">spec</span><span class="Preform-plain-syntax"> = </span><a href="4-aots.html#SP13" class="function-link"><span class="Preform-function-syntax">ExParser::parse_with_cache</span></a><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">, </span><span class="Preform-constant-syntax">0</span><span class="Preform-plain-syntax">, </span><span class="Preform-function-syntax">&lt;s-value-uncached&gt;</span><span class="Preform-plain-syntax">);</span>
2020-07-28 21:19:38 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><span class="Preform-identifier-syntax">Node::is</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">spec</span><span class="Preform-plain-syntax">, </span><span class="Preform-identifier-syntax">UNKNOWN_NT</span><span class="Preform-plain-syntax">)) { ==&gt; { </span><span class="Preform-identifier-syntax">fail</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">nonterminal</span><span class="Preform-plain-syntax"> }; }</span>
<span class="Preform-plain-syntax"> ==&gt; { -, </span><span class="Preform-identifier-syntax">spec</span><span class="Preform-plain-syntax"> };</span>
2020-05-09 01:13:45 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-17 13:51:27 +03:00
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
2020-08-18 00:57:45 +03:00
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>&lt;s-condition&gt; looks for a condition &mdash; anything legal after an
2019-03-17 14:40:57 +02:00
"if", in short. This includes sentence-like excerpts such as "six
animals have been in the Stables".
</p>
2020-05-09 01:13:45 +03:00
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;s-condition&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">internal</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{</span>
2020-08-26 12:52:50 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">LocalVariables::make_necessary_callings</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">);</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">parse_node</span><span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">spec</span><span class="Preform-plain-syntax"> = </span><a href="4-aots.html#SP13" class="function-link"><span class="Preform-function-syntax">ExParser::parse_with_cache</span></a><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">, </span><span class="Preform-constant-syntax">1</span><span class="Preform-plain-syntax">, </span><span class="Preform-function-syntax">&lt;s-condition-uncached&gt;</span><span class="Preform-plain-syntax">);</span>
2020-07-28 21:19:38 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><span class="Preform-identifier-syntax">Node::is</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">spec</span><span class="Preform-plain-syntax">, </span><span class="Preform-identifier-syntax">UNKNOWN_NT</span><span class="Preform-plain-syntax">)) { ==&gt; { </span><span class="Preform-identifier-syntax">fail</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">nonterminal</span><span class="Preform-plain-syntax"> }; }</span>
<span class="Preform-plain-syntax"> ==&gt; { -, </span><span class="Preform-identifier-syntax">spec</span><span class="Preform-plain-syntax"> };</span>
2020-05-09 01:13:45 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-17 13:51:27 +03:00
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
2020-08-18 00:57:45 +03:00
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>&lt;s-non-action-condition&gt; is the same, but disallowing action patterns
2019-03-17 14:40:57 +02:00
as conditions, so for example "taking something" would not match.
</p>
2020-05-09 01:13:45 +03:00
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;s-non-action-condition&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">internal</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{</span>
2020-08-26 12:52:50 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">LocalVariables::make_necessary_callings</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">);</span>
2020-05-09 01:13:45 +03:00
<span class="Preform-plain-syntax"> #</span><span class="Preform-identifier-syntax">ifdef</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">IF_MODULE</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">int</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">old_state</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">PL::Actions::Patterns::suppress</span><span class="Preform-plain-syntax">();</span>
<span class="Preform-plain-syntax"> #</span><span class="Preform-identifier-syntax">endif</span>
2020-08-26 12:52:50 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">parse_node</span><span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">spec</span><span class="Preform-plain-syntax"> = </span><a href="4-aots.html#SP13" class="function-link"><span class="Preform-function-syntax">ExParser::parse_with_cache</span></a><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">, </span><span class="Preform-constant-syntax">2</span><span class="Preform-plain-syntax">, </span><span class="Preform-function-syntax">&lt;s-condition-uncached&gt;</span><span class="Preform-plain-syntax">);</span>
2020-05-09 01:13:45 +03:00
<span class="Preform-plain-syntax"> #</span><span class="Preform-identifier-syntax">ifdef</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">IF_MODULE</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">PL::Actions::Patterns::resume</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">old_state</span><span class="Preform-plain-syntax">);</span>
<span class="Preform-plain-syntax"> #</span><span class="Preform-identifier-syntax">endif</span>
2020-07-28 21:19:38 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><span class="Preform-identifier-syntax">Node::is</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">spec</span><span class="Preform-plain-syntax">, </span><span class="Preform-identifier-syntax">UNKNOWN_NT</span><span class="Preform-plain-syntax">)) { ==&gt; { </span><span class="Preform-identifier-syntax">fail</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">nonterminal</span><span class="Preform-plain-syntax"> }; }</span>
<span class="Preform-plain-syntax"> ==&gt; { -, </span><span class="Preform-identifier-syntax">spec</span><span class="Preform-plain-syntax"> };</span>
2020-05-09 01:13:45 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-17 13:51:27 +03:00
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
2020-08-18 00:57:45 +03:00
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>&lt;s-type-expression&gt; is for where we expect to find the "type" of something
2019-03-17 14:40:57 +02:00
&mdash; for instance, the kind of value to be stored in a variable, or the
specification of a phrase argument.
</p>
2020-05-09 01:13:45 +03:00
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;s-type-expression&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">internal</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{</span>
2020-08-26 12:52:50 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">parse_node</span><span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">spec</span><span class="Preform-plain-syntax"> = </span><a href="4-aots.html#SP13" class="function-link"><span class="Preform-function-syntax">ExParser::parse_with_cache</span></a><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">, </span><span class="Preform-constant-syntax">3</span><span class="Preform-plain-syntax">, </span><span class="Preform-function-syntax">&lt;s-type-expression-uncached&gt;</span><span class="Preform-plain-syntax">);</span>
2020-07-28 21:19:38 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><span class="Preform-identifier-syntax">Node::is</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">spec</span><span class="Preform-plain-syntax">, </span><span class="Preform-identifier-syntax">UNKNOWN_NT</span><span class="Preform-plain-syntax">)) { ==&gt; { </span><span class="Preform-identifier-syntax">fail</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">nonterminal</span><span class="Preform-plain-syntax"> }; }</span>
<span class="Preform-plain-syntax"> ==&gt; { -, </span><span class="Preform-identifier-syntax">spec</span><span class="Preform-plain-syntax"> };</span>
2020-05-09 01:13:45 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-17 13:51:27 +03:00
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
2020-08-18 00:57:45 +03:00
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b>&lt;s-descriptive-type-expression&gt; is the same thing, with one difference: it
2019-03-17 14:40:57 +02:00
allows nounless descriptions, such as "open opaque fixed in place", and to
this end it treats bare adjective names as descriptions rather than values. If
we have said "Colour is a kind of value. The colours are red, green and taupe.
A thing has a colour.", then "green" is parsed by &lt;s-descriptive-type-expression&gt;
as a description meaning "any thing which is green", but by &lt;s-type-expression&gt;
and &lt;s-value&gt; as a constant value of the kind "colour".
</p>
2020-05-09 01:13:45 +03:00
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;s-descriptive-type-expression&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">internal</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{</span>
2020-08-26 12:52:50 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">parse_node</span><span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">spec</span><span class="Preform-plain-syntax"> = </span><a href="4-aots.html#SP13" class="function-link"><span class="Preform-function-syntax">ExParser::parse_with_cache</span></a><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">, </span><span class="Preform-constant-syntax">4</span><span class="Preform-plain-syntax">, </span><span class="Preform-function-syntax">&lt;s-descriptive-type-expression-uncached&gt;</span><span class="Preform-plain-syntax">);</span>
2020-07-28 21:19:38 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><span class="Preform-identifier-syntax">Node::is</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">spec</span><span class="Preform-plain-syntax">, </span><span class="Preform-identifier-syntax">UNKNOWN_NT</span><span class="Preform-plain-syntax">)) { ==&gt; { </span><span class="Preform-identifier-syntax">fail</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">nonterminal</span><span class="Preform-plain-syntax"> }; }</span>
<span class="Preform-plain-syntax"> ==&gt; { -, </span><span class="Preform-identifier-syntax">spec</span><span class="Preform-plain-syntax"> };</span>
2020-05-09 01:13:45 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-17 13:51:27 +03:00
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
2020-08-18 00:57:45 +03:00
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b>The following internal is just a shell for &lt;s-descriptive-type-expression&gt;,
2019-03-17 14:40:57 +02:00
but it temporarily changes the parsing mode to phrase token parsing, so that
kind variables will be read as formal prototypes.
</p>
2020-05-09 01:13:45 +03:00
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;s-phrase-token-type&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">internal</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">int</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">s</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">kind_parsing_mode</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">kind_parsing_mode</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">PHRASE_TOKEN_KIND_PARSING</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">int</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">t</span><span class="Preform-plain-syntax"> = </span><span class="Preform-function-syntax">&lt;s-descriptive-type-expression&gt;</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">);</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">kind_parsing_mode</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">s</span><span class="Preform-plain-syntax">;</span>
2020-07-28 21:19:38 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><span class="Preform-identifier-syntax">t</span><span class="Preform-plain-syntax">) { ==&gt; { </span><span class="Preform-function-syntax">&lt;&lt;r&gt;&gt;</span><span class="Preform-plain-syntax">, </span><span class="Preform-function-syntax">&lt;&lt;rp&gt;&gt;</span><span class="Preform-plain-syntax"> }; </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">; }</span>
<span class="Preform-plain-syntax"> ==&gt; { </span><span class="Preform-identifier-syntax">fail</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">nonterminal</span><span class="Preform-plain-syntax"> };</span>
2020-05-09 01:13:45 +03:00
<span class="Preform-plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-17 13:51:27 +03:00
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
2020-08-18 00:57:45 +03:00
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. </b>That's it for the cached nonterminals, but we will also define a convenient
2019-03-17 14:40:57 +02:00
super-nonterminal which matches almost any meaningful reference to data, so
it's frequently used as a way of finding out whether a new name will clash
with some existing meaning.
</p>
2020-05-09 01:13:45 +03:00
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;s-type-expression-or-value&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
2020-07-28 21:19:38 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;s-type-expression&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> { pass 1 }</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;s-value&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> { pass 1 }</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-17 13:51:27 +03:00
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
2020-08-18 00:57:45 +03:00
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. </b>One further convenience is for text which describes an explicit action in
2019-03-17 14:40:57 +02:00
a noun-like way.
</p>
2020-05-09 01:13:45 +03:00
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;s-explicit-action&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">internal</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{</span>
<span class="Preform-plain-syntax"> #</span><span class="Preform-identifier-syntax">ifdef</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">IF_MODULE</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">parse_node</span><span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">S</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">NULL</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">int</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">p</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">permit_trying_omission</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">permit_trying_omission</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><span class="Preform-function-syntax">&lt;s-condition-uncached&gt;</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">)) </span><span class="Preform-identifier-syntax">S</span><span class="Preform-plain-syntax"> = </span><span class="Preform-function-syntax">&lt;&lt;rp&gt;&gt;</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">permit_trying_omission</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">p</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><span class="Preform-identifier-syntax">S</span><span class="Preform-plain-syntax">) {</span>
2020-08-27 17:50:24 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><a href="2-rvl.html#SP21" class="function-link"><span class="Preform-function-syntax">Rvalues::is_CONSTANT_of_kind</span></a><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">S</span><span class="Preform-plain-syntax">, </span><span class="Preform-identifier-syntax">K_stored_action</span><span class="Preform-plain-syntax">)) {</span>
2020-07-28 21:19:38 +03:00
<span class="Preform-plain-syntax"> ==&gt; { -, </span><span class="Preform-identifier-syntax">S</span><span class="Preform-plain-syntax"> };</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">;</span>
2020-08-26 12:52:50 +03:00
<span class="Preform-plain-syntax"> } </span><span class="Preform-reserved-syntax">else</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><a href="2-cnd.html#SP10" class="function-link"><span class="Preform-function-syntax">Conditions::is_TEST_ACTION</span></a><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">S</span><span class="Preform-plain-syntax">)) {</span>
<span class="Preform-plain-syntax"> ==&gt; { -, </span><span class="Preform-identifier-syntax">S</span><span class="Preform-plain-syntax">-&gt;</span><span class="Preform-identifier-syntax">down</span><span class="Preform-plain-syntax"> };</span>
2020-05-09 01:13:45 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">;</span>
2020-07-28 21:19:38 +03:00
<span class="Preform-plain-syntax"> } </span><span class="Preform-reserved-syntax">else</span><span class="Preform-plain-syntax"> {</span>
<span class="Preform-plain-syntax"> ==&gt; { </span><span class="Preform-identifier-syntax">fail</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">nonterminal</span><span class="Preform-plain-syntax"> };</span>
<span class="Preform-plain-syntax"> }</span>
2020-05-09 01:13:45 +03:00
<span class="Preform-plain-syntax"> }</span>
<span class="Preform-plain-syntax"> #</span><span class="Preform-identifier-syntax">endif</span>
2020-07-28 21:19:38 +03:00
<span class="Preform-plain-syntax"> ==&gt; { </span><span class="Preform-identifier-syntax">fail</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">nonterminal</span><span class="Preform-plain-syntax"> };</span>
2020-05-09 01:13:45 +03:00
<span class="Preform-plain-syntax">}</span>
<span class="Preform-function-syntax">&lt;s-constant-action&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">internal</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{</span>
<span class="Preform-plain-syntax"> #</span><span class="Preform-identifier-syntax">ifdef</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">IF_MODULE</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">parse_node</span><span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">S</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">NULL</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">int</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">p</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">permit_trying_omission</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">permit_trying_omission</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">int</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">p2</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">permit_nonconstant_action_parameters</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">permit_nonconstant_action_parameters</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">FALSE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><span class="Preform-function-syntax">&lt;s-condition-uncached&gt;</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">)) </span><span class="Preform-identifier-syntax">S</span><span class="Preform-plain-syntax"> = </span><span class="Preform-function-syntax">&lt;&lt;rp&gt;&gt;</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">permit_trying_omission</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">p</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">permit_nonconstant_action_parameters</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">p2</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><span class="Preform-identifier-syntax">S</span><span class="Preform-plain-syntax">) {</span>
2020-08-27 17:50:24 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><a href="2-rvl.html#SP21" class="function-link"><span class="Preform-function-syntax">Rvalues::is_CONSTANT_of_kind</span></a><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">S</span><span class="Preform-plain-syntax">, </span><span class="Preform-identifier-syntax">K_stored_action</span><span class="Preform-plain-syntax">)) {</span>
2020-07-28 21:19:38 +03:00
<span class="Preform-plain-syntax"> ==&gt; { -, </span><span class="Preform-identifier-syntax">S</span><span class="Preform-plain-syntax"> };</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">;</span>
2020-08-26 12:52:50 +03:00
<span class="Preform-plain-syntax"> } </span><span class="Preform-reserved-syntax">else</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><a href="2-cnd.html#SP10" class="function-link"><span class="Preform-function-syntax">Conditions::is_TEST_ACTION</span></a><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">S</span><span class="Preform-plain-syntax">)) {</span>
<span class="Preform-plain-syntax"> ==&gt; { -, </span><span class="Preform-identifier-syntax">S</span><span class="Preform-plain-syntax">-&gt;</span><span class="Preform-identifier-syntax">down</span><span class="Preform-plain-syntax"> };</span>
2020-05-09 01:13:45 +03:00
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">;</span>
2020-07-28 21:19:38 +03:00
<span class="Preform-plain-syntax"> } </span><span class="Preform-reserved-syntax">else</span><span class="Preform-plain-syntax"> {</span>
<span class="Preform-plain-syntax"> ==&gt; { </span><span class="Preform-identifier-syntax">fail</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">nonterminal</span><span class="Preform-plain-syntax"> };</span>
<span class="Preform-plain-syntax"> }</span>
2020-05-09 01:13:45 +03:00
<span class="Preform-plain-syntax"> }</span>
<span class="Preform-plain-syntax"> #</span><span class="Preform-identifier-syntax">endif</span>
2020-07-28 21:19:38 +03:00
<span class="Preform-plain-syntax"> ==&gt; { </span><span class="Preform-identifier-syntax">fail</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">nonterminal</span><span class="Preform-plain-syntax"> };</span>
2020-05-09 01:13:45 +03:00
<span class="Preform-plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-17 13:51:27 +03:00
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
2020-08-18 00:57:45 +03:00
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. The cache. </b>The above nonterminals are called pretty frequently on overlapping or
2019-03-17 14:40:57 +02:00
coinciding runs of text. Inform runs substantially faster if the results of
parsing the most recent expressions are cached; so, for instance, if Inform
parses the text in words 507 to 511 once, it need not do so again in the same
context.
</p>
2020-08-18 00:57:45 +03:00
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. </b>The cache takes the form of a modest ring buffer for each of the contexts:
2019-03-17 14:40:57 +02:00
</p>
2020-05-09 01:13:45 +03:00
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="Preform-constant-syntax">MAXIMUM_CACHE_SIZE</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">20</span><span class="Preform-plain-syntax"> </span><span class="Preform-comment-syntax"> a Goldilocks value: too high slows us down, too low doesn't cache enough</span>
<span class="definition-keyword">define</span> <span class="Preform-constant-syntax">NUMBER_OF_CACHED_NONTERMINALS</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">5</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">expression_cache</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">expression_cache_entry</span><span class="plain-syntax"> </span><span class="identifier-syntax">pe_cache</span><span class="plain-syntax">[</span><span class="constant-syntax">MAXIMUM_CACHE_SIZE</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pe_cache_size</span><span class="plain-syntax">; </span><span class="comment-syntax"> number of entries used, 0 to </span><span class="extract"><span class="extract-syntax">MAXIMUM_CACHE_SIZE</span></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pe_cache_posn</span><span class="plain-syntax">; </span><span class="comment-syntax"> next write position, 0 to </span><span class="extract"><span class="extract-syntax">pe_cache_size</span></span><span class="comment-syntax"> minus 1</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">expression_cache</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">expression_cache_entry</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">cached_query</span><span class="plain-syntax">; </span><span class="comment-syntax"> the word range whose parsing this is</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cached_result</span><span class="plain-syntax">; </span><span class="comment-syntax"> and the result (quite possibly </span><span class="extract"><span class="extract-syntax">UNKNOWN_NT</span></span><span class="comment-syntax">)</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">expression_cache_entry</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">expression_cache_has_been_used</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">expression_cache</span><span class="plain-syntax"> </span><span class="identifier-syntax">contextual_cache</span><span class="plain-syntax">[</span><span class="constant-syntax">NUMBER_OF_CACHED_NONTERMINALS</span><span class="plain-syntax">];</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-03 03:01:21 +03:00
<ul class="endnotetexts"><li>The structure expression_cache is private to this section.</li><li>The structure expression_cache_entry is private to this section.</li></ul>
2020-08-18 00:57:45 +03:00
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. </b></p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
2020-08-26 12:52:50 +03:00
<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">ExParser::parse_with_cache</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">ExParser::parse_with_cache</span></span>:<br/><a href="4-aots.html#SP3">&#167;3</a>, <a href="4-aots.html#SP4">&#167;4</a>, <a href="4-aots.html#SP5">&#167;5</a>, <a href="4-aots.html#SP6">&#167;6</a>, <a href="4-aots.html#SP7">&#167;7</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">context</span><span class="plain-syntax">, </span><span class="identifier-syntax">nonterminal</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nt</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::empty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-spc.html#SP10" class="function-link"><span class="function-syntax">Specifications::new_UNKNOWN</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">context</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">context</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">NUMBER_OF_CACHED_NONTERMINALS</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax"> (</span><span class="string-syntax">"bad expression parsing context"</span><span class="plain-syntax">);</span>
2020-08-26 12:52:50 +03:00
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-aots.html#SP13_1" class="named-paragraph-link"><span class="named-paragraph">Check the expression cache to see if we already know the answer</span><span class="named-paragraph-number">13.1</span></a></span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">unwanted</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">spec</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">plm</span><span class="plain-syntax"> = </span><span class="identifier-syntax">preform_lookahead_mode</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">preform_lookahead_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Preform::parse_nt_against_word_range</span><span class="plain-syntax">(</span><span class="identifier-syntax">nt</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">unwanted</span><span class="plain-syntax">, (</span><span class="reserved-syntax">void</span><span class="plain-syntax"> **) &amp;</span><span class="identifier-syntax">spec</span><span class="plain-syntax">)) {</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::empty</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">))) </span><span class="identifier-syntax">Node::set_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
2020-08-26 12:52:50 +03:00
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">spec</span><span class="plain-syntax"> = </span><a href="2-spc.html#SP10" class="function-link"><span class="function-syntax">Specifications::new_UNKNOWN</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">preform_lookahead_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">plm</span><span class="plain-syntax">;</span>
2020-08-26 12:52:50 +03:00
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-aots.html#SP13_2" class="named-paragraph-link"><span class="named-paragraph">Write the newly discovered specification to the cache for future use</span><span class="named-paragraph-number">13.2</span></a></span><span class="plain-syntax">;</span>
2020-05-11 21:14:00 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">VerifyTree::verify_structure_from</span><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">spec</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-08-18 00:57:45 +03:00
<p class="commentary firstcommentary"><a id="SP13_1" class="paragraph-anchor"></a><b>&#167;13.1. </b>The following seeks a previously cached answer:
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check the expression cache to see if we already know the answer</span><span class="named-paragraph-number">13.1</span></span><span class="comment-syntax"> =</span>
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">expression_cache</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ec</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">contextual_cache</span><span class="plain-syntax">[</span><span class="identifier-syntax">context</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">expression_cache_has_been_used</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
2020-08-26 12:52:50 +03:00
<span class="plain-syntax"> </span><a href="4-aots.html#SP14" class="function-link"><span class="function-syntax">ExParser::warn_expression_cache</span></a><span class="plain-syntax">(); </span><span class="comment-syntax"> this empties all the caches</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">expression_cache_has_been_used</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
2020-05-09 01:13:45 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax">&lt;ec-&gt;</span><span class="element-syntax">pe_cache_size</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">ec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">pe_cache</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">cached_query</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">ec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">pe_cache</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">cached_result</span><span class="plain-syntax">;</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-08-26 12:52:50 +03:00
<ul class="endnotetexts"><li>This code is used in <a href="4-aots.html#SP13">&#167;13</a>.</li></ul>
2020-08-18 00:57:45 +03:00
<p class="commentary firstcommentary"><a id="SP13_2" class="paragraph-anchor"></a><b>&#167;13.2. </b>The cache expands until it reaches <span class="extract"><span class="extract-syntax">MAXIMUM_CACHE_SIZE</span></span>; after that,
2019-03-17 14:40:57 +02:00
entries are written in a position cycling through the ring. In either case
2020-05-03 03:01:21 +03:00
it takes <span class="extract"><span class="extract-syntax">MAXIMUM_CACHE_SIZE</span></span> further parses (not found in the cache) to
2019-03-17 14:40:57 +02:00
overwrite the one we put down now.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Write the newly discovered specification to the cache for future use</span><span class="named-paragraph-number">13.2</span></span><span class="comment-syntax"> =</span>
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">expression_cache</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ec</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">contextual_cache</span><span class="plain-syntax">[</span><span class="identifier-syntax">context</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">pe_cache</span><span class="plain-syntax">[</span><span class="identifier-syntax">ec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">pe_cache_posn</span><span class="plain-syntax">].</span><span class="element-syntax">cached_query</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">pe_cache</span><span class="plain-syntax">[</span><span class="identifier-syntax">ec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">pe_cache_posn</span><span class="plain-syntax">].</span><span class="element-syntax">cached_result</span><span class="plain-syntax"> = </span><span class="identifier-syntax">spec</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">pe_cache_posn</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">pe_cache_size</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">MAXIMUM_CACHE_SIZE</span><span class="plain-syntax">) </span><span class="identifier-syntax">ec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">pe_cache_size</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">pe_cache_posn</span><span class="plain-syntax"> == </span><span class="constant-syntax">MAXIMUM_CACHE_SIZE</span><span class="plain-syntax">) </span><span class="identifier-syntax">ec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">pe_cache_posn</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-08-26 12:52:50 +03:00
<ul class="endnotetexts"><li>This code is used in <a href="4-aots.html#SP13">&#167;13</a>.</li></ul>
2020-08-18 00:57:45 +03:00
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. </b>As with all caches, we have to be careful that the information does not fall
2019-03-17 14:40:57 +02:00
out of date. There are two things which can go wrong: the S-node in the cache
might be altered, perhaps as a result of the type-checker trying to force a
round peg into a square hole; or the stock of Inform's defined names might
change, so that the same text now has to be read differently.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">The first problem can't be fixed here. It's tempting to try something like
2019-03-17 14:40:57 +02:00
flagging S-nodes which have been altered, and then ensuring that the
cache never serves up an altered result. But that fails for timing reasons &mdash;
by the time the S-node might be altered, pointers to it may exist
in multiple data structures already, because the cache might have served
it more than once by that time. (Not just a theoretical possibility &mdash; tests
show that this does, albeit rarely, happen.) The brute force solution is to
serve a copy of the cache entry, and thus never send out the same pointer
twice. But this more than doubles the memory required to store S-nodes,
which is unacceptable, and also slows Inform down, because allocating memory
for all those copies is laborious. We therefore just have to be very careful
about modifying S-nodes which have arisen from parsing.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">The second problem is easier. We require other parts of Inform which make
2019-03-17 14:40:57 +02:00
or unmake name definitions to warn us, by calling this routine. Definitions
are made and unmade relatively rarely, so the performance hit is small.
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
2020-08-26 12:52:50 +03:00
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ExParser::warn_expression_cache</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">ExParser::warn_expression_cache</span></span>:<br/><a href="4-aots.html#SP13_1">&#167;13.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">NUMBER_OF_CACHED_NONTERMINALS</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">contextual_cache</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">pe_cache_size</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">contextual_cache</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">pe_cache_posn</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-08-18 00:57:45 +03:00
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. Void phrases. </b>The S-parser is also used by the main code compiler to turn phrases into
2019-03-17 14:40:57 +02:00
S-nodes, using &lt;s-command&gt; and &lt;s-say-command&gt;. These however need a
wrapper: instead of turning text into an S-node, we take text from an
existing node (in the structural parse tree for a routine), turn that
into a new S-node with an invocation list below it, then glue the list
back into the original tree but throw away the S-node head.
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
2020-08-26 12:52:50 +03:00
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ExParser::parse_void_phrase</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-aots.html#SP15" class="function-link"><span class="function-syntax">ExParser::parse_phrase_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax">}</span>
2020-08-26 12:52:50 +03:00
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ExParser::parse_say_term</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-aots.html#SP15" class="function-link"><span class="function-syntax">ExParser::parse_phrase_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ExParser::parse_phrase_inner</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">as_say_term</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no node to parse"</span><span class="plain-syntax">);</span>
2020-08-26 12:52:50 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">))) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">results</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">as_say_term</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="function-syntax">&lt;s-command&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)))) </span><span class="identifier-syntax">results</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;rp&gt;&gt;</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">as_say_term</span><span class="plain-syntax">) &amp;&amp; (</span><span class="function-syntax">&lt;s-say-command&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">)))) </span><span class="identifier-syntax">results</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;rp&gt;&gt;</span><span class="plain-syntax">;</span>
2020-08-26 12:52:50 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">results</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">results</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">)) </span><span class="identifier-syntax">p</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax"> = </span><span class="identifier-syntax">results</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-03 03:01:21 +03:00
<nav role="progress"><div class="progresscontainer">
2020-08-26 12:52:50 +03:00
<ul class="progressbar"><li class="progressprev"><a href="4-its.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-vm.html">1</a></li><li class="progresschapter"><a href="2-spc.html">2</a></li><li class="progresschapter"><a href="3-lp.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-its.html">its</a></li><li class="progresscurrent">aots</li><li class="progresssection"><a href="4-pl.html">pl</a></li><li class="progresssection"><a href="4-cad.html">cad</a></li><li class="progresssection"><a href="4-teav.html">teav</a></li><li class="progresssection"><a href="4-varc.html">varc</a></li><li class="progresssection"><a href="4-cap.html">cap</a></li><li class="progresschapter"><a href="5-tl.html">5</a></li><li class="progresschapter"><a href="6-lc.html">6</a></li><li class="progresschapter"><a href="7-eqt.html">7</a></li><li class="progressnext"><a href="4-pl.html">&#10095;</a></li></ul></div>
2020-05-03 03:01:21 +03:00
</nav><!--End of weave-->
2019-03-17 14:40:57 +02:00
2020-03-19 02:11:25 +02:00
</main>
2019-03-17 14:40:57 +02:00
</body>
</html>