1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-06-28 21:14:57 +03:00

Rewrite of parsing stages

This commit is contained in:
Graham Nelson 2021-11-25 21:53:47 +00:00
parent 39f1780e96
commit c772f426e1
7 changed files with 534 additions and 334 deletions

View file

@ -1,6 +1,6 @@
# Inform 7
v10.1.0-alpha.1+6T82 'Krypton' (24 November 2021)
v10.1.0-alpha.1+6T83 'Krypton' (25 November 2021)
## About Inform 7

View file

@ -1,3 +1,3 @@
Prerelease: alpha.1
Build Date: 24 November 2021
Build Number: 6T82
Build Date: 25 November 2021
Build Number: 6T83

View file

@ -226,7 +226,7 @@ what the red button marked "danger" does.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">PipelineErrors::kit_error</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">PipelineErrors::kit_error</span></span>:<br/>Parsing Stages - <a href="3-ps.html#SP3">&#167;3</a>, <a href="3-ps.html#SP9_1">&#167;9.1</a>, <a href="3-ps.html#SP9_2_2">&#167;9.2.2</a>, <a href="3-ps.html#SP9_2_3">&#167;9.2.3</a>, <a href="3-ps.html#SP9_2_4">&#167;9.2.4</a>, <a href="3-ps.html#SP9_2_5_2">&#167;9.2.5.2</a><br/>Resolving Conditional Compilation - <a href="3-rcc.html#SP2">&#167;2</a>, <a href="3-rcc.html#SP2_4">&#167;2.4</a>, <a href="3-rcc.html#SP2_2_2">&#167;2.2.2</a>, <a href="3-rcc.html#SP2_5">&#167;2.5</a>, <a href="3-rcc.html#SP2_6">&#167;2.6</a><br/>Assimilate Linked Matter - <a href="3-ass.html#SP2_1_2">&#167;2.1.2</a>, <a href="3-ass.html#SP2_2_1">&#167;2.2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">quote</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">PipelineErrors::kit_error</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">PipelineErrors::kit_error</span></span>:<br/>Parsing Stages - <a href="3-ps.html#SP3">&#167;3</a>, <a href="3-ps.html#SP11_1">&#167;11.1</a>, <a href="3-ps.html#SP11_2_2">&#167;11.2.2</a>, <a href="3-ps.html#SP11_2_3">&#167;11.2.3</a>, <a href="3-ps.html#SP11_2_4">&#167;11.2.4</a>, <a href="3-ps.html#SP11_2_5_2">&#167;11.2.5.2</a><br/>Resolving Conditional Compilation - <a href="3-rcc.html#SP2">&#167;2</a>, <a href="3-rcc.html#SP2_4">&#167;2.4</a>, <a href="3-rcc.html#SP2_2_2">&#167;2.2.2</a>, <a href="3-rcc.html#SP2_5">&#167;2.5</a>, <a href="3-rcc.html#SP2_6">&#167;2.6</a><br/>Assimilate Linked Matter - <a href="3-ass.html#SP2_1_2">&#167;2.1.2</a>, <a href="3-ass.html#SP2_2_1">&#167;2.2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">quote</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">PROBLEMS_MODULE</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">M</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">M</span><span class="plain-syntax">, </span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="identifier-syntax">quote</span><span class="plain-syntax">);</span>

View file

@ -73,10 +73,20 @@ function togglePopup(material_id) {
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inter Modules</a></li><li><a href="index.html">pipeline</a></li><li><a href="index.html#3">Chapter 3: Linking Stages</a></li><li><b>Parsing Stages</b></li></ul></div>
<p class="purpose">Two stages which accept raw I6-syntax material in the parse tree, either from imsertions made using Inform 7's low-level features, or after reading the source code for a kit.</p>
<ul class="toc"><li><a href="3-ps.html#SP1">&#167;1. The two stages</a></li><li><a href="3-ps.html#SP4">&#167;4. I6T kits</a></li><li><a href="3-ps.html#SP7">&#167;7. Syntax of I6T files</a></li><li><a href="3-ps.html#SP9_2_5_3">&#167;9.2.5.3. Acting on I6T commands</a></li><li><a href="3-ps.html#SP10">&#167;10. Contents section</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="3-ps.html#SP1">&#167;1. The two stages</a></li><li><a href="3-ps.html#SP7">&#167;7. The I6T Reader</a></li><li><a href="3-ps.html#SP11_2_5_3">&#167;11.2.5.3. Acting on I6T commands</a></li><li><a href="3-ps.html#SP12">&#167;12. Contents section</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. The two stages. </b></p>
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. The two stages. </b>These stages have more in common than they first appear. Both convert I6T-syntax
source code into a series of <span class="extract"><span class="extract-syntax">SPLAT_IST</span></span> nodes in the Inter tree, with one
such node for each different directive in the I6T source.
</p>
<p class="commentary">The T in "I6T" stands for "template", which in the 2010s was a mechanism for
providing I6 code to I7. That's not the arrangement any more, but the syntax
</p>
<ul class="items"><li>(mostly) lives on, and so does the name I6T. Still, it's really just the same
thing as Inform 6 code in an Inweb-style literate programming notation.
</li></ul>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParsingStages::create_pipeline_stage</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">ParsingStages::create_pipeline_stage</span></span>:<br/>Parsing Pipelines - <a href="2-pp.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="2-pp.html#SP3" class="function-link"><span class="function-syntax">ParsingPipelines::new_stage</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"load-kit-source"</span><span class="plain-syntax">, </span><a href="3-ps.html#SP2" class="function-link"><span class="function-syntax">ParsingStages::run_load_kit_source</span></a><span class="plain-syntax">,</span>
@ -86,9 +96,8 @@ function togglePopup(material_id) {
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>The stage <span class="extract"><span class="extract-syntax">load-kit-source K</span></span> takes the kit <span class="extract"><span class="extract-syntax">K</span></span>, looks for its source code
(which will be Inform 6-syntax source code written in a literate programming
notation) and reads this in to the current Inter tree, as a new top-level
module.
(text files written in I6T syntax) and reads this in to the current Inter tree,
placing the resulting nodes in a new top-level module.
</p>
<pre class="displayed-code all-displayed-code code-font">
@ -98,13 +107,13 @@ module.
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">main_package</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP2_1" class="named-paragraph-link"><span class="named-paragraph">Create a module to hold the Inter read in from this kit</span><span class="named-paragraph-number">2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> </span><span class="identifier-syntax">kit</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP2_3" class="named-paragraph-link"><span class="named-paragraph">Make a suitable I6T kit</span><span class="named-paragraph-number">2.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="3-ps.html#SP9" class="function-link"><span class="function-syntax">ParsingStages::capture</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">kit</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"all"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-ps.html#SP11" class="function-link"><span class="function-syntax">ParsingStages::I6T_reader</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">kit</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"all"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2_1" class="paragraph-anchor"></a><b>&#167;2.1. </b>So for example if we are reading the source for WorldModelKit, then the
following creates the package <span class="extract"><span class="extract-syntax">/main/WorldModelKit</span></span>, with package type <span class="extract"><span class="extract-syntax">_module</span></span>.
It's into this module that all the code will be read.
It's into this module that the resulting <span class="extract"><span class="extract-syntax">SPLAT_IST</span></span> nodes will be put.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Create a module to hold the Inter read in from this kit</span><span class="named-paragraph-number">2.1</span></span><span class="comment-syntax"> =</span>
@ -119,122 +128,90 @@ It's into this module that all the code will be read.
<span class="plain-syntax"> </span><span class="identifier-syntax">Site::set_assimilation_package</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">template_p</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP2">&#167;2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2" class="paragraph-anchor"></a><b>&#167;2.2. </b></p>
<p class="commentary firstcommentary"><a id="SP2_2" class="paragraph-anchor"></a><b>&#167;2.2. </b>The stage <span class="extract"><span class="extract-syntax">parse-insertions</span></span> does the same thing, but on a much smaller scale,
and reading raw I6T source code from <span class="extract"><span class="extract-syntax">LINK_IST</span></span> nodes in the Inter tree rather
than from an external file. There will only be a few of these, and with not much
code in them, when the tree has been compiled by Inform: they arise from
features such as
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">Include</span><span class="plain-syntax"> (-</span>
<span class="plain-syntax"> </span><span class="comment-syntax">CuriousFunction;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"Curious!"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> ];</span>
<span class="plain-syntax">-).</span>
</pre>
<p class="commentary">The <a href="../inform7/index.html" class="internal">inform7</a> code does not contain a compiler from I6T down to Inter, so
it can only leave us these unparsed fragments as <span class="extract"><span class="extract-syntax">LINK_IST</span></span> nodes. We take
it from there.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">ParsingStages::run_parse_insertions</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">ParsingStages::run_parse_insertions</span></span>:<br/><a href="3-ps.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">pipeline_step</span><span class="plain-syntax"> *</span><span class="identifier-syntax">step</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><span class="identifier-syntax">step</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ephemera</span><span class="plain-syntax">.</span><span class="element-syntax">repository</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> </span><span class="identifier-syntax">kit</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP2_3" class="named-paragraph-link"><span class="named-paragraph">Make a suitable I6T kit</span><span class="named-paragraph-number">2.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">InterTree::traverse</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><a href="3-ps.html#SP2_2" class="function-link"><span class="function-syntax">ParsingStages::catch_all_visitor</span></a><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">kit</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</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">InterTree::traverse</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><a href="3-ps.html#SP2_2" class="function-link"><span class="function-syntax">ParsingStages::visit_insertions</span></a><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">kit</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">LINK_IST</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParsingStages::catch_all_visitor</span><span class="plain-syntax">(</span><span class="identifier-syntax">inter_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">state</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">P</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">W</span><span class="plain-syntax">.</span><span class="identifier-syntax">data</span><span class="plain-syntax">[</span><span class="identifier-syntax">ID_IFLD</span><span class="plain-syntax">] == </span><span class="identifier-syntax">LINK_IST</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">insertion</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Inode::ID_to_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">W</span><span class="plain-syntax">.</span><span class="identifier-syntax">data</span><span class="plain-syntax">[</span><span class="identifier-syntax">TO_RAW_LINK_IFLD</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">Inode::ID_to_ref</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">W</span><span class="plain-syntax">.</span><span class="identifier-syntax">data</span><span class="plain-syntax">[</span><span class="identifier-syntax">REF_LINK_IFLD</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kit</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">state</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="3-ps.html#SP9" class="function-link"><span class="function-syntax">ParsingStages::capture</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kit</span><span class="plain-syntax">, </span><span class="identifier-syntax">insertion</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">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParsingStages::visit_insertions</span><span class="plain-syntax">(</span><span class="identifier-syntax">inter_tree</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">state</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">insertion</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Inode::ID_to_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">W</span><span class="plain-syntax">.</span><span class="identifier-syntax">data</span><span class="plain-syntax">[</span><span class="identifier-syntax">TO_RAW_LINK_IFLD</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">Inode::ID_to_ref</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">W</span><span class="plain-syntax">.</span><span class="identifier-syntax">data</span><span class="plain-syntax">[</span><span class="identifier-syntax">REF_LINK_IFLD</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kit</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">state</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="3-ps.html#SP11" class="function-link"><span class="function-syntax">ParsingStages::I6T_reader</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kit</span><span class="plain-syntax">, </span><span class="identifier-syntax">insertion</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2_3" class="paragraph-anchor"></a><b>&#167;2.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Make a suitable I6T kit</span><span class="named-paragraph-number">2.3</span></span><span class="comment-syntax"> =</span>
<p class="commentary firstcommentary"><a id="SP2_3" class="paragraph-anchor"></a><b>&#167;2.3. </b>So, then, both of those stages rely on (i) making something called an I6T kit,
then (ii) calling <a href="3-ps.html#SP11" class="internal">ParsingStages::I6T_reader</a>.
</p>
<p class="commentary">Here's where we make the kit, which is really just a collection of settings for
the I6T-reader. That comes down to:
</p>
<ul class="items"><li>(a) the place to put any nodes generated,
</li><li>(b) what to do with I6 source code, or with commands embedded in it, and
</li><li>(c) which file-system paths to look inside when reading from files rather
than raw text in memory.
</li></ul>
<p class="commentary">For (c), note that if a kit is in directory <span class="extract"><span class="extract-syntax">K</span></span> then its source files are
in <span class="extract"><span class="extract-syntax">K/Sections</span></span>.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Make a suitable I6T kit</span><span class="named-paragraph-number">2.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PP</span><span class="plain-syntax"> = </span><span class="identifier-syntax">step</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ephemera</span><span class="plain-syntax">.</span><span class="element-syntax">the_PP</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_package</span><span class="plain-syntax"> *</span><span class="identifier-syntax">template_package</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Site::ensure_assimilation_package</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><a href="2-rp.html#SP5" class="function-link"><span class="function-syntax">RunningPipelines::get_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">step</span><span class="plain-syntax">, </span><span class="constant-syntax">plain_ptype_RPSYM</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_bookmark</span><span class="plain-syntax"> </span><span class="identifier-syntax">link_bookmark</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Inter::Bookmarks::at_end_of_this_package</span><span class="plain-syntax">(</span><span class="identifier-syntax">template_package</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kit</span><span class="plain-syntax"> = </span><a href="3-ps.html#SP6" class="function-link"><span class="function-syntax">ParsingStages::kit_out</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">link_bookmark</span><span class="plain-syntax">, &amp;(</span><a href="3-ps.html#SP3" class="function-link"><span class="function-syntax">ParsingStages::receive_raw</span></a><span class="plain-syntax">), &amp;(</span><a href="3-ps.html#SP3" class="function-link"><span class="function-syntax">ParsingStages::receive_command</span></a><span class="plain-syntax">), </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kit</span><span class="plain-syntax">.</span><span class="element-syntax">no_i6t_file_areas</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LinkedLists::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">PP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_package</span><span class="plain-syntax"> *</span><span class="identifier-syntax">assimilation_package</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Site::ensure_assimilation_package</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="2-rp.html#SP5" class="function-link"><span class="function-syntax">RunningPipelines::get_symbol</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">step</span><span class="plain-syntax">, </span><span class="constant-syntax">plain_ptype_RPSYM</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_bookmark</span><span class="plain-syntax"> </span><span class="identifier-syntax">assimilation_point</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Inter::Bookmarks::at_end_of_this_package</span><span class="plain-syntax">(</span><span class="identifier-syntax">assimilation_package</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">pathname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">pathname</span><span class="plain-syntax">, </span><span class="identifier-syntax">PP</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kit</span><span class="plain-syntax">.</span><span class="element-syntax">i6t_files</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">Pathnames::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Sections"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">pathname</span><span class="plain-syntax">, </span><span class="identifier-syntax">step</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ephemera</span><span class="plain-syntax">.</span><span class="element-syntax">the_PP</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">Pathnames::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Sections"</span><span class="plain-syntax">), </span><span class="identifier-syntax">pathname</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kit</span><span class="plain-syntax"> = </span><a href="3-ps.html#SP8" class="function-link"><span class="function-syntax">ParsingStages::kit_out</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">assimilation_point</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> &amp;(</span><a href="3-ps.html#SP4" class="function-link"><span class="function-syntax">ParsingStages::receive_raw</span></a><span class="plain-syntax">), &amp;(</span><a href="3-ps.html#SP3" class="function-link"><span class="function-syntax">ParsingStages::receive_command</span></a><span class="plain-syntax">), </span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP2">&#167;2</a>, <a href="3-ps.html#SP2_2">&#167;2.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b></p>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>Once the I6T reader has unpacked the literate-programming notation, it will
reduce the I6T code to pure Inform 6 source together with (perhaps) a handful of
commands in braces. Our kit must say what to do with each of these outputs.
</p>
<p class="commentary">The easy part: what to do when we find a command in I6T source. In pre-Inter
versions of Inform, when I6T was just a way of expressing Inform 6 code but
with some braced commands mixed in, there were lots of legal if enigmatic
syntaxes in use. Now those have all gone, so in all cases we issue an error:
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">IGNORE_WS_FILTER_BIT</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">DQUOTED_FILTER_BIT</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">SQUOTED_FILTER_BIT</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">COMMENTED_FILTER_BIT</span><span class="plain-syntax"> </span><span class="constant-syntax">8</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">ROUTINED_FILTER_BIT</span><span class="plain-syntax"> </span><span class="constant-syntax">16</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">CONTENT_ON_LINE_FILTER_BIT</span><span class="plain-syntax"> </span><span class="constant-syntax">32</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">SUBORDINATE_FILTER_BITS</span><span class="plain-syntax"> (</span><span class="constant-syntax">COMMENTED_FILTER_BIT</span><span class="plain-syntax"> + </span><span class="constant-syntax">SQUOTED_FILTER_BIT</span><span class="plain-syntax"> + </span><span class="constant-syntax">DQUOTED_FILTER_BIT</span><span class="plain-syntax"> + </span><span class="constant-syntax">ROUTINED_FILTER_BIT</span><span class="plain-syntax">)</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParsingStages::receive_raw</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">ParsingStages::receive_raw</span></span>:<br/><a href="3-ps.html#SP2_3">&#167;2.3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kit</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::new</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">mode</span><span class="plain-syntax"> = </span><span class="constant-syntax">IGNORE_WS_FILTER_BIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::get</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">10</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">13</span><span class="plain-syntax">)) </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="character-syntax">'\n'</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">IGNORE_WS_FILTER_BIT</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'\n'</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">Characters::is_whitespace</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">))) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> -= </span><span class="constant-syntax">IGNORE_WS_FILTER_BIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'!'</span><span class="plain-syntax">) &amp;&amp; (!(</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; (</span><span class="constant-syntax">DQUOTED_FILTER_BIT</span><span class="plain-syntax"> + </span><span class="constant-syntax">SQUOTED_FILTER_BIT</span><span class="plain-syntax">)))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> | </span><span class="constant-syntax">COMMENTED_FILTER_BIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">COMMENTED_FILTER_BIT</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'\n'</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> -= </span><span class="constant-syntax">COMMENTED_FILTER_BIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!(</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">CONTENT_ON_LINE_FILTER_BIT</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'['</span><span class="plain-syntax">) &amp;&amp; (!(</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">SUBORDINATE_FILTER_BITS</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> | </span><span class="constant-syntax">ROUTINED_FILTER_BIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">ROUTINED_FILTER_BIT</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">']'</span><span class="plain-syntax">) &amp;&amp; (!(</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; (</span><span class="constant-syntax">DQUOTED_FILTER_BIT</span><span class="plain-syntax"> + </span><span class="constant-syntax">SQUOTED_FILTER_BIT</span><span class="plain-syntax"> + </span><span class="constant-syntax">COMMENTED_FILTER_BIT</span><span class="plain-syntax">)))) </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> -= </span><span class="constant-syntax">ROUTINED_FILTER_BIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'\''</span><span class="plain-syntax">) &amp;&amp; (!(</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; (</span><span class="constant-syntax">DQUOTED_FILTER_BIT</span><span class="plain-syntax"> + </span><span class="constant-syntax">COMMENTED_FILTER_BIT</span><span class="plain-syntax">)))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">SQUOTED_FILTER_BIT</span><span class="plain-syntax">) </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> -= </span><span class="constant-syntax">SQUOTED_FILTER_BIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> | </span><span class="constant-syntax">SQUOTED_FILTER_BIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'\"'</span><span class="plain-syntax">) &amp;&amp; (!(</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; (</span><span class="constant-syntax">SQUOTED_FILTER_BIT</span><span class="plain-syntax"> + </span><span class="constant-syntax">COMMENTED_FILTER_BIT</span><span class="plain-syntax">)))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">DQUOTED_FILTER_BIT</span><span class="plain-syntax">) </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> -= </span><span class="constant-syntax">DQUOTED_FILTER_BIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> | </span><span class="constant-syntax">DQUOTED_FILTER_BIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> != </span><span class="character-syntax">'\n'</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Characters::is_whitespace</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> | </span><span class="constant-syntax">CONTENT_ON_LINE_FILTER_BIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">CONTENT_ON_LINE_FILTER_BIT</span><span class="plain-syntax">) </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> - </span><span class="constant-syntax">CONTENT_ON_LINE_FILTER_BIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!(</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">SUBORDINATE_FILTER_BITS</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">';'</span><span class="plain-syntax">) &amp;&amp; (!(</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">SUBORDINATE_FILTER_BITS</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><a href="3-ps.html#SP3" class="function-link"><span class="function-syntax">ParsingStages::chunked_raw</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">kit</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="constant-syntax">IGNORE_WS_FILTER_BIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="3-ps.html#SP3" class="function-link"><span class="function-syntax">ParsingStages::chunked_raw</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">kit</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParsingStages::chunked_raw</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kit</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="character-syntax">'\n'</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-ps.html#SP3" class="function-link"><span class="function-syntax">ParsingStages::entire_splat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kit</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">IBM</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"template"</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) (</span><span class="identifier-syntax">Inter::Bookmarks::baseline</span><span class="plain-syntax">(</span><span class="identifier-syntax">kit</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">IBM</span><span class="plain-syntax">) + </span><span class="constant-syntax">1</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParsingStages::entire_splat</span><span class="plain-syntax">(</span><span class="identifier-syntax">inter_bookmark</span><span class="plain-syntax"> *</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">origin</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">content</span><span class="plain-syntax">, </span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax"> </span><span class="identifier-syntax">level</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax"> </span><span class="identifier-syntax">SID</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Inter::Warehouse::create_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">Inter::Bookmarks::warehouse</span><span class="plain-syntax">(</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">), </span><span class="identifier-syntax">Inter::Bookmarks::package</span><span class="plain-syntax">(</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">glob_storage</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Inter::Warehouse::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">Inter::Bookmarks::warehouse</span><span class="plain-syntax">(</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">), </span><span class="identifier-syntax">SID</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::copy</span><span class="plain-syntax">(</span><span class="identifier-syntax">glob_storage</span><span class="plain-syntax">, </span><span class="identifier-syntax">content</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::guard</span><span class="plain-syntax">(</span><span class="identifier-syntax">Inter::Splat::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">, </span><span class="identifier-syntax">SID</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">level</span><span class="plain-syntax">, </span><span class="constant-syntax">0</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">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParsingStages::receive_command</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">ParsingStages::receive_command</span></span>:<br/><a href="3-ps.html#SP2_3">&#167;2.3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">command</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">argument</span><span class="plain-syntax">, </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kit</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParsingStages::receive_command</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">ParsingStages::receive_command</span></span>:<br/><a href="3-ps.html#SP2_3">&#167;2.3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">command</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">argument</span><span class="plain-syntax">, </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kit</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Str::eq_wide_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">command</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"plugin"</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_wide_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">command</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"type"</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_wide_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">command</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"open-file"</span><span class="plain-syntax">)) ||</span>
@ -259,53 +236,183 @@ It's into this module that all the code will be read.
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_wide_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">command</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"testing-routine"</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_wide_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">command</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"testing-command"</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"command: &lt;%S&gt; argument: &lt;%S&gt;\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">command</span><span class="plain-syntax">, </span><span class="identifier-syntax">argument</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-pe.html#SP3" class="function-link"><span class="function-syntax">PipelineErrors::kit_error</span></a><span class="plain-syntax">(</span><span class="string-syntax">"the template command '{-%S}' has been withdrawn in this version of Inform"</span><span class="plain-syntax">, </span><span class="identifier-syntax">command</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-pe.html#SP3" class="function-link"><span class="function-syntax">PipelineErrors::kit_error</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the template command '{-%S}' has been withdrawn in this version of Inform"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">command</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"command: &lt;%S&gt; argument: &lt;%S&gt;\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">command</span><span class="plain-syntax">, </span><span class="identifier-syntax">argument</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-pe.html#SP3" class="function-link"><span class="function-syntax">PipelineErrors::kit_error</span></a><span class="plain-syntax">(</span><span class="string-syntax">"no such {-command} as '%S'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">command</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. I6T kits. </b>These are used to abstract calls to the I6T reader, so that customers of
varying dispositions can do different things with the code parsed.
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>We very much do not ignore the raw I6 code read in, though. When the reader
gives us a chunk of this, we parse through it with a simple finite-state machine.
This can be summarised as "divide the code up at <span class="extract"><span class="extract-syntax">;</span></span> boundaries, sending each
piece in turn to //ParsingStages::splat//". But of course we do not want to
react to semicolons in quoted text or comments, and in fact we also do not
want to react to semicolons used as statement dividers inside I6 routines (i.e.,
functions). So for example
</p>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">Global</span><span class="plain-syntax"> </span><span class="identifier-syntax">aspic</span><span class="plain-syntax"> = </span><span class="string-syntax">"this; and that"</span><span class="plain-syntax">;</span>
<span class="comment-syntax">Don't react to this; I'm only a comment</span>
<span class="plain-syntax">[ </span><span class="identifier-syntax">Hello</span><span class="plain-syntax">; </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"Hello; goodbye.^"</span><span class="plain-syntax">; ];</span>
</pre>
<p class="commentary">would be divided into just two splats,
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">Global</span><span class="plain-syntax"> </span><span class="identifier-syntax">aspic</span><span class="plain-syntax"> = </span><span class="string-syntax">"this; and that"</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary">and
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">Hello</span><span class="plain-syntax">; </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"Hello; goodbye.^"</span><span class="plain-syntax">; ];</span>
</pre>
<p class="commentary">(And the comment would be stripped out entirely.)
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">IGNORE_WS_I6TBIT</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">DQUOTED_I6TBIT</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">SQUOTED_I6TBIT</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">COMMENTED_I6TBIT</span><span class="plain-syntax"> </span><span class="constant-syntax">8</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">ROUTINED_I6TBIT</span><span class="plain-syntax"> </span><span class="constant-syntax">16</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">CONTENT_ON_LINE_I6TBIT</span><span class="plain-syntax"> </span><span class="constant-syntax">32</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">SUBORDINATE_I6TBITS</span>
<span class="plain-syntax"> (</span><span class="constant-syntax">COMMENTED_I6TBIT</span><span class="plain-syntax"> + </span><span class="constant-syntax">SQUOTED_I6TBIT</span><span class="plain-syntax"> + </span><span class="constant-syntax">DQUOTED_I6TBIT</span><span class="plain-syntax"> + </span><span class="constant-syntax">ROUTINED_I6TBIT</span><span class="plain-syntax">)</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParsingStages::receive_raw</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">ParsingStages::receive_raw</span></span>:<br/><a href="3-ps.html#SP2_3">&#167;2.3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kit</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::new</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">mode</span><span class="plain-syntax"> = </span><span class="constant-syntax">IGNORE_WS_I6TBIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::get</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">10</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">13</span><span class="plain-syntax">)) </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="character-syntax">'\n'</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">IGNORE_WS_I6TBIT</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'\n'</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">Characters::is_whitespace</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">))) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> -= </span><span class="constant-syntax">IGNORE_WS_I6TBIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'!'</span><span class="plain-syntax">) &amp;&amp; (!(</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; (</span><span class="constant-syntax">DQUOTED_I6TBIT</span><span class="plain-syntax"> + </span><span class="constant-syntax">SQUOTED_I6TBIT</span><span class="plain-syntax">)))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> | </span><span class="constant-syntax">COMMENTED_I6TBIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">COMMENTED_I6TBIT</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'\n'</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> -= </span><span class="constant-syntax">COMMENTED_I6TBIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!(</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">CONTENT_ON_LINE_I6TBIT</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'['</span><span class="plain-syntax">) &amp;&amp; (!(</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">SUBORDINATE_I6TBITS</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> | </span><span class="constant-syntax">ROUTINED_I6TBIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">ROUTINED_I6TBIT</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">']'</span><span class="plain-syntax">) &amp;&amp; (!(</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; (</span><span class="constant-syntax">DQUOTED_I6TBIT</span><span class="plain-syntax"> + </span><span class="constant-syntax">SQUOTED_I6TBIT</span><span class="plain-syntax"> + </span><span class="constant-syntax">COMMENTED_I6TBIT</span><span class="plain-syntax">))))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> -= </span><span class="constant-syntax">ROUTINED_I6TBIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'\''</span><span class="plain-syntax">) &amp;&amp; (!(</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; (</span><span class="constant-syntax">DQUOTED_I6TBIT</span><span class="plain-syntax"> + </span><span class="constant-syntax">COMMENTED_I6TBIT</span><span class="plain-syntax">)))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">SQUOTED_I6TBIT</span><span class="plain-syntax">) </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> -= </span><span class="constant-syntax">SQUOTED_I6TBIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> | </span><span class="constant-syntax">SQUOTED_I6TBIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'\"'</span><span class="plain-syntax">) &amp;&amp; (!(</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; (</span><span class="constant-syntax">SQUOTED_I6TBIT</span><span class="plain-syntax"> + </span><span class="constant-syntax">COMMENTED_I6TBIT</span><span class="plain-syntax">)))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">DQUOTED_I6TBIT</span><span class="plain-syntax">) </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> -= </span><span class="constant-syntax">DQUOTED_I6TBIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> | </span><span class="constant-syntax">DQUOTED_I6TBIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> != </span><span class="character-syntax">'\n'</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Characters::is_whitespace</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> | </span><span class="constant-syntax">CONTENT_ON_LINE_I6TBIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">CONTENT_ON_LINE_I6TBIT</span><span class="plain-syntax">) </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> - </span><span class="constant-syntax">CONTENT_ON_LINE_I6TBIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!(</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">SUBORDINATE_I6TBITS</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">';'</span><span class="plain-syntax">) &amp;&amp; (!(</span><span class="identifier-syntax">mode</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">SUBORDINATE_I6TBITS</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><a href="3-ps.html#SP5" class="function-link"><span class="function-syntax">ParsingStages::splat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">kit</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="constant-syntax">IGNORE_WS_I6TBIT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="3-ps.html#SP5" class="function-link"><span class="function-syntax">ParsingStages::splat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">kit</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>Each of those "splats" becomes a <span class="extract"><span class="extract-syntax">SPLAT_IST</span></span> node in the tree at the
current insertion point recorded in the kit.
</p>
<p class="commentary">Note that this function empties the splat buffer <span class="extract"><span class="extract-syntax">R</span></span> before exiting.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParsingStages::splat</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">ParsingStages::splat</span></span>:<br/><a href="3-ps.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kit</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="character-syntax">'\n'</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax"> </span><span class="identifier-syntax">SID</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Inter::Warehouse::create_text</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Inter::Bookmarks::warehouse</span><span class="plain-syntax">(</span><span class="identifier-syntax">kit</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">IBM</span><span class="plain-syntax">), </span><span class="identifier-syntax">Inter::Bookmarks::package</span><span class="plain-syntax">(</span><span class="identifier-syntax">kit</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">IBM</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">textual_storage</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Inter::Warehouse::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">Inter::Bookmarks::warehouse</span><span class="plain-syntax">(</span><span class="identifier-syntax">kit</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">IBM</span><span class="plain-syntax">), </span><span class="identifier-syntax">SID</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::copy</span><span class="plain-syntax">(</span><span class="identifier-syntax">textual_storage</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Produce::guard</span><span class="plain-syntax">(</span><span class="identifier-syntax">Inter::Splat::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">kit</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">IBM</span><span class="plain-syntax">, </span><span class="identifier-syntax">SID</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">inter_ti</span><span class="plain-syntax">) (</span><span class="identifier-syntax">Inter::Bookmarks::baseline</span><span class="plain-syntax">(</span><span class="identifier-syntax">kit</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">IBM</span><span class="plain-syntax">) + </span><span class="constant-syntax">1</span><span class="plain-syntax">), </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>And that's it: the result of these stages is just to break the I6T source they
found up into individual directives, and put them into the tree as <span class="extract"><span class="extract-syntax">SPLAT_IST</span></span> nodes.
No effort has been made yet to see what directives they are. Subsequent stages
will handle that.
</p>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. The I6T Reader. </b>The rest of this section, then, is a general-purpose reader of I6T-syntax code.
Although it is only used for one purpose in the Inform code base, it once had
multiple uses, and so it's written quite flexibly. There seems no reason to
get rid of that flexibility: perhaps we'll use it again some day.
</p>
<p class="commentary">So, then, this is the parcel of settings for controlling the I6T reader:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">I6T_kit</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">inter_bookmark</span><span class="plain-syntax"> *</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_i6t_file_areas</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">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">i6t_files</span><span class="plain-syntax">[16];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">raw_callback</span><span class="plain-syntax">)(</span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">command_callback</span><span class="plain-syntax">)(</span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">command_callback</span><span class="plain-syntax">)(</span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</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">text_stream</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I6T_state</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">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">search_paths</span><span class="plain-syntax">; </span><span class="comment-syntax"> of </span><span class="extract"><span class="extract-syntax">pathname</span></span>
<span class="plain-syntax">} </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure I6T_kit is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b></p>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b>We actually don't use this facility, but a kit contains a <span class="extract"><span class="extract-syntax">state</span></span> which is
shared across the calls to the callback functions. When a kit is created, the
initial state must be supplied; after that, it's updated only by the callback
functions supplied.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> </span><span class="function-syntax">ParsingStages::kit_out</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">ParsingStages::kit_out</span></span>:<br/><a href="3-ps.html#SP2_3">&#167;2.3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">inter_bookmark</span><span class="plain-syntax"> *</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">A</span><span class="plain-syntax">)(</span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *),</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">B</span><span class="plain-syntax">)(</span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *),</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> </span><span class="function-syntax">ParsingStages::kit_out</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">ParsingStages::kit_out</span></span>:<br/><a href="3-ps.html#SP2_3">&#167;2.3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">inter_bookmark</span><span class="plain-syntax"> *</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">A</span><span class="plain-syntax">)(</span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *),</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">B</span><span class="plain-syntax">)(</span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</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">text_stream</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">search_list</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">initial_state</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> </span><span class="identifier-syntax">kit</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kit</span><span class="plain-syntax">.</span><span class="element-syntax">IBM</span><span class="plain-syntax"> = </span><span class="identifier-syntax">IBM</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kit</span><span class="plain-syntax">.</span><span class="element-syntax">raw_callback</span><span class="plain-syntax"> = </span><span class="identifier-syntax">A</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kit</span><span class="plain-syntax">.</span><span class="element-syntax">command_callback</span><span class="plain-syntax"> = </span><span class="identifier-syntax">B</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kit</span><span class="plain-syntax">.</span><span class="element-syntax">I6T_state</span><span class="plain-syntax"> = </span><span class="identifier-syntax">C</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kit</span><span class="plain-syntax">.</span><span class="element-syntax">no_i6t_file_areas</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">kit</span><span class="plain-syntax">.</span><span class="element-syntax">I6T_state</span><span class="plain-syntax"> = </span><span class="identifier-syntax">initial_state</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">kit</span><span class="plain-syntax">.</span><span class="element-syntax">search_paths</span><span class="plain-syntax"> = </span><span class="identifier-syntax">search_list</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">kit</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. Syntax of I6T files. </b>The syntax of these files has been designed so that a valid I6T file is
also a valid Inweb section file. (Inweb now has two formats, an old and a
new one: here we can read either, though the I6T sources in the main Inform
distribution have been modernised to the new syntax.) Many Inweb syntaxes
are, however, not allowed in I6T: really, you should use only <span class="extract"><span class="extract-syntax">@h</span></span> headings
and the <span class="extract"><span class="extract-syntax">=</span></span> sign to divide commentary from text. Macros and definitions, in
particular, are not permitted. This means that no real tangling is required
to make the I6T files.
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. </b>I6T files use a literate programming notation which is, in effect, a much
simplified version of Inweb's. (Note that Inweb can therefore read kits as
if they were webs, and we use that to weave them for the source website.)
</p>
<p class="commentary">Many Inweb syntaxes are, however, not allowed in I6T: really, you should use
only <span class="extract"><span class="extract-syntax">@h</span></span> headings and the <span class="extract"><span class="extract-syntax">=</span></span> sign to divide commentary from text. Macros and
definitions, in particular, are not permitted; I6T is not really tangled as such.
</p>
<p class="commentary">The entire range of possibilities is shown here:
@ -330,7 +437,7 @@ code. While this doesn't allow for full-on literate programming, it does
permit a generous amount of annotation.
</p>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b>One restriction. It actually doesn't matter if a template file contains
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. </b>One restriction. It actually doesn't matter if a template file contains
lines longer than this, so long as they do not occur inside <span class="extract"><span class="extract-syntax">{-lines:...}</span></span> and
<span class="extract"><span class="extract-syntax">{-endlines}</span></span>, and so long as no individual braced command <span class="extract"><span class="extract-syntax">{-...}</span></span> exceeds
this length.
@ -338,7 +445,7 @@ this length.
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_I6T_LINE_LENGTH</span><span class="plain-syntax"> </span><span class="constant-syntax">1024</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. </b>The I6T interpreter is then a single routine to implement the description
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>The I6T interpreter is then a single routine to implement the description
above, though note that it can act on interventions as well. (But in modern
Inform usage, often there won't be any, because templates for the Standard
Rules and so forth are assimilated in stand-alone runs of the code generator,
@ -351,25 +458,26 @@ and therefore no interventions will have happened.)
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">active</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">contents_section_state</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParsingStages::capture</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">ParsingStages::capture</span></span>:<br/><a href="3-ps.html#SP2">&#167;2</a>, <a href="3-ps.html#SP2_2">&#167;2.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kit</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">insertion</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">segment</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParsingStages::I6T_reader</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">ParsingStages::I6T_reader</span></span>:<br/><a href="3-ps.html#SP2">&#167;2</a>, <a href="3-ps.html#SP2_2">&#167;2.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kit</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">insertion</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">segment</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="3-ps.html#SP9" class="function-link"><span class="function-syntax">ParsingStages::interpret</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">insertion</span><span class="plain-syntax">, </span><span class="identifier-syntax">segment</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">kit</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-ps.html#SP11" class="function-link"><span class="function-syntax">ParsingStages::interpret</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">insertion</span><span class="plain-syntax">, </span><span class="identifier-syntax">segment</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">kit</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> (*(</span><span class="identifier-syntax">kit</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">raw_callback</span><span class="plain-syntax">))(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">kit</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">)</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParsingStages::interpret</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">ParsingStages::interpret</span></span>:<br/><a href="3-ps.html#SP9_2_5_3_1">&#167;9.2.5.3.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sf</span><span class="plain-syntax">,</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParsingStages::interpret</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">ParsingStages::interpret</span></span>:<br/><a href="3-ps.html#SP11_2_5_3_1">&#167;11.2.5.3.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sf</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">segment_name</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">N_escape</span><span class="plain-syntax">, </span><span class="reserved-syntax">I6T_kit</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kit</span><span class="plain-syntax">, </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Input_Filename</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">segment_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"all"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">area</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">area</span><span class="function-syntax">&lt;kit-&gt;</span><span class="element-syntax">no_i6t_file_areas</span><span class="plain-syntax">; </span><span class="identifier-syntax">area</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Pathnames::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">kit</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">i6t_files</span><span class="plain-syntax">[</span><span class="identifier-syntax">area</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">pathname</span><span class="plain-syntax">, </span><span class="identifier-syntax">kit</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">search_paths</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Pathnames::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">web_md</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Wm</span><span class="plain-syntax"> = </span><span class="identifier-syntax">WebMetadata::get</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">V2_SYNTAX</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">chapter_md</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Cm</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">Cm</span><span class="plain-syntax">, </span><span class="identifier-syntax">chapter_md</span><span class="plain-syntax">, </span><span class="identifier-syntax">Wm</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">chapters_md</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">section_md</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Sm</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">Sm</span><span class="plain-syntax">, </span><span class="identifier-syntax">section_md</span><span class="plain-syntax">, </span><span class="identifier-syntax">Cm</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">sections_md</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">SF</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Sm</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">source_file_for_section</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="3-ps.html#SP9" class="function-link"><span class="function-syntax">ParsingStages::interpret</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">sf</span><span class="plain-syntax">, </span><span class="identifier-syntax">Sm</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">sect_title</span><span class="plain-syntax">, </span><span class="identifier-syntax">N_escape</span><span class="plain-syntax">, </span><span class="identifier-syntax">kit</span><span class="plain-syntax">, </span><span class="identifier-syntax">SF</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-ps.html#SP11" class="function-link"><span class="function-syntax">ParsingStages::interpret</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">sf</span><span class="plain-syntax">, </span><span class="identifier-syntax">Sm</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">sect_title</span><span class="plain-syntax">, </span><span class="identifier-syntax">N_escape</span><span class="plain-syntax">, </span><span class="identifier-syntax">kit</span><span class="plain-syntax">, </span><span class="identifier-syntax">SF</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
@ -381,11 +489,11 @@ and therefore no interventions will have happened.)
<span class="plain-syntax"> </span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Input_File</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">segment_name</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">Input_Filename</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP9_1" class="named-paragraph-link"><span class="named-paragraph">Open the I6 template file</span><span class="named-paragraph-number">9.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP11_1" class="named-paragraph-link"><span class="named-paragraph">Open the I6 template file</span><span class="named-paragraph-number">11.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">comment</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">comment</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP9_2" class="named-paragraph-link"><span class="named-paragraph">Interpret the I6T file</span><span class="named-paragraph-number">9.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP11_2" class="named-paragraph-link"><span class="named-paragraph">Interpret the I6T file</span><span class="named-paragraph-number">11.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Input_File</span><span class="plain-syntax">) { </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DL</span><span class="plain-syntax">) </span><span class="identifier-syntax">STREAM_FLUSH</span><span class="plain-syntax">(</span><span class="identifier-syntax">DL</span><span class="plain-syntax">); </span><span class="identifier-syntax">fclose</span><span class="plain-syntax">(</span><span class="identifier-syntax">Input_File</span><span class="plain-syntax">); }</span>
@ -393,25 +501,26 @@ and therefore no interventions will have happened.)
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure contents_section_state is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_1" class="paragraph-anchor"></a><b>&#167;9.1. </b>We look for the <span class="extract"><span class="extract-syntax">.i6t</span></span> files in a list of possible locations supplied as
<p class="commentary firstcommentary"><a id="SP11_1" class="paragraph-anchor"></a><b>&#167;11.1. </b>We look for the <span class="extract"><span class="extract-syntax">.i6t</span></span> files in a list of possible locations supplied as
part of the I6T kit.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Open the I6 template file</span><span class="named-paragraph-number">9.1</span></span><span class="comment-syntax"> =</span>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Open the I6 template file</span><span class="named-paragraph-number">11.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Input_Filename</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Input_File</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::fopen</span><span class="plain-syntax">(</span><span class="identifier-syntax">Input_Filename</span><span class="plain-syntax">, </span><span class="string-syntax">"r"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">area</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">area</span><span class="function-syntax">&lt;kit-&gt;</span><span class="element-syntax">no_i6t_file_areas</span><span class="plain-syntax">; </span><span class="identifier-syntax">area</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">pathname</span><span class="plain-syntax">, </span><span class="identifier-syntax">kit</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">search_paths</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Input_File</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Input_File</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::fopen</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">kit</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">i6t_files</span><span class="plain-syntax">[</span><span class="identifier-syntax">area</span><span class="plain-syntax">], </span><span class="identifier-syntax">segment_name</span><span class="plain-syntax">), </span><span class="string-syntax">"r"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">segment_name</span><span class="plain-syntax">), </span><span class="string-syntax">"r"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Input_File</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="2-pe.html#SP3" class="function-link"><span class="function-syntax">PipelineErrors::kit_error</span></a><span class="plain-syntax">(</span><span class="string-syntax">"unable to open the template segment '%S'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">segment_name</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP9">&#167;9</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_2" class="paragraph-anchor"></a><b>&#167;9.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Interpret the I6T file</span><span class="named-paragraph-number">9.2</span></span><span class="comment-syntax"> =</span>
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP11">&#167;11</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP11_2" class="paragraph-anchor"></a><b>&#167;11.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Interpret the I6T file</span><span class="named-paragraph-number">11.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
@ -420,22 +529,22 @@ part of the I6T kit.
<span class="plain-syntax"> </span><span class="reserved-syntax">do</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">command</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">argument</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP9_2_1" class="named-paragraph-link"><span class="named-paragraph">Read next character from I6T stream</span><span class="named-paragraph-number">9.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP11_2_1" class="named-paragraph-link"><span class="named-paragraph">Read next character from I6T stream</span><span class="named-paragraph-number">11.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">NewCharacter:</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="identifier-syntax">EOF</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="character-syntax">'@'</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="character-syntax">'='</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">col</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">inweb_syntax</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="character-syntax">'='</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP9_2_3" class="named-paragraph-link"><span class="named-paragraph">Read the rest of line as an equals-heading</span><span class="named-paragraph-number">9.2.3</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP9_2_2" class="named-paragraph-link"><span class="named-paragraph">Read the rest of line as an at-heading</span><span class="named-paragraph-number">9.2.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP9_2_4" class="named-paragraph-link"><span class="named-paragraph">Act on the heading, going in or out of comment mode as appropriate</span><span class="named-paragraph-number">9.2.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="character-syntax">'='</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP11_2_3" class="named-paragraph-link"><span class="named-paragraph">Read the rest of line as an equals-heading</span><span class="named-paragraph-number">11.2.3</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP11_2_2" class="named-paragraph-link"><span class="named-paragraph">Read the rest of line as an at-heading</span><span class="named-paragraph-number">11.2.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP11_2_4" class="named-paragraph-link"><span class="named-paragraph">Act on the heading, going in or out of comment mode as appropriate</span><span class="named-paragraph-number">11.2.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">comment</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP9_2_5" class="named-paragraph-link"><span class="named-paragraph">Deal with material which isn't commentary</span><span class="named-paragraph-number">9.2.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">comment</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP11_2_5" class="named-paragraph-link"><span class="named-paragraph">Deal with material which isn't commentary</span><span class="named-paragraph-number">11.2.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> != </span><span class="identifier-syntax">EOF</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">command</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">argument</span><span class="plain-syntax">)</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP9">&#167;9</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_2_1" class="paragraph-anchor"></a><b>&#167;9.2.1. </b>I6 template files are encoded as ISO Latin-1, not as Unicode UTF-8, so
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP11">&#167;11</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP11_2_1" class="paragraph-anchor"></a><b>&#167;11.2.1. </b>I6 template files are encoded as ISO Latin-1, not as Unicode UTF-8, so
ordinary <span class="extract"><span class="extract-syntax">fgetc</span></span> is used, and no BOM marker is parsed. Lines are assumed
to be terminated with either <span class="extract"><span class="extract-syntax">0x0a</span></span> or <span class="extract"><span class="extract-syntax">0x0d</span></span>. (Since blank lines are
harmless, we take no trouble over <span class="extract"><span class="extract-syntax">0a0d</span></span> or <span class="extract"><span class="extract-syntax">0d0a</span></span> combinations.) The
@ -443,7 +552,7 @@ built-in template files, almost always the only ones used, are line
terminated <span class="extract"><span class="extract-syntax">0x0a</span></span> in Unix fashion.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Read next character from I6T stream</span><span class="named-paragraph-number">9.2.1</span></span><span class="comment-syntax"> =</span>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Read next character from I6T stream</span><span class="named-paragraph-number">11.2.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
@ -453,8 +562,8 @@ terminated <span class="extract"><span class="extract-syntax">0x0a</span></span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">cr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EOF</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">col</span><span class="plain-syntax">++; </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="constant-syntax">10</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="constant-syntax">13</span><span class="plain-syntax">)) </span><span class="identifier-syntax">col</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP9_2">&#167;9.2</a>, <a href="3-ps.html#SP9_2_2">&#167;9.2.2</a>, <a href="3-ps.html#SP9_2_3">&#167;9.2.3</a>, <a href="3-ps.html#SP9_2_5">&#167;9.2.5</a> (three times), <a href="3-ps.html#SP9_2_5_1">&#167;9.2.5.1</a>, <a href="3-ps.html#SP9_2_5_2">&#167;9.2.5.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_2_2" class="paragraph-anchor"></a><b>&#167;9.2.2. </b>Anything following an at-character in the first column is looked at to see if
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP11_2">&#167;11.2</a>, <a href="3-ps.html#SP11_2_2">&#167;11.2.2</a>, <a href="3-ps.html#SP11_2_3">&#167;11.2.3</a>, <a href="3-ps.html#SP11_2_5">&#167;11.2.5</a> (three times), <a href="3-ps.html#SP11_2_5_1">&#167;11.2.5.1</a>, <a href="3-ps.html#SP11_2_5_2">&#167;11.2.5.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP11_2_2" class="paragraph-anchor"></a><b>&#167;11.2.2. </b>Anything following an at-character in the first column is looked at to see if
it's a heading, that is, an Inweb syntax. We recognise both <span class="extract"><span class="extract-syntax">@h</span></span> and <span class="extract"><span class="extract-syntax">@p</span></span> as
heading markers, in order to accommodate both old and new Inweb syntaxes.
</p>
@ -467,14 +576,14 @@ heading markers, in order to accommodate both old and new Inweb syntaxes.
<span class="definition-keyword">define</span> <span class="constant-syntax">INWEB_EQUALS_SYNTAX</span><span class="plain-syntax"> </span><span class="constant-syntax">6</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">INWEB_EXTRACT_SYNTAX</span><span class="plain-syntax"> </span><span class="constant-syntax">7</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Read the rest of line as an at-heading</span><span class="named-paragraph-number">9.2.2</span></span><span class="comment-syntax"> =</span>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Read the rest of line as an at-heading</span><span class="named-paragraph-number">11.2.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">I6T_buffer</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">committed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">unacceptable_character</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">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">MAX_I6T_LINE_LENGTH</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP9_2_1" class="named-paragraph-link"><span class="named-paragraph">Read next character from I6T stream</span><span class="named-paragraph-number">9.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP11_2_1" class="named-paragraph-link"><span class="named-paragraph">Read next character from I6T stream</span><span class="named-paragraph-number">11.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">committed</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; ((</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="constant-syntax">10</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="constant-syntax">13</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="character-syntax">' '</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_wide_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">I6T_buffer</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"p"</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inweb_syntax</span><span class="plain-syntax"> = </span><span class="constant-syntax">INWEB_PARAGRAPH_SYNTAX</span><span class="plain-syntax">;</span>
@ -523,15 +632,15 @@ heading markers, in order to accommodate both old and new Inweb syntaxes.
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::copy</span><span class="plain-syntax">(</span><span class="identifier-syntax">command</span><span class="plain-syntax">, </span><span class="identifier-syntax">I6T_buffer</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">I6T_buffer</span><span class="plain-syntax">)</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP9_2">&#167;9.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_2_3" class="paragraph-anchor"></a><b>&#167;9.2.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Read the rest of line as an equals-heading</span><span class="named-paragraph-number">9.2.3</span></span><span class="comment-syntax"> =</span>
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP11_2">&#167;11.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP11_2_3" class="paragraph-anchor"></a><b>&#167;11.2.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Read the rest of line as an equals-heading</span><span class="named-paragraph-number">11.2.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">I6T_buffer</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">MAX_I6T_LINE_LENGTH</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP9_2_1" class="named-paragraph-link"><span class="named-paragraph">Read next character from I6T stream</span><span class="named-paragraph-number">9.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP11_2_1" class="named-paragraph-link"><span class="named-paragraph">Read next character from I6T stream</span><span class="named-paragraph-number">11.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="constant-syntax">10</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="constant-syntax">13</span><span class="plain-syntax">)) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">I6T_buffer</span><span class="plain-syntax">, </span><span class="identifier-syntax">cr</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
@ -556,13 +665,13 @@ heading markers, in order to accommodate both old and new Inweb syntaxes.
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Regexp::dispose_of</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP9_2">&#167;9.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_2_4" class="paragraph-anchor"></a><b>&#167;9.2.4. </b>As can be seen, only a small minority of Inweb syntaxes are allowed:
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP11_2">&#167;11.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP11_2_4" class="paragraph-anchor"></a><b>&#167;11.2.4. </b>As can be seen, only a small minority of Inweb syntaxes are allowed:
in particular, no definitions<span class="extract"><span class="extract-syntax"> or angle-bracketed macros. This reader is not
</span></span>a full-fledged tangler.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on the heading, going in or out of comment mode as appropriate</span><span class="named-paragraph-number">9.2.4</span></span><span class="comment-syntax"> =</span>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on the heading, going in or out of comment mode as appropriate</span><span class="named-paragraph-number">11.2.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
@ -598,20 +707,20 @@ in particular, no definitions<span class="extract"><span class="extract-syntax">
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">INWEB_FIGURE_SYNTAX:</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP9_2">&#167;9.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_2_5" class="paragraph-anchor"></a><b>&#167;9.2.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Deal with material which isn't commentary</span><span class="named-paragraph-number">9.2.5</span></span><span class="comment-syntax"> =</span>
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP11_2">&#167;11.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP11_2_5" class="paragraph-anchor"></a><b>&#167;11.2.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Deal with material which isn't commentary</span><span class="named-paragraph-number">11.2.5</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="character-syntax">'{'</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP9_2_1" class="named-paragraph-link"><span class="named-paragraph">Read next character from I6T stream</span><span class="named-paragraph-number">9.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP11_2_1" class="named-paragraph-link"><span class="named-paragraph">Read next character from I6T stream</span><span class="named-paragraph-number">11.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="character-syntax">'-'</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP9_2_5_1" class="named-paragraph-link"><span class="named-paragraph">Read up to the next close brace as an I6T command and argument</span><span class="named-paragraph-number">9.2.5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP11_2_5_1" class="named-paragraph-link"><span class="named-paragraph">Read up to the next close brace as an I6T command and argument</span><span class="named-paragraph-number">11.2.5.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::get_first_char</span><span class="plain-syntax">(</span><span class="identifier-syntax">command</span><span class="plain-syntax">) == </span><span class="character-syntax">'!'</span><span class="plain-syntax">) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP9_2_5_3" class="named-paragraph-link"><span class="named-paragraph">Act on I6T command and argument</span><span class="named-paragraph-number">9.2.5.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP11_2_5_3" class="named-paragraph-link"><span class="named-paragraph">Act on I6T command and argument</span><span class="named-paragraph-number">11.2.5.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="character-syntax">'N'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">N_escape</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP9_2_1" class="named-paragraph-link"><span class="named-paragraph">Read next character from I6T stream</span><span class="named-paragraph-number">9.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP11_2_1" class="named-paragraph-link"><span class="named-paragraph">Read next character from I6T stream</span><span class="named-paragraph-number">11.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="character-syntax">'}'</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">N_escape</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
@ -624,9 +733,9 @@ in particular, no definitions<span class="extract"><span class="extract-syntax">
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="character-syntax">'('</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP9_2_1" class="named-paragraph-link"><span class="named-paragraph">Read next character from I6T stream</span><span class="named-paragraph-number">9.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP11_2_1" class="named-paragraph-link"><span class="named-paragraph">Read next character from I6T stream</span><span class="named-paragraph-number">11.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="character-syntax">'+'</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP9_2_5_2" class="named-paragraph-link"><span class="named-paragraph">Read up to the next plus close-bracket as an I7 expression</span><span class="named-paragraph-number">9.2.5.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP11_2_5_2" class="named-paragraph-link"><span class="named-paragraph">Read up to the next plus close-bracket as an I7 expression</span><span class="named-paragraph-number">11.2.5.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> { </span><span class="comment-syntax"> otherwise the open bracket was a literal</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="character-syntax">'('</span><span class="plain-syntax">);</span>
@ -635,13 +744,13 @@ in particular, no definitions<span class="extract"><span class="extract-syntax">
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">cr</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP9_2">&#167;9.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_2_5_1" class="paragraph-anchor"></a><b>&#167;9.2.5.1. </b>And here we read a normal command. The command name must not include <span class="extract"><span class="extract-syntax">}</span></span>
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP11_2">&#167;11.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP11_2_5_1" class="paragraph-anchor"></a><b>&#167;11.2.5.1. </b>And here we read a normal command. The command name must not include <span class="extract"><span class="extract-syntax">}</span></span>
or <span class="extract"><span class="extract-syntax">:</span></span>. If there is no <span class="extract"><span class="extract-syntax">:</span></span> then the argument is left unset (so that it will
be the empty string: see above). The argument must not include <span class="extract"><span class="extract-syntax">}</span></span>.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Read up to the next close brace as an I6T command and argument</span><span class="named-paragraph-number">9.2.5.1</span></span><span class="comment-syntax"> =</span>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Read up to the next close brace as an I6T command and argument</span><span class="named-paragraph-number">11.2.5.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
@ -649,25 +758,25 @@ be the empty string: see above). The argument must not include <span class="extr
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">argument</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">com_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP9_2_1" class="named-paragraph-link"><span class="named-paragraph">Read next character from I6T stream</span><span class="named-paragraph-number">9.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP11_2_1" class="named-paragraph-link"><span class="named-paragraph">Read next character from I6T stream</span><span class="named-paragraph-number">11.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="character-syntax">'}'</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="identifier-syntax">EOF</span><span class="plain-syntax">)) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="character-syntax">':'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">com_mode</span><span class="plain-syntax">)) { </span><span class="identifier-syntax">com_mode</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">com_mode</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">command</span><span class="plain-syntax">, </span><span class="identifier-syntax">cr</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">argument</span><span class="plain-syntax">, </span><span class="identifier-syntax">cr</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP9_2_5">&#167;9.2.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_2_5_2" class="paragraph-anchor"></a><b>&#167;9.2.5.2. </b>And similarly, for the <span class="extract"><span class="extract-syntax">(+</span></span> ... <span class="extract"><span class="extract-syntax">+)</span></span> notation used to mark I7 material
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP11_2_5">&#167;11.2.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP11_2_5_2" class="paragraph-anchor"></a><b>&#167;11.2.5.2. </b>And similarly, for the <span class="extract"><span class="extract-syntax">(+</span></span> ... <span class="extract"><span class="extract-syntax">+)</span></span> notation used to mark I7 material
within I6:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Read up to the next plus close-bracket as an I7 expression</span><span class="named-paragraph-number">9.2.5.2</span></span><span class="comment-syntax"> =</span>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Read up to the next plus close-bracket as an I7 expression</span><span class="named-paragraph-number">11.2.5.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">i7_exp</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP9_2_1" class="named-paragraph-link"><span class="named-paragraph">Read next character from I6T stream</span><span class="named-paragraph-number">9.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP11_2_1" class="named-paragraph-link"><span class="named-paragraph">Read next character from I6T stream</span><span class="named-paragraph-number">11.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="identifier-syntax">EOF</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cr</span><span class="plain-syntax"> == </span><span class="character-syntax">')'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Str::get_last_char</span><span class="plain-syntax">(</span><span class="identifier-syntax">i7_exp</span><span class="plain-syntax">) == </span><span class="character-syntax">'+'</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::delete_last_character</span><span class="plain-syntax">(</span><span class="identifier-syntax">i7_exp</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">; }</span>
@ -677,16 +786,16 @@ within I6:
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">i7_exp</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="2-pe.html#SP3" class="function-link"><span class="function-syntax">PipelineErrors::kit_error</span></a><span class="plain-syntax">(</span><span class="string-syntax">"use of (+ ... +) in the template has been withdrawn: '%S'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">i7_exp</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP9_2_5">&#167;9.2.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_2_5_3" class="paragraph-anchor"></a><b>&#167;9.2.5.3. Acting on I6T commands. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on I6T command and argument</span><span class="named-paragraph-number">9.2.5.3</span></span><span class="comment-syntax"> =</span>
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP11_2_5">&#167;11.2.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP11_2_5_3" class="paragraph-anchor"></a><b>&#167;11.2.5.3. Acting on I6T commands. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on I6T command and argument</span><span class="named-paragraph-number">11.2.5.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP9_2_5_3_1" class="named-paragraph-link"><span class="named-paragraph">Act on the I6T segment command</span><span class="named-paragraph-number">9.2.5.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-ps.html#SP11_2_5_3_1" class="named-paragraph-link"><span class="named-paragraph">Act on the I6T segment command</span><span class="named-paragraph-number">11.2.5.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> (*(</span><span class="identifier-syntax">kit</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">command_callback</span><span class="plain-syntax">))(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">command</span><span class="plain-syntax">, </span><span class="identifier-syntax">argument</span><span class="plain-syntax">, </span><span class="identifier-syntax">kit</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP9_2_5">&#167;9.2.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_2_5_3_1" class="paragraph-anchor"></a><b>&#167;9.2.5.3.1. </b>The <span class="extract"><span class="extract-syntax">{-segment:...}</span></span> command recursively calls the I6T interpreter on the
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP11_2_5">&#167;11.2.5</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP11_2_5_3_1" class="paragraph-anchor"></a><b>&#167;11.2.5.3.1. </b>The <span class="extract"><span class="extract-syntax">{-segment:...}</span></span> command recursively calls the I6T interpreter on the
supplied I6T filename, which means it acts rather like <span class="extract"><span class="extract-syntax">#include</span></span> in C.
Note that because we pass the current output file handle <span class="extract"><span class="extract-syntax">of</span></span> through to
this new invocation, it will have the file open if we do, and closed if
@ -694,7 +803,7 @@ we do. It won't run in indexing mode, so <span class="extract"><span class="extr
safely between <span class="extract"><span class="extract-syntax">{-open-index}</span></span> and <span class="extract"><span class="extract-syntax">{-close-index}</span></span>.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on the I6T segment command</span><span class="named-paragraph-number">9.2.5.3.1</span></span><span class="comment-syntax"> =</span>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Act on the I6T segment command</span><span class="named-paragraph-number">11.2.5.3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
@ -702,14 +811,14 @@ safely between <span class="extract"><span class="extract-syntax">{-open-index}<
<span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"neurotica!"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> (*(</span><span class="identifier-syntax">kit</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">raw_callback</span><span class="plain-syntax">))(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">kit</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-ps.html#SP9" class="function-link"><span class="function-syntax">ParsingStages::interpret</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">argument</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">kit</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-ps.html#SP11" class="function-link"><span class="function-syntax">ParsingStages::interpret</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">argument</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">kit</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> (*(</span><span class="identifier-syntax">kit</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">raw_callback</span><span class="plain-syntax">))(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">kit</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP9_2_5_3">&#167;9.2.5.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. Contents section. </b></p>
<ul class="endnotetexts"><li>This code is used in <a href="3-ps.html#SP11_2_5_3">&#167;11.2.5.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. Contents section. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ParsingStages::read_contents</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">state</span><span class="plain-syntax">) {</span>

View file

@ -1,10 +1,10 @@
Total memory consumption was 400127K = 391 MB
60.9% was used for 2026653 objects, in 380059 frames in 305 x 800K = 244000K = 238 MB:
60.9% was used for 2026654 objects, in 380060 frames in 305 x 800K = 244000K = 238 MB:
10.2% inter_tree_node_array 58 x 8192 = 475136 objects, 41813824 bytes
7.2% text_stream_array 5302 x 100 = 530200 objects, 29860864 bytes
4.7% linked_list 34789 objects, 19481840 bytes
4.7% linked_list 34790 objects, 19482400 bytes
3.9% inter_symbol_array 140 x 1024 = 143360 objects, 16060800 bytes
2.5% parse_node 129462 objects, 10356960 bytes
1.8% verb_conjugation 160 objects, 7425280 bytes
@ -255,5 +255,5 @@ Total memory consumption was 400127K = 391 MB
---- code generation workspace for objects 1336 bytes in 4 claims
---- emitter array storage 161792 bytes in 2062 claims
18.5% was overhead - 76160600 bytes = 74375K = 72 MB
18.5% was overhead - 76160040 bytes = 74375K = 72 MB

View file

@ -1,36 +1,36 @@
100.0% in inform7 run
55.6% in compilation to Inter
40.1% in //Sequence::undertake_queued_tasks//
3.5% in //MajorNodes::pre_pass//
56.0% in compilation to Inter
40.5% in //Sequence::undertake_queued_tasks//
3.4% in //MajorNodes::pre_pass//
2.4% in //MajorNodes::pass_1//
2.1% in //RTPhrasebook::compile_entries//
2.2% in //RTPhrasebook::compile_entries//
1.3% in //ImperativeDefinitions::assess_all//
1.2% in //RTKindConstructors::compile//
0.4% in //MajorNodes::pass_2//
0.4% in //Sequence::undertake_queued_tasks//
0.4% in //Sequence::undertake_queued_tasks//
0.4% in //World::stage_V//
0.3% in //ImperativeDefinitions::compile_first_block//
0.3% in //Sequence::undertake_queued_tasks//
0.1% in //CompletionModule::compile//
0.1% in //InferenceSubjects::emit_all//
0.1% in //RTKindConstructors::compile_permissions//
0.1% in //Task::make_built_in_kind_constructors//
2.0% not specifically accounted for
42.3% in running Inter pipeline
11.9% in step preparation
2.1% not specifically accounted for
42.0% in running Inter pipeline
12.0% in step preparation
9.7% in inter step 7/16: consolidate-text
8.2% in inter step 6/16: load-binary-kits
8.1% in inter step 6/16: load-binary-kits
6.9% in inter step 16/16: generate inform6 -> auto.inf
1.5% in inter step 11/16: make-identifiers-unique
1.6% in inter step 11/16: make-identifiers-unique
0.4% in inter step 12/16: reconcile-verbs
0.3% in inter step 14/16: eliminate-redundant-operations
0.3% in inter step 5/16: assimilate
0.3% in inter step 8/16: resolve-external-symbols
0.3% in inter step 9/16: inspect-plugs
0.1% in inter step 10/16: detect-indirect-calls
0.1% in inter step 13/16: eliminate-redundant-labels
0.1% in inter step 3/16: parse-linked-matter
0.1% in inter step 4/16: resolve-conditional-compilation
0.1% in inter step 9/16: inspect-plugs
1.7% not specifically accounted for
1.7% in supervisor
1.4% not specifically accounted for
1.6% in supervisor
0.4% not specifically accounted for

View file

@ -5,6 +5,14 @@ imsertions made using Inform 7's low-level features, or after reading the
source code for a kit.
@h The two stages.
These stages have more in common than they first appear. Both convert I6T-syntax
source code into a series of |SPLAT_IST| nodes in the Inter tree, with one
such node for each different directive in the I6T source.
The T in "I6T" stands for "template", which in the 2010s was a mechanism for
providing I6 code to I7. That's not the arrangement any more, but the syntax
(mostly) lives on, and so does the name I6T. Still, it's really just the same
thing as Inform 6 code in an Inweb-style literate programming notation.
=
void ParsingStages::create_pipeline_stage(void) {
@ -15,9 +23,8 @@ void ParsingStages::create_pipeline_stage(void) {
}
@ The stage |load-kit-source K| takes the kit |K|, looks for its source code
(which will be Inform 6-syntax source code written in a literate programming
notation) and reads this in to the current Inter tree, as a new top-level
module.
(text files written in I6T syntax) and reads this in to the current Inter tree,
placing the resulting nodes in a new top-level module.
=
int ParsingStages::run_load_kit_source(pipeline_step *step) {
@ -26,13 +33,13 @@ int ParsingStages::run_load_kit_source(pipeline_step *step) {
if (main_package) @<Create a module to hold the Inter read in from this kit@>;
I6T_kit kit;
@<Make a suitable I6T kit@>;
ParsingStages::capture(&kit, NULL, I"all");
ParsingStages::I6T_reader(&kit, NULL, I"all");
return TRUE;
}
@ So for example if we are reading the source for WorldModelKit, then the
following creates the package |/main/WorldModelKit|, with package type |_module|.
It's into this module that all the code will be read.
It's into this module that the resulting |SPLAT_IST| nodes will be put.
@<Create a module to hold the Inter read in from this kit@> =
inter_bookmark IBM = Inter::Bookmarks::at_end_of_this_package(main_package);
@ -42,117 +49,78 @@ It's into this module that all the code will be read.
module_name, 1, NULL, &template_p);
Site::set_assimilation_package(I, template_p);
@ =
@ The stage |parse-insertions| does the same thing, but on a much smaller scale,
and reading raw I6T source code from |LINK_IST| nodes in the Inter tree rather
than from an external file. There will only be a few of these, and with not much
code in them, when the tree has been compiled by Inform: they arise from
features such as
= (text as Inform 7)
Include (-
[ CuriousFunction;
print "Curious!";
];
-).
=
The //inform7// code does not contain a compiler from I6T down to Inter, so
it can only leave us these unparsed fragments as |LINK_IST| nodes. We take
it from there.
=
int ParsingStages::run_parse_insertions(pipeline_step *step) {
inter_tree *I = step->ephemera.repository;
I6T_kit kit;
@<Make a suitable I6T kit@>;
InterTree::traverse(I, ParsingStages::catch_all_visitor, &kit, NULL, 0);
InterTree::traverse(I, ParsingStages::visit_insertions, &kit, NULL, LINK_IST);
return TRUE;
}
void ParsingStages::catch_all_visitor(inter_tree *I, inter_tree_node *P, void *state) {
if (P->W.data[ID_IFLD] == LINK_IST) {
text_stream *insertion = Inode::ID_to_text(P, P->W.data[TO_RAW_LINK_IFLD]);
#ifdef CORE_MODULE
current_sentence = (parse_node *) Inode::ID_to_ref(P, P->W.data[REF_LINK_IFLD]);
#endif
I6T_kit *kit = (I6T_kit *) state;
ParsingStages::capture(kit, insertion, NULL);
}
void ParsingStages::visit_insertions(inter_tree *I, inter_tree_node *P, void *state) {
text_stream *insertion = Inode::ID_to_text(P, P->W.data[TO_RAW_LINK_IFLD]);
#ifdef CORE_MODULE
current_sentence = (parse_node *) Inode::ID_to_ref(P, P->W.data[REF_LINK_IFLD]);
#endif
I6T_kit *kit = (I6T_kit *) state;
ParsingStages::I6T_reader(kit, insertion, NULL);
}
@ So, then, both of those stages rely on (i) making something called an I6T kit,
then (ii) calling //ParsingStages::I6T_reader//.
Here's where we make the kit, which is really just a collection of settings for
the I6T-reader. That comes down to:
(a) the place to put any nodes generated,
(b) what to do with I6 source code, or with commands embedded in it, and
(c) which file-system paths to look inside when reading from files rather
than raw text in memory.
For (c), note that if a kit is in directory |K| then its source files are
in |K/Sections|.
@<Make a suitable I6T kit@> =
linked_list *PP = step->ephemera.the_PP;
inter_package *template_package = Site::ensure_assimilation_package(I, RunningPipelines::get_symbol(step, plain_ptype_RPSYM));
inter_bookmark link_bookmark =
Inter::Bookmarks::at_end_of_this_package(template_package);
kit = ParsingStages::kit_out(&link_bookmark, &(ParsingStages::receive_raw), &(ParsingStages::receive_command), NULL);
kit.no_i6t_file_areas = LinkedLists::len(PP);
inter_package *assimilation_package = Site::ensure_assimilation_package(I,
RunningPipelines::get_symbol(step, plain_ptype_RPSYM));
inter_bookmark assimilation_point =
Inter::Bookmarks::at_end_of_this_package(assimilation_package);
linked_list *L = NEW_LINKED_LIST(pathname);
pathname *P;
int i=0;
LOOP_OVER_LINKED_LIST(P, pathname, PP)
kit.i6t_files[i++] = Pathnames::down(P, I"Sections");
LOOP_OVER_LINKED_LIST(P, pathname, step->ephemera.the_PP)
ADD_TO_LINKED_LIST(Pathnames::down(P, I"Sections"), pathname, L);
kit = ParsingStages::kit_out(&assimilation_point,
&(ParsingStages::receive_raw), &(ParsingStages::receive_command), L, NULL);
@
@ Once the I6T reader has unpacked the literate-programming notation, it will
reduce the I6T code to pure Inform 6 source together with (perhaps) a handful of
commands in braces. Our kit must say what to do with each of these outputs.
@d IGNORE_WS_FILTER_BIT 1
@d DQUOTED_FILTER_BIT 2
@d SQUOTED_FILTER_BIT 4
@d COMMENTED_FILTER_BIT 8
@d ROUTINED_FILTER_BIT 16
@d CONTENT_ON_LINE_FILTER_BIT 32
@d SUBORDINATE_FILTER_BITS (COMMENTED_FILTER_BIT + SQUOTED_FILTER_BIT + DQUOTED_FILTER_BIT + ROUTINED_FILTER_BIT)
The easy part: what to do when we find a command in I6T source. In pre-Inter
versions of Inform, when I6T was just a way of expressing Inform 6 code but
with some braced commands mixed in, there were lots of legal if enigmatic
syntaxes in use. Now those have all gone, so in all cases we issue an error:
=
void ParsingStages::receive_raw(text_stream *S, I6T_kit *kit) {
text_stream *R = Str::new();
int mode = IGNORE_WS_FILTER_BIT;
LOOP_THROUGH_TEXT(pos, S) {
wchar_t c = Str::get(pos);
if ((c == 10) || (c == 13)) c = '\n';
if (mode & IGNORE_WS_FILTER_BIT) {
if ((c == '\n') || (Characters::is_whitespace(c))) continue;
mode -= IGNORE_WS_FILTER_BIT;
}
if ((c == '!') && (!(mode & (DQUOTED_FILTER_BIT + SQUOTED_FILTER_BIT)))) {
mode = mode | COMMENTED_FILTER_BIT;
}
if (mode & COMMENTED_FILTER_BIT) {
if (c == '\n') {
mode -= COMMENTED_FILTER_BIT;
if (!(mode & CONTENT_ON_LINE_FILTER_BIT)) continue;
}
else continue;
}
if ((c == '[') && (!(mode & SUBORDINATE_FILTER_BITS))) {
mode = mode | ROUTINED_FILTER_BIT;
}
if (mode & ROUTINED_FILTER_BIT) {
if ((c == ']') && (!(mode & (DQUOTED_FILTER_BIT + SQUOTED_FILTER_BIT + COMMENTED_FILTER_BIT)))) mode -= ROUTINED_FILTER_BIT;
}
if ((c == '\'') && (!(mode & (DQUOTED_FILTER_BIT + COMMENTED_FILTER_BIT)))) {
if (mode & SQUOTED_FILTER_BIT) mode -= SQUOTED_FILTER_BIT;
else mode = mode | SQUOTED_FILTER_BIT;
}
if ((c == '\"') && (!(mode & (SQUOTED_FILTER_BIT + COMMENTED_FILTER_BIT)))) {
if (mode & DQUOTED_FILTER_BIT) mode -= DQUOTED_FILTER_BIT;
else mode = mode | DQUOTED_FILTER_BIT;
}
if (c != '\n') {
if (Characters::is_whitespace(c) == FALSE) mode = mode | CONTENT_ON_LINE_FILTER_BIT;
} else {
if (mode & CONTENT_ON_LINE_FILTER_BIT) mode = mode - CONTENT_ON_LINE_FILTER_BIT;
else if (!(mode & SUBORDINATE_FILTER_BITS)) continue;
}
PUT_TO(R, c);
if ((c == ';') && (!(mode & SUBORDINATE_FILTER_BITS))) {
ParsingStages::chunked_raw(R, kit);
mode = IGNORE_WS_FILTER_BIT;
}
}
ParsingStages::chunked_raw(R, kit);
Str::clear(S);
}
void ParsingStages::chunked_raw(text_stream *S, I6T_kit *kit) {
if (Str::len(S) == 0) return;
PUT_TO(S, '\n');
ParsingStages::entire_splat(kit->IBM, I"template", S, (inter_ti) (Inter::Bookmarks::baseline(kit->IBM) + 1));
Str::clear(S);
}
void ParsingStages::entire_splat(inter_bookmark *IBM, text_stream *origin, text_stream *content, inter_ti level) {
inter_ti SID = Inter::Warehouse::create_text(Inter::Bookmarks::warehouse(IBM), Inter::Bookmarks::package(IBM));
text_stream *glob_storage = Inter::Warehouse::get_text(Inter::Bookmarks::warehouse(IBM), SID);
Str::copy(glob_storage, content);
Produce::guard(Inter::Splat::new(IBM, SID, 0, level, 0, NULL));
}
void ParsingStages::receive_command(OUTPUT_STREAM, text_stream *command, text_stream *argument, I6T_kit *kit) {
void ParsingStages::receive_command(OUTPUT_STREAM, text_stream *command,
text_stream *argument, I6T_kit *kit) {
if ((Str::eq_wide_string(command, L"plugin")) ||
(Str::eq_wide_string(command, L"type")) ||
(Str::eq_wide_string(command, L"open-file")) ||
@ -177,54 +145,175 @@ void ParsingStages::receive_command(OUTPUT_STREAM, text_stream *command, text_st
(Str::eq_wide_string(command, L"testing-routine")) ||
(Str::eq_wide_string(command, L"testing-command"))) {
LOG("command: <%S> argument: <%S>\n", command, argument);
PipelineErrors::kit_error("the template command '{-%S}' has been withdrawn in this version of Inform", command);
PipelineErrors::kit_error(
"the template command '{-%S}' has been withdrawn in this version of Inform",
command);
} else {
LOG("command: <%S> argument: <%S>\n", command, argument);
PipelineErrors::kit_error("no such {-command} as '%S'", command);
}
}
@h I6T kits.
These are used to abstract calls to the I6T reader, so that customers of
varying dispositions can do different things with the code parsed.
@ We very much do not ignore the raw I6 code read in, though. When the reader
gives us a chunk of this, we parse through it with a simple finite-state machine.
This can be summarised as "divide the code up at |;| boundaries, sending each
piece in turn to //ParsingStages::splat//". But of course we do not want to
react to semicolons in quoted text or comments, and in fact we also do not
want to react to semicolons used as statement dividers inside I6 routines (i.e.,
functions). So for example
= (text as Inform 6)
Global aspic = "this; and that";
! Don't react to this; I'm only a comment
[ Hello; print "Hello; goodbye.^"; ];
=
would be divided into just two splats,
= (text as Inform 6)
Global aspic = "this; and that";
=
and
= (text as Inform 6)
[ Hello; print "Hello; goodbye.^"; ];
=
(And the comment would be stripped out entirely.)
@ =
@d IGNORE_WS_I6TBIT 1
@d DQUOTED_I6TBIT 2
@d SQUOTED_I6TBIT 4
@d COMMENTED_I6TBIT 8
@d ROUTINED_I6TBIT 16
@d CONTENT_ON_LINE_I6TBIT 32
@d SUBORDINATE_I6TBITS
(COMMENTED_I6TBIT + SQUOTED_I6TBIT + DQUOTED_I6TBIT + ROUTINED_I6TBIT)
=
void ParsingStages::receive_raw(text_stream *S, I6T_kit *kit) {
text_stream *R = Str::new();
int mode = IGNORE_WS_I6TBIT;
LOOP_THROUGH_TEXT(pos, S) {
wchar_t c = Str::get(pos);
if ((c == 10) || (c == 13)) c = '\n';
if (mode & IGNORE_WS_I6TBIT) {
if ((c == '\n') || (Characters::is_whitespace(c))) continue;
mode -= IGNORE_WS_I6TBIT;
}
if ((c == '!') && (!(mode & (DQUOTED_I6TBIT + SQUOTED_I6TBIT)))) {
mode = mode | COMMENTED_I6TBIT;
}
if (mode & COMMENTED_I6TBIT) {
if (c == '\n') {
mode -= COMMENTED_I6TBIT;
if (!(mode & CONTENT_ON_LINE_I6TBIT)) continue;
}
else continue;
}
if ((c == '[') && (!(mode & SUBORDINATE_I6TBITS))) {
mode = mode | ROUTINED_I6TBIT;
}
if (mode & ROUTINED_I6TBIT) {
if ((c == ']') && (!(mode & (DQUOTED_I6TBIT + SQUOTED_I6TBIT + COMMENTED_I6TBIT))))
mode -= ROUTINED_I6TBIT;
}
if ((c == '\'') && (!(mode & (DQUOTED_I6TBIT + COMMENTED_I6TBIT)))) {
if (mode & SQUOTED_I6TBIT) mode -= SQUOTED_I6TBIT;
else mode = mode | SQUOTED_I6TBIT;
}
if ((c == '\"') && (!(mode & (SQUOTED_I6TBIT + COMMENTED_I6TBIT)))) {
if (mode & DQUOTED_I6TBIT) mode -= DQUOTED_I6TBIT;
else mode = mode | DQUOTED_I6TBIT;
}
if (c != '\n') {
if (Characters::is_whitespace(c) == FALSE)
mode = mode | CONTENT_ON_LINE_I6TBIT;
} else {
if (mode & CONTENT_ON_LINE_I6TBIT) mode = mode - CONTENT_ON_LINE_I6TBIT;
else if (!(mode & SUBORDINATE_I6TBITS)) continue;
}
PUT_TO(R, c);
if ((c == ';') && (!(mode & SUBORDINATE_I6TBITS))) {
ParsingStages::splat(R, kit);
mode = IGNORE_WS_I6TBIT;
}
}
ParsingStages::splat(R, kit);
Str::clear(S);
}
@ Each of those "splats" becomes a |SPLAT_IST| node in the tree at the
current insertion point recorded in the kit.
Note that this function empties the splat buffer |R| before exiting.
=
void ParsingStages::splat(text_stream *R, I6T_kit *kit) {
if (Str::len(R) > 0) {
PUT_TO(R, '\n');
inter_ti SID = Inter::Warehouse::create_text(
Inter::Bookmarks::warehouse(kit->IBM), Inter::Bookmarks::package(kit->IBM));
text_stream *textual_storage =
Inter::Warehouse::get_text(Inter::Bookmarks::warehouse(kit->IBM), SID);
Str::copy(textual_storage, R);
Produce::guard(Inter::Splat::new(kit->IBM, SID, 0,
(inter_ti) (Inter::Bookmarks::baseline(kit->IBM) + 1), 0, NULL));
Str::clear(R);
}
}
@ And that's it: the result of these stages is just to break the I6T source they
found up into individual directives, and put them into the tree as |SPLAT_IST| nodes.
No effort has been made yet to see what directives they are. Subsequent stages
will handle that.
@h The I6T Reader.
The rest of this section, then, is a general-purpose reader of I6T-syntax code.
Although it is only used for one purpose in the Inform code base, it once had
multiple uses, and so it's written quite flexibly. There seems no reason to
get rid of that flexibility: perhaps we'll use it again some day.
So, then, this is the parcel of settings for controlling the I6T reader:
=
typedef struct I6T_kit {
struct inter_bookmark *IBM;
int no_i6t_file_areas;
struct pathname *i6t_files[16];
void (*raw_callback)(struct text_stream *, struct I6T_kit *);
void (*command_callback)(struct text_stream *, struct text_stream *, struct text_stream *, struct I6T_kit *);
void (*command_callback)(struct text_stream *, struct text_stream *,
struct text_stream *, struct I6T_kit *);
void *I6T_state;
struct linked_list *search_paths; /* of |pathname| */
} I6T_kit;
@ =
I6T_kit ParsingStages::kit_out(inter_bookmark *IBM, void (*A)(struct text_stream *, struct I6T_kit *),
void (*B)(struct text_stream *, struct text_stream *, struct text_stream *, struct I6T_kit *),
void *C) {
@ We actually don't use this facility, but a kit contains a |state| which is
shared across the calls to the callback functions. When a kit is created, the
initial state must be supplied; after that, it's updated only by the callback
functions supplied.
=
I6T_kit ParsingStages::kit_out(inter_bookmark *IBM,
void (*A)(struct text_stream *, struct I6T_kit *),
void (*B)(struct text_stream *, struct text_stream *,
struct text_stream *, struct I6T_kit *),
linked_list *search_list, void *initial_state) {
I6T_kit kit;
kit.IBM = IBM;
kit.raw_callback = A;
kit.command_callback = B;
kit.I6T_state = C;
kit.no_i6t_file_areas = 0;
kit.I6T_state = initial_state;
kit.search_paths = search_list;
return kit;
}
@h Syntax of I6T files.
The syntax of these files has been designed so that a valid I6T file is
also a valid Inweb section file. (Inweb now has two formats, an old and a
new one: here we can read either, though the I6T sources in the main Inform
distribution have been modernised to the new syntax.) Many Inweb syntaxes
are, however, not allowed in I6T: really, you should use only |@h| headings
and the |=| sign to divide commentary from text. Macros and definitions, in
particular, are not permitted. This means that no real tangling is required
to make the I6T files.
@ I6T files use a literate programming notation which is, in effect, a much
simplified version of Inweb's. (Note that Inweb can therefore read kits as
if they were webs, and we use that to weave them for the source website.)
Many Inweb syntaxes are, however, not allowed in I6T: really, you should use
only |@h| headings and the |=| sign to divide commentary from text. Macros and
definitions, in particular, are not permitted; I6T is not really tangled as such.
The entire range of possibilities is shown here:
= (text as Inweb)
Circuses.
This hypothetical I6T file provides support for holding circuses.
@h Start.
@ -259,7 +348,7 @@ typedef struct contents_section_state {
int active;
} contents_section_state;
void ParsingStages::capture(I6T_kit *kit, text_stream *insertion, text_stream *segment) {
void ParsingStages::I6T_reader(I6T_kit *kit, text_stream *insertion, text_stream *segment) {
TEMPORARY_TEXT(T)
ParsingStages::interpret(T, insertion, segment, -1, kit, NULL);
(*(kit->raw_callback))(T, kit);
@ -269,8 +358,9 @@ void ParsingStages::capture(I6T_kit *kit, text_stream *insertion, text_stream *s
void ParsingStages::interpret(OUTPUT_STREAM, text_stream *sf,
text_stream *segment_name, int N_escape, I6T_kit *kit, filename *Input_Filename) {
if (Str::eq(segment_name, I"all")) {
for (int area=0; area<kit->no_i6t_file_areas; area++) {
pathname *P = Pathnames::up(kit->i6t_files[area]);
pathname *K;
LOOP_OVER_LINKED_LIST(K, pathname, kit->search_paths) {
pathname *P = Pathnames::up(K);
web_md *Wm = WebMetadata::get(P, NULL, V2_SYNTAX, NULL, FALSE, TRUE, NULL);
chapter_md *Cm;
LOOP_OVER_LINKED_LIST(Cm, chapter_md, Wm->chapters_md) {
@ -306,10 +396,11 @@ part of the I6T kit.
@<Open the I6 template file@> =
if (Input_Filename)
Input_File = Filenames::fopen(Input_Filename, "r");
for (int area=0; area<kit->no_i6t_file_areas; area++)
pathname *P;
LOOP_OVER_LINKED_LIST(P, pathname, kit->search_paths)
if (Input_File == NULL)
Input_File = Filenames::fopen(
Filenames::in(kit->i6t_files[area], segment_name), "r");
Filenames::in(P, segment_name), "r");
if (Input_File == NULL)
PipelineErrors::kit_error("unable to open the template segment '%S'", segment_name);