1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-06-26 04:00:43 +03:00

Documented arch module

This commit is contained in:
Graham Nelson 2020-05-09 23:49:59 +01:00
parent baff90449f
commit dd8233116c
53 changed files with 1081 additions and 403 deletions

View file

@ -58,7 +58,7 @@
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Shared Modules</a></li><li><a href="index.html">arch</a></li><li><a href="index.html#1">Chapter 1: Setting Up</a></li><li><b>Arch Module</b></li></ul></div>
<p class="purpose">Setting up the use of this module.</p>
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <span class="extract"><span class="extract-syntax">foundation</span></span>, and
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <a href="../../../inweb/docs/foundation-module/index.html" class="internal">foundation</a>, and
contains no code of interest. The following constant exists only in tools
which use this module:
</p>
@ -86,8 +86,8 @@ which use this module:
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-am.html#SP3_2" class="named-paragraph-link"><span class="named-paragraph">Register this module's stream writers</span><span class="named-paragraph-number">3.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-am.html#SP3_3" class="named-paragraph-link"><span class="named-paragraph">Register this module's debugging log aspects</span><span class="named-paragraph-number">3.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-am.html#SP3_4" class="named-paragraph-link"><span class="named-paragraph">Register this module's debugging log writers</span><span class="named-paragraph-number">3.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="2-arc.html#SP1" class="function-link"><span class="function-syntax">Architectures::create</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><a href="2-tvm.html#SP1" class="function-link"><span class="function-syntax">TargetVMs::create</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><a href="2-arc.html#SP3" class="function-link"><span class="function-syntax">Architectures::create</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><a href="2-tvm.html#SP3" class="function-link"><span class="function-syntax">TargetVMs::create</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ArchModule::end</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">}</span>
@ -121,7 +121,7 @@ which use this module:
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="1-am.html#SP3">&#167;3</a>.</li></ul>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprevoff">&#10094;</li><li class="progresscurrentchapter">1</li><li class="progresscurrent">am</li><li class="progresschapter"><a href="2-arc.html">2</a></li><li class="progressnext"><a href="2-arc.html">&#10095;</a></li></ul></div>
<ul class="progressbar"><li class="progressprev"><a href="P-wtmd.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresscurrentchapter">1</li><li class="progresscurrent">am</li><li class="progresschapter"><a href="2-arc.html">2</a></li><li class="progressnext"><a href="2-arc.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>

View file

@ -63,12 +63,21 @@ function togglePopup(material_id) {
<main role="main">
<!--Weave of 'Architectures' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Shared Modules</a></li><li><a href="index.html">arch</a></li><li><a href="index.html#2">Chapter 2: Architectures</a></li><li><b>Architectures</b></li></ul></div>
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Shared Modules</a></li><li><a href="index.html">arch</a></li><li><a href="index.html#2">Chapter 2: Architectures and VMs</a></li><li><b>Architectures</b></li></ul></div>
<p class="purpose">To deal with multiple inter architectures.</p>
<ul class="toc"><li><a href="2-arc.html#SP1">&#167;1. Architectures</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="2-arc.html#SP1">&#167;1. Architectures</a></li><li><a href="2-arc.html#SP3">&#167;3. Standard set</a></li><li><a href="2-arc.html#SP4">&#167;4. Canonical filenames</a></li><li><a href="2-arc.html#SP5">&#167;5. Shorthand</a></li><li><a href="2-arc.html#SP6">&#167;6. What an architecture offers</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. Architectures. </b></p>
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. Architectures. </b>An "architecture" is a choice of how to use Inter code: for example, with the
expectation that it will have 32-bit rather than 16-bit integers. These are
not different Inter formats: two Inter files could, in fact, be identical
and yet one could be intended to be code-generated to a 32-bit program
and another to 16-bit. In effect, an "architecture" holds the settings which
<a href="../inform7/index.html" class="internal">inform7</a> uses when turning source text into Inter code.
</p>
<p class="commentary">Each different architecture is represented by one of these:
</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">inter_architecture</span><span class="plain-syntax"> {</span>
@ -77,22 +86,36 @@ function togglePopup(material_id) {
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">debug_enabled</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">inter_architecture</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure inter_architecture is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP2"></a><b>&#167;2. </b></p>
<span class="reserved-syntax">inter_architecture</span><span class="plain-syntax"> *</span><span class="function-syntax">Architectures::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">code</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">s</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">d</span><span class="plain-syntax">) {</span>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">inter_architecture</span><span class="plain-syntax"> *</span><span class="function-syntax">Architectures::new</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">Architectures::new</span></span>:<br/><a href="2-arc.html#SP3">&#167;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">code</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">s</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">d</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inter_architecture</span><span class="plain-syntax"> *</span><span class="identifier-syntax">A</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">inter_architecture</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">A</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">shorthand</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">code</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">A</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sixteen_bit</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">A</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">debug_enabled</span><span class="plain-syntax"> = </span><span class="identifier-syntax">d</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">A</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3"></a><b>&#167;3. Standard set. </b>This is called when the <a href="index.html" class="internal">arch</a> module starts up; no other architectures
are ever made.
</p>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Architectures::create</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">Architectures::create</span></span>:<br/>Arch Module - <a href="1-am.html#SP3">&#167;3</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-arc.html#SP1" class="function-link"><span class="function-syntax">Architectures::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"16"</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-arc.html#SP1" class="function-link"><span class="function-syntax">Architectures::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"16d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-arc.html#SP1" class="function-link"><span class="function-syntax">Architectures::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"32"</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-arc.html#SP1" class="function-link"><span class="function-syntax">Architectures::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"32d"</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>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Architectures::create</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Architectures::create</span></span>:<br/>Arch Module - <a href="1-am.html#SP3">&#167;3</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-arc.html#SP2" class="function-link"><span class="function-syntax">Architectures::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"16"</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-arc.html#SP2" class="function-link"><span class="function-syntax">Architectures::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"16d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-arc.html#SP2" class="function-link"><span class="function-syntax">Architectures::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"32"</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-arc.html#SP2" class="function-link"><span class="function-syntax">Architectures::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"32d"</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="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4"></a><b>&#167;4. Canonical filenames. </b>When a kit is assimilated, its Inter code is stored in files with these
leafnames:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="function-syntax">Architectures::canonical_binary</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="reserved-syntax">inter_architecture</span><span class="plain-syntax"> *</span><span class="identifier-syntax">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">A</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no arch"</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">leafname</span><span class="plain-syntax">);</span>
@ -110,32 +133,39 @@ function togglePopup(material_id) {
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">leafname</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">F</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5"></a><b>&#167;5. Shorthand. </b>These functions turn an architecture into a text like <span class="extract"><span class="extract-syntax">16d</span></span> and back again:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">Architectures::to_codename</span><span class="plain-syntax">(</span><span class="reserved-syntax">inter_architecture</span><span class="plain-syntax"> *</span><span class="identifier-syntax">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">A</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">A</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">shorthand</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">inter_architecture</span><span class="plain-syntax"> *</span><span class="function-syntax">Architectures::from_codename</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Architectures::from_codename</span></span>:<br/>Target Virtual Machines - <a href="2-tvm.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">inter_architecture</span><span class="plain-syntax"> *</span><span class="function-syntax">Architectures::from_codename</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">Architectures::from_codename</span></span>:<br/>Target Virtual Machines - <a href="2-tvm.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inter_architecture</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">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">A</span><span class="plain-syntax">, </span><span class="reserved-syntax">inter_architecture</span><span 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_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">A</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">shorthand</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</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">A</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6"></a><b>&#167;6. What an architecture offers. </b>At present, this all there is, so in a sense all possible architectures exist:
</p>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Architectures::is_16_bit</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">Architectures::is_16_bit</span></span>:<br/>Target Virtual Machines - <a href="2-tvm.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inter_architecture</span><span class="plain-syntax"> *</span><span class="identifier-syntax">A</span><span class="plain-syntax">) {</span>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Architectures::is_16_bit</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">Architectures::is_16_bit</span></span>:<br/>Target Virtual Machines - <a href="2-tvm.html#SP2">&#167;2</a>, <a href="2-tvm.html#SP7">&#167;7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inter_architecture</span><span class="plain-syntax"> *</span><span class="identifier-syntax">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">A</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no arch"</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">A</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sixteen_bit</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Architectures::debug_enabled</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">Architectures::debug_enabled</span></span>:<br/>Target Virtual Machines - <a href="2-tvm.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inter_architecture</span><span class="plain-syntax"> *</span><span class="identifier-syntax">A</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Architectures::debug_enabled</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">Architectures::debug_enabled</span></span>:<br/>Target Virtual Machines - <a href="2-tvm.html#SP7">&#167;7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inter_architecture</span><span class="plain-syntax"> *</span><span class="identifier-syntax">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">A</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no arch"</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">A</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">debug_enabled</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure inter_architecture is private to this section.</li></ul>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="1-am.html">&#10094;</a></li><li class="progresschapter"><a href="1-am.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresscurrent">arc</li><li class="progresssection"><a href="2-tvm.html">tvm</a></li><li class="progresssection"><a href="2-cmp.html">cmp</a></li><li class="progressnext"><a href="2-tvm.html">&#10095;</a></li></ul></div>
<ul class="progressbar"><li class="progressprev"><a href="1-am.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-am.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresscurrent">arc</li><li class="progresssection"><a href="2-tvm.html">tvm</a></li><li class="progresssection"><a href="2-cmp.html">cmp</a></li><li class="progressnext"><a href="2-tvm.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>

View file

@ -12,6 +12,14 @@
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
@ -55,34 +63,65 @@
<main role="main">
<!--Weave of 'Compatibility' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Shared Modules</a></li><li><a href="index.html">arch</a></li><li><a href="index.html#2">Chapter 2: Architectures</a></li><li><b>Compatibility</b></li></ul></div>
<p class="purpose">To manage compatibility lists: what can be compiled to what format.</p>
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Shared Modules</a></li><li><a href="index.html">arch</a></li><li><a href="index.html#2">Chapter 2: Architectures and VMs</a></li><li><b>Compatibility</b></li></ul></div>
<p class="purpose">To manage specifications of compatibility with some VMs but not others.</p>
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b></p>
<ul class="toc"><li><a href="2-cmp.html#SP1">&#167;1. Specifications</a></li><li><a href="2-cmp.html#SP5">&#167;5. Converting to text</a></li><li><a href="2-cmp.html#SP6">&#167;6. Converting from text</a></li><li><a href="2-cmp.html#SP11">&#167;11. Testing</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. Specifications. </b>An object of the following class can represent any subset of VMs, so
it's a fully general way to express which VMs some piece of software works with:
</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">compatibility_specification</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="identifier-syntax">parsed_from</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="identifier-syntax">parsed_from</span><span class="plain-syntax">; </span><span class="comment-syntax"> if it came from text</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">default_allows</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">exceptions</span><span class="plain-syntax">; </span><span class="comment-syntax"> of </span><span class="extract"><span class="extract-syntax">target_vm</span></span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">compatibility_specification</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure compatibility_specification is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP2"></a><b>&#167;2. </b>The creator function for this always begins with a specification meaning
"works with all VMs":
</p>
<span class="reserved-syntax">compatibility_specification</span><span class="plain-syntax"> *</span><span class="function-syntax">Compatibility::all</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">compatibility_specification</span><span class="plain-syntax"> *</span><span class="function-syntax">Compatibility::all</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">Compatibility::all</span></span>:<br/><a href="2-cmp.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">compatibility_specification</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">compatibility_specification</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parsed_from</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">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">default_allows</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">exceptions</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">target_vm</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">C</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3"></a><b>&#167;3. </b>We can then change this in two ways: one is to reverse the default...
</p>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Compatibility::universal</span><span class="plain-syntax">(</span><span class="reserved-syntax">compatibility_specification</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="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">LinkedLists::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">exceptions</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">default_allows</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Compatibility::reverse</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Compatibility::reverse</span></span>:<br/><a href="2-cmp.html#SP6">&#167;6</a>, <a href="2-cmp.html#SP6_2_1">&#167;6.2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">compatibility_specification</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">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">default_allows</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">default_allows</span><span class="plain-syntax">)?</span><span class="identifier-syntax">FALSE:TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4"></a><b>&#167;4. </b>...and the other is to add an exception:
</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">Compatibility::add_exception</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">Compatibility::add_exception</span></span>:<br/><a href="2-cmp.html#SP10_1">&#167;10.1</a>, <a href="2-cmp.html#SP10_2">&#167;10.2</a>, <a href="2-cmp.html#SP10_3">&#167;10.3</a>, <a href="2-cmp.html#SP10_5">&#167;10.5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">compatibility_specification</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">already_there</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">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">X</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">X</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">exceptions</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">VM</span><span class="plain-syntax"> == </span><span class="identifier-syntax">X</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">already_there</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">already_there</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">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">exceptions</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">already_there</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5"></a><b>&#167;5. Converting to text. </b>This often produces something verbose; the <span class="extract"><span class="extract-syntax">parsed_from</span></span> text probably reads
better, if available.
</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">Compatibility::write</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">compatibility_specification</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="identifier-syntax">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"for none"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">x</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LinkedLists::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">exceptions</span><span class="plain-syntax">);</span>
@ -98,18 +137,58 @@
<span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">n</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">n</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">x</span><span class="plain-syntax">)) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">n</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">n</span><span class="plain-syntax"> == </span><span class="identifier-syntax">x</span><span class="plain-syntax">)) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" or "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-tvm.html#SP1" class="function-link"><span class="function-syntax">TargetVMs::write</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-tvm.html#SP4" class="function-link"><span class="function-syntax">TargetVMs::write</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6"></a><b>&#167;6. Converting from text. </b>This is quite a tricky little parser, which has to read, for example,
text like "for Glulx only" used in Inform extension headings. A syntactically
invalid description returns <span class="extract"><span class="extract-syntax">NULL</span></span> but prints no error message; an empty
description returns the universally valid specification.
</p>
<p class="commentary">A question we might return to is whether an unrecognisable description &mdash;
say, "for Marzipan version 28.1 only" &mdash; should return a universally-false
specification rather than returning <span class="extract"><span class="extract-syntax">NULL</span></span>: this would enable current Inform
tools to work with future resources which use VMs currently unthought of.
But for now, it seems best to generate errors, because the more likely thing
is that an extension author is botching the wording of something, or
writing "Z machine" instead of "Z-machine", or something like that.
</p>
<p class="commentary">It might seem better to all of this with a Preform grammar, rather than by
hand. But we want to make it work in tools which don't have Preform available,
and we want it to run quickly.
</p>
<p class="commentary">Unless the text is empty, we start with the "works with nothing" specification
and then add each VM with which <span class="extract"><span class="extract-syntax">C</span></span> does work as an exception.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">compatibility_specification</span><span class="plain-syntax"> *</span><span class="function-syntax">Compatibility::from_text</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="plain-syntax"> </span><span class="reserved-syntax">compatibility_specification</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax"> = </span><a href="2-cmp.html#SP1" class="function-link"><span class="function-syntax">Compatibility::all</span></a><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">incorrect</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">compatibility_specification</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax"> = </span><a href="2-cmp.html#SP2" class="function-link"><span class="function-syntax">Compatibility::all</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parsed_from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">C</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="2-cmp.html#SP3" class="function-link"><span class="function-syntax">Compatibility::reverse</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">); </span><span class="comment-syntax"> now </span><span class="extract"><span class="extract-syntax">C</span></span><span class="comment-syntax"> works with nothing</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">error_in_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Regexp::create_mr</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">parse</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">parse</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parsed_from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-cmp.html#SP6_1" class="named-paragraph-link"><span class="named-paragraph">Remove excess space and/or enclosing brackets and lower in case</span><span class="named-paragraph-number">6.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-cmp.html#SP6_2" class="named-paragraph-link"><span class="named-paragraph">Actually parse the description</span><span class="named-paragraph-number">6.2</span></a></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">parse</span><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>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><span class="identifier-syntax">error_in_syntax</span><span class="plain-syntax">)?</span><span class="identifier-syntax">NULL:C</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6_1"></a><b>&#167;6.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Remove excess space and/or enclosing brackets and lower in case</span><span class="named-paragraph-number">6.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::trim_white_space</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse</span><span 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">parse</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">parse</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_first_character</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse</span><span class="plain-syntax">);</span>
@ -118,46 +197,70 @@
<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">parse</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::put</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">Characters::tolower</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>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-cmp.html#SP6">&#167;6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6_2"></a><b>&#167;6.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Actually parse the description</span><span class="named-paragraph-number">6.2</span></span><span class="comment-syntax"> =</span>
</p>
<span class="plain-syntax"> </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">default_allows</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">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Regexp::create_mr</span><span class="plain-syntax">();</span>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">negated</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-cmp.html#SP6_2_1" class="named-paragraph-link"><span class="named-paragraph">Parse out the prefix not</span><span class="named-paragraph-number">6.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-cmp.html#SP6_2_2" class="named-paragraph-link"><span class="named-paragraph">Remove the meaningless word for</span><span class="named-paragraph-number">6.2.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-cmp.html#SP6_2_3" class="named-paragraph-link"><span class="named-paragraph">Parse out the suffix only</span><span class="named-paragraph-number">6.2.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">negated</span><span class="plain-syntax">) </span><span class="identifier-syntax">error_in_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="comment-syntax"> "not for all"</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">default_allows</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"none"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">negated</span><span class="plain-syntax">) </span><span class="identifier-syntax">error_in_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="comment-syntax"> "not for none"</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">default_allows</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-cmp.html#SP8" class="function-link"><span class="function-syntax">Compatibility::parse_specifics</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse</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">error_in_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-cmp.html#SP6">&#167;6</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6_2_1"></a><b>&#167;6.2.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse out the prefix not</span><span class="named-paragraph-number">6.2.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Regexp::match</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"not (%c+)"</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">parse</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">parse</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::trim_white_space</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">default_allows</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="2-cmp.html#SP3" class="function-link"><span class="function-syntax">Compatibility::reverse</span></a><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">negated</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-cmp.html#SP6_2">&#167;6.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6_2_2"></a><b>&#167;6.2.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Remove the meaningless word for</span><span class="named-paragraph-number">6.2.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Regexp::match</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"for (%c+)"</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">parse</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">parse</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::trim_white_space</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-cmp.html#SP6_2">&#167;6.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP6_2_3"></a><b>&#167;6.2.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse out the suffix only</span><span class="named-paragraph-number">6.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="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Regexp::match</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"(%c+) only"</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">parse</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">parse</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::trim_white_space</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">negated</span><span class="plain-syntax">) </span><span class="identifier-syntax">incorrect</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="comment-syntax"> "not for 32d only"</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">negated</span><span class="plain-syntax">) </span><span class="identifier-syntax">error_in_syntax</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="comment-syntax"> "not for 32d only"</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-cmp.html#SP6_2">&#167;6.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP7"></a><b>&#167;7. </b>The above gets us down from, say, "for Glulx only" to just "Glulx", and
calls the function <a href="2-cmp.html#SP8" class="internal">Compatibility::parse_specifics</a> to handle that specific part &mdash;
though it may be more complicated. See the <a href="../arch-test/index.html" class="internal">arch-test</a> unit test for
examples. While parsing those specifics we maintain a state in the following
structure:
</p>
<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">parse</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">negated</span><span class="plain-syntax">) </span><span class="identifier-syntax">incorrect</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="comment-syntax"> "not for all"</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">default_allows</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"none"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">negated</span><span class="plain-syntax">) </span><span class="identifier-syntax">incorrect</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="comment-syntax"> "not for none"</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">default_allows</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-cmp.html#SP1" class="function-link"><span class="function-syntax">Compatibility::clause</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">parse</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">incorrect</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">parse</span><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>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">incorrect</span><span class="plain-syntax">) </span><span class="identifier-syntax">C</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">C</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<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">compat_parser_state</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">compatibility_specification</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">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">current_family</span><span class="plain-syntax">;</span>
@ -166,14 +269,45 @@
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">family_used</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">compat_parser_state</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Compatibility::clause</span><span class="plain-syntax">(</span><span class="reserved-syntax">compatibility_specification</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</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="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">correct</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Regexp::create_mr</span><span class="plain-syntax">();</span>
<span class="reserved-syntax">compat_parser_state</span><span class="plain-syntax"> </span><span class="function-syntax">Compatibility::initial_state</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">Compatibility::initial_state</span></span>:<br/><a href="2-cmp.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">compatibility_specification</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">compat_parser_state</span><span class="plain-syntax"> </span><span class="identifier-syntax">cps</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cps</span><span class="plain-syntax">.</span><span class="element-syntax">C</span><span class="plain-syntax"> = </span><span class="identifier-syntax">C</span><span class="plain-syntax">; </span><span class="identifier-syntax">cps</span><span class="plain-syntax">.</span><span class="element-syntax">version_allowed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="identifier-syntax">cps</span><span class="plain-syntax">.</span><span class="element-syntax">version_required</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">cps</span><span class="plain-syntax">.</span><span class="element-syntax">current_family</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">cps</span><span class="plain-syntax">.</span><span class="element-syntax">family_used</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">cps</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure compat_parser_state is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP8"></a><b>&#167;8. </b>So here's the specific details parser, then. We return <span class="extract"><span class="extract-syntax">TRUE</span></span> if no syntax
errors occurred, and we change <span class="extract"><span class="extract-syntax">C</span></span> according to what <span class="extract"><span class="extract-syntax">text</span></span> says.
</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">Compatibility::parse_specifics</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">Compatibility::parse_specifics</span></span>:<br/><a href="2-cmp.html#SP6_2">&#167;6.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">compatibility_specification</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</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="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">okay</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Regexp::create_mr</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">compat_parser_state</span><span class="plain-syntax"> </span><span class="identifier-syntax">cps</span><span class="plain-syntax"> = </span><a href="2-cmp.html#SP7" class="function-link"><span class="function-syntax">Compatibility::initial_state</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-cmp.html#SP8_1" class="named-paragraph-link"><span class="named-paragraph">Reduce the text to a sequence of tokens</span><span class="named-paragraph-number">8.1</span></a></span><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>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">okay</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_1"></a><b>&#167;8.1. </b>This is essentially simple &mdash; it splits up text like "Z-machine versions 5 or 8"
into tokens, sending them one at a time to <a href="2-cmp.html#SP10" class="internal">Compatibility::parse_token</a>.
Note that commas are converted to the token <span class="extract"><span class="extract-syntax">or</span></span>: e.g., "Z-machine versions 5, 6
or 8" would be treated as "Z-machine versions 5 or 6 or 8"; and note also that
"with debugging" and "without debugging" are handled specially.
</p>
<p class="commentary">We end the sequence of tokens with a <span class="extract"><span class="extract-syntax">NULL</span></span>, telling the token-parser that
it has reached the end.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Reduce the text to a sequence of tokens</span><span class="named-paragraph-number">8.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Regexp::match</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"(%C+) (%c+)"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">comma</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::get_last_char</span><span class="plain-syntax">(</span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[0]) == </span><span class="character-syntax">','</span><span class="plain-syntax">) {</span>
@ -181,63 +315,62 @@
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::delete_last_character</span><span class="plain-syntax">(</span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::trim_white_space</span><span class="plain-syntax">(</span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">with</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Regexp::create_mr</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Regexp::match</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr2</span><span class="plain-syntax">, </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[1], </span><span class="identifier-syntax">L</span><span class="string-syntax">"with debugging,* *(%c*)"</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">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[1]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::copy</span><span class="plain-syntax">(</span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[1], </span><span class="identifier-syntax">mr2</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">with</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Regexp::match</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr2</span><span class="plain-syntax">, </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[1], </span><span class="identifier-syntax">L</span><span class="string-syntax">"without debugging,* *(%c*)"</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">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[1]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::copy</span><span class="plain-syntax">(</span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[1], </span><span class="identifier-syntax">mr2</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">with</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Regexp::dispose_of</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">correct</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">correct</span><span class="plain-syntax"> &amp;&amp; </span><a href="2-cmp.html#SP1" class="function-link"><span class="function-syntax">Compatibility::word</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">cps</span><span class="plain-syntax">, </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[0], </span><span class="identifier-syntax">with</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">comma</span><span class="plain-syntax">) </span><span class="identifier-syntax">correct</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">correct</span><span class="plain-syntax"> &amp;&amp; </span><a href="2-cmp.html#SP1" class="function-link"><span class="function-syntax">Compatibility::word</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">cps</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"or"</span><span class="plain-syntax">, </span><span class="identifier-syntax">with</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">with</span><span class="plain-syntax"> = </span><a href="2-cmp.html#SP9" class="function-link"><span class="function-syntax">Compatibility::parse_debugging</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[1]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">okay</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">okay</span><span class="plain-syntax"> &amp;&amp; </span><a href="2-cmp.html#SP10" class="function-link"><span class="function-syntax">Compatibility::parse_token</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">cps</span><span class="plain-syntax">, </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[0], </span><span class="identifier-syntax">with</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">comma</span><span class="plain-syntax">) </span><span class="identifier-syntax">okay</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">okay</span><span class="plain-syntax"> &amp;&amp; </span><a href="2-cmp.html#SP10" class="function-link"><span class="function-syntax">Compatibility::parse_token</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">cps</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"or"</span><span class="plain-syntax">, </span><span class="identifier-syntax">with</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">text</span><span class="plain-syntax">); </span><span class="identifier-syntax">Str::copy</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[1]);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">text</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">correct</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">correct</span><span class="plain-syntax"> &amp;&amp; </span><a href="2-cmp.html#SP1" class="function-link"><span class="function-syntax">Compatibility::word</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">cps</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">correct</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">cps</span><span class="plain-syntax">.</span><span class="element-syntax">family_used</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">cps</span><span class="plain-syntax">.</span><span class="element-syntax">current_family</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="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span 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_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">cps</span><span class="plain-syntax">.</span><span class="element-syntax">current_family</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family_name</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="2-cmp.html#SP1" class="function-link"><span class="function-syntax">Compatibility::add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">okay</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">okay</span><span class="plain-syntax"> &amp;&amp; </span><a href="2-cmp.html#SP10" class="function-link"><span class="function-syntax">Compatibility::parse_token</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">cps</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">okay</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">okay</span><span class="plain-syntax"> &amp;&amp; </span><a href="2-cmp.html#SP10" class="function-link"><span class="function-syntax">Compatibility::parse_token</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">cps</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">));</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-cmp.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9"></a><b>&#167;9. </b>Returns <span class="extract"><span class="extract-syntax">TRUE</span></span> if the text <span class="extract"><span class="extract-syntax">T</span></span> begins "with debugging", and trims that text
away from <span class="extract"><span class="extract-syntax">T</span></span>; returns <span class="extract"><span class="extract-syntax">FALSE</span></span> if it begins "without debugging", and similarly
trims; and otherwise returns <span class="extract"><span class="extract-syntax">NOT_APPLICABLE</span></span> and leaves <span class="extract"><span class="extract-syntax">T</span></span> unaltered.
</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">Compatibility::parse_debugging</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">Compatibility::parse_debugging</span></span>:<br/><a href="2-cmp.html#SP8_1">&#167;8.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">with</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Regexp::create_mr</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Regexp::match</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"with debugging,* *(%c*)"</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">T</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">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">with</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Regexp::match</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"without debugging,* *(%c*)"</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">T</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">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[0]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">with</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Regexp::dispose_of</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</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">correct</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">with</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10"></a><b>&#167;10. </b>Once again we return <span class="extract"><span class="extract-syntax">TRUE</span></span> if no syntax errors occurred, and we change <span class="extract"><span class="extract-syntax">C</span></span>
according to what the <span class="extract"><span class="extract-syntax">token</span></span> says.
</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">Compatibility::parse_token</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">Compatibility::parse_token</span></span>:<br/><a href="2-cmp.html#SP8_1">&#167;8.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">compat_parser_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cps</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">token</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">with</span><span 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">token</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-cmp.html#SP10_5" class="named-paragraph-link"><span class="named-paragraph">Construe the token as the end-marker</span><span class="named-paragraph-number">10.5</span></a></span><span class="plain-syntax">;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Compatibility::word</span><span class="plain-syntax">(</span><span class="reserved-syntax">compat_parser_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cps</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">word</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">with</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">version_allowed</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax"> = </span><span class="identifier-syntax">VersionNumbers::from_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">word</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax"> = </span><span class="identifier-syntax">VersionNumbers::from_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">token</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">VersionNumbers::is_null</span><span class="plain-syntax">(</span><span class="identifier-syntax">V</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">version_required</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">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">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_family</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family_used</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">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</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">seen</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">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span 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_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_family</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">seen</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">VersionNumbers::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">version</span><span class="plain-syntax">, </span><span class="identifier-syntax">V</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">with</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">) || (</span><a href="2-tvm.html#SP1" class="function-link"><span class="function-syntax">TargetVMs::debug_enabled</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">) == </span><span class="identifier-syntax">with</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><a href="2-cmp.html#SP1" class="function-link"><span class="function-syntax">Compatibility::add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">version_required</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">seen</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-cmp.html#SP10_1" class="named-paragraph-link"><span class="named-paragraph">Construe token as a version number</span><span class="named-paragraph-number">10.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">word</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"or"</span><span 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_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">token</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"or"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">with</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Str::eq_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">word</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"version"</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">word</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"versions"</span><span 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_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">token</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"version"</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">token</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"versions"</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">with</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">version_required</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">version_allowed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
@ -248,54 +381,94 @@
<span class="plain-syntax"> </span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">version_allowed</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bits</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">word</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"16-bit"</span><span class="plain-syntax">)) </span><span class="identifier-syntax">bits</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">word</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"32-bit"</span><span class="plain-syntax">)) </span><span class="identifier-syntax">bits</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bits</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-tvm.html#SP1" class="function-link"><span class="function-syntax">TargetVMs::is_16_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">) == </span><span class="identifier-syntax">bits</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">with</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">) || (</span><a href="2-tvm.html#SP1" class="function-link"><span class="function-syntax">TargetVMs::debug_enabled</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">) == </span><span class="identifier-syntax">with</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="2-cmp.html#SP1" class="function-link"><span class="function-syntax">Compatibility::add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_family</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">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family_used</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">token</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"16-bit"</span><span class="plain-syntax">)) </span><span class="identifier-syntax">bits</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">token</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"32-bit"</span><span class="plain-syntax">)) </span><span class="identifier-syntax">bits</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bits</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-cmp.html#SP10_2" class="named-paragraph-link"><span class="named-paragraph">Construe token as a bit count</span><span class="named-paragraph-number">10.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">with</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">seen</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">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span 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_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">word</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">seen</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-tvm.html#SP1" class="function-link"><span class="function-syntax">TargetVMs::debug_enabled</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">) == </span><span class="identifier-syntax">with</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="2-cmp.html#SP1" class="function-link"><span class="function-syntax">Compatibility::add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_family</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">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family_used</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">seen</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">with</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-cmp.html#SP10_3" class="named-paragraph-link"><span class="named-paragraph">Construe token as a family name subject to debugging</span><span class="named-paragraph-number">10.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-cmp.html#SP10_4" class="named-paragraph-link"><span class="named-paragraph">Construe token as a family name</span><span class="named-paragraph-number">10.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10_1"></a><b>&#167;10.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Construe token as a version number</span><span class="named-paragraph-number">10.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family_used</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">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</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">seen</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">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span 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_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_family</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">seen</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">VersionNumbers::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">version</span><span class="plain-syntax">, </span><span class="identifier-syntax">V</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">with</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">) || (</span><a href="2-tvm.html#SP7" class="function-link"><span class="function-syntax">TargetVMs::debug_enabled</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">) == </span><span class="identifier-syntax">with</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><a href="2-cmp.html#SP4" class="function-link"><span class="function-syntax">Compatibility::add_exception</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">version_required</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">seen</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-cmp.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_2"></a><b>&#167;10.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Construe token as a bit count</span><span class="named-paragraph-number">10.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span 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_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">word</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-tvm.html#SP7" class="function-link"><span class="function-syntax">TargetVMs::is_16_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">) == </span><span class="identifier-syntax">bits</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">with</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NOT_APPLICABLE</span><span class="plain-syntax">) || (</span><a href="2-tvm.html#SP7" class="function-link"><span class="function-syntax">TargetVMs::debug_enabled</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">) == </span><span class="identifier-syntax">with</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="2-cmp.html#SP4" class="function-link"><span class="function-syntax">Compatibility::add_exception</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_family</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">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family_used</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-cmp.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_3"></a><b>&#167;10.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Construe token as a family name subject to debugging</span><span class="named-paragraph-number">10.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">seen</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">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span 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_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">token</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">seen</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-tvm.html#SP7" class="function-link"><span class="function-syntax">TargetVMs::debug_enabled</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">) == </span><span class="identifier-syntax">with</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="2-cmp.html#SP4" class="function-link"><span class="function-syntax">Compatibility::add_exception</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_family</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">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family_used</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">seen</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-cmp.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_4"></a><b>&#167;10.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Construe token as a family name</span><span class="named-paragraph-number">10.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span 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_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">token</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_family</span><span class="plain-syntax"> = </span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family_name</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-cmp.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP10_5"></a><b>&#167;10.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Construe the token as the end-marker</span><span class="named-paragraph-number">10.5</span></span><span class="comment-syntax"> =</span>
</p>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Compatibility::add</span><span class="plain-syntax">(</span><span class="reserved-syntax">compatibility_specification</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">already_there</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">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">X</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">X</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">exceptions</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">VM</span><span class="plain-syntax"> == </span><span class="identifier-syntax">X</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">already_there</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">already_there</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">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">exceptions</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">already_there</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<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">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family_used</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_family</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="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span 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_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_family</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family_name</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="2-cmp.html#SP4" class="function-link"><span class="function-syntax">Compatibility::add_exception</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cps</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-cmp.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP11"></a><b>&#167;11. Testing. </b></p>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Compatibility::with</span><span class="plain-syntax">(</span><span class="reserved-syntax">compatibility_specification</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">) {</span>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Compatibility::test</span><span class="plain-syntax">(</span><span class="reserved-syntax">compatibility_specification</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span 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="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">decision</span><span class="plain-syntax"> = </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">default_allows</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">X</span><span class="plain-syntax">;</span>
@ -304,10 +477,16 @@
<span class="plain-syntax"> </span><span class="identifier-syntax">decision</span><span class="plain-syntax"> = </span><span class="identifier-syntax">decision</span><span class="plain-syntax">?</span><span class="identifier-syntax">FALSE:TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">decision</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Compatibility::test_universal</span><span class="plain-syntax">(</span><span class="reserved-syntax">compatibility_specification</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="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">LinkedLists::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">exceptions</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">default_allows</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure compatibility_specification is private to this section.</li><li>The structure compat_parser_state is private to this section.</li></ul>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="2-tvm.html">&#10094;</a></li><li class="progresschapter"><a href="1-am.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresssection"><a href="2-arc.html">arc</a></li><li class="progresssection"><a href="2-tvm.html">tvm</a></li><li class="progresscurrent">cmp</li><li class="progressnextoff">&#10095;</li></ul></div>
<ul class="progressbar"><li class="progressprev"><a href="2-tvm.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-am.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresssection"><a href="2-arc.html">arc</a></li><li class="progresssection"><a href="2-tvm.html">tvm</a></li><li class="progresscurrent">cmp</li><li class="progressnextoff">&#10095;</li></ul></div>
</nav><!--End of weave-->
</main>

View file

@ -63,12 +63,24 @@ function togglePopup(material_id) {
<main role="main">
<!--Weave of 'Target Virtual Machines' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Shared Modules</a></li><li><a href="index.html">arch</a></li><li><a href="index.html#2">Chapter 2: Architectures</a></li><li><b>Target Virtual Machines</b></li></ul></div>
<p class="purpose">To deal with multiple inter architectures.</p>
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Shared Modules</a></li><li><a href="index.html">arch</a></li><li><a href="index.html#2">Chapter 2: Architectures and VMs</a></li><li><b>Target Virtual Machines</b></li></ul></div>
<p class="purpose">To deal with multiple object code formats.</p>
<ul class="toc"><li><a href="2-tvm.html#SP1">&#167;1. Architectures</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="2-tvm.html#SP1">&#167;1. Object code</a></li><li><a href="2-tvm.html#SP3">&#167;3. Standard set</a></li><li><a href="2-tvm.html#SP4">&#167;4. Describing and finding</a></li><li><a href="2-tvm.html#SP7">&#167;7. Miscellaneous provisions</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. Architectures. </b></p>
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. Object code. </b>The end result of compilation is traditionally called "object code" and
people tend to use words like "binary" or even "machine code" about it,
though in fact the world is more diverse nowadays. Inform 7 has always
generated "object code" which is itself a program for a virtual machine;
for example, it makes Glulx bytecode rather than x86 or ARM instructions.
Because of that, we use the customary term "virtual machine" for the format
of the end product of the Inform build process. But it doesn't have to be
virtual. If Inter-to-x86-via-C is properly implemented, we will probably
want to add a VM to represent something like "32-bit binary via ANSI C".
</p>
<p class="commentary">Each different target VM is represented by one of these objects:
</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">target_vm</span><span class="plain-syntax"> {</span>
@ -86,8 +98,12 @@ function togglePopup(material_id) {
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">supports_floating_point</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure target_vm is accessed in 2/cmp and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2"></a><b>&#167;2. </b></p>
<span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="function-syntax">TargetVMs::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">code</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nick</span><span class="plain-syntax">, </span><span class="identifier-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax">,</span>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="function-syntax">TargetVMs::new</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">TargetVMs::new</span></span>:<br/><a href="2-tvm.html#SP3">&#167;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">code</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">nick</span><span class="plain-syntax">, </span><span class="identifier-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V</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">image</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">interpreter</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">blorbed</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">arch</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">debug</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">max_locals</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">iFiction</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">target_vm</span><span class="plain-syntax">);</span>
@ -99,16 +115,44 @@ function togglePopup(material_id) {
<span class="plain-syntax"> </span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">VM_image</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">image</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">max_locals</span><span class="plain-syntax"> = </span><span class="identifier-syntax">max_locals</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">default_browser_interpreter</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">interpreter</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">architecture</span><span class="plain-syntax"> = </span><a href="2-arc.html#SP1" class="function-link"><span class="function-syntax">Architectures::from_codename</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">arch</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">architecture</span><span class="plain-syntax"> = </span><a href="2-arc.html#SP5" class="function-link"><span class="function-syntax">Architectures::from_codename</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">arch</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">architecture</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no such architecture"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">with_debugging_enabled</span><span class="plain-syntax"> = </span><span class="identifier-syntax">debug</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">supports_floating_point</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-arc.html#SP1" class="function-link"><span class="function-syntax">Architectures::is_16_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">architecture</span><span class="plain-syntax">)) </span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">supports_floating_point</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-arc.html#SP6" class="function-link"><span class="function-syntax">Architectures::is_16_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">architecture</span><span class="plain-syntax">)) </span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">supports_floating_point</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">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">iFiction_format_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">iFiction</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">VM</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3"></a><b>&#167;3. Standard set. </b>This is called when the <a href="index.html" class="internal">arch</a> module starts up; no other architectures
are ever made.
</p>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">TargetVMs::write</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">TargetVMs::write</span></span>:<br/>Compatibility - <a href="2-cmp.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">) {</span>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">TargetVMs::create</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">TargetVMs::create</span></span>:<br/>Arch Module - <a href="1-am.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> hat tip: Joel Berez and Marc Blank, 1979, and later hands</span>
<span class="plain-syntax"> </span><a href="2-tvm.html#SP2" class="function-link"><span class="function-syntax">TargetVMs::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Z-Machine"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"z5"</span><span class="plain-syntax">, </span><span class="identifier-syntax">VersionNumbers::from_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"5"</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="string-syntax">"vm_z5.png"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Parchment"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"zblorb"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"16"</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="constant-syntax">15</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"zcode"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-tvm.html#SP2" class="function-link"><span class="function-syntax">TargetVMs::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Z-Machine"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"z5"</span><span class="plain-syntax">, </span><span class="identifier-syntax">VersionNumbers::from_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"5"</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="string-syntax">"vm_z5.png"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Parchment"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"zblorb"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"16d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="constant-syntax">15</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"zcode"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-tvm.html#SP2" class="function-link"><span class="function-syntax">TargetVMs::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Z-Machine"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"z8"</span><span class="plain-syntax">, </span><span class="identifier-syntax">VersionNumbers::from_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"8"</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="string-syntax">"vm_z8.png"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Parchment"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"zblorb"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"16"</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="constant-syntax">15</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"zcode"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-tvm.html#SP2" class="function-link"><span class="function-syntax">TargetVMs::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Z-Machine"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"z8"</span><span class="plain-syntax">, </span><span class="identifier-syntax">VersionNumbers::from_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"8"</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="string-syntax">"vm_z8.png"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Parchment"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"zblorb"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"16d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="constant-syntax">15</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"zcode"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> hat tip: Andrew Plotkin, 2000</span>
<span class="plain-syntax"> </span><a href="2-tvm.html#SP2" class="function-link"><span class="function-syntax">TargetVMs::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Glulx"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"ulx"</span><span class="plain-syntax">, </span><span class="identifier-syntax">VersionNumbers::from_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"3.1.2"</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="string-syntax">"vm_glulx.png"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Quixe"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"gblorb"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"32"</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="constant-syntax">256</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"glulx"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-tvm.html#SP2" class="function-link"><span class="function-syntax">TargetVMs::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Glulx"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"ulx"</span><span class="plain-syntax">, </span><span class="identifier-syntax">VersionNumbers::from_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"3.1.2"</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="string-syntax">"vm_glulx.png"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Quixe"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"gblorb"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"32d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="constant-syntax">256</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"glulx"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4"></a><b>&#167;4. Describing and finding. </b>This is the longhand form of the VM name:
</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">TargetVMs::write</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">TargetVMs::write</span></span>:<br/>Compatibility - <a href="2-cmp.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">VM</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"none"</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">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family_name</span><span class="plain-syntax">);</span>
@ -117,32 +161,20 @@ function togglePopup(material_id) {
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">with_debugging_enabled</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" with debugging"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5"></a><b>&#167;5. </b>Here we deduce a VM from the given filename extension, which is the rather
clumsy way that VMs are referred to on the <a href="../inform7/index.html" class="internal">inform7</a> command line. For
example, <span class="extract"><span class="extract-syntax">ulx</span></span> produces one of the Glulx VMs.
</p>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">TargetVMs::create</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">TargetVMs::create</span></span>:<br/>Arch Module - <a href="1-am.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> hat tip: Joel Berez and Marc Blank, 1979, and later hands</span>
<span class="plain-syntax"> </span><a href="2-tvm.html#SP1" class="function-link"><span class="function-syntax">TargetVMs::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Z-Machine"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"z5"</span><span class="plain-syntax">, </span><span class="identifier-syntax">VersionNumbers::from_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"5"</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="string-syntax">"vm_z5.png"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Parchment"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"zblorb"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"16"</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="constant-syntax">15</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"zcode"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-tvm.html#SP1" class="function-link"><span class="function-syntax">TargetVMs::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Z-Machine"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"z5"</span><span class="plain-syntax">, </span><span class="identifier-syntax">VersionNumbers::from_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"5"</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="string-syntax">"vm_z5.png"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Parchment"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"zblorb"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"16d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="constant-syntax">15</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"zcode"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-tvm.html#SP1" class="function-link"><span class="function-syntax">TargetVMs::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Z-Machine"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"z8"</span><span class="plain-syntax">, </span><span class="identifier-syntax">VersionNumbers::from_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"8"</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="string-syntax">"vm_z8.png"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Parchment"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"zblorb"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"16"</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="constant-syntax">15</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"zcode"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-tvm.html#SP1" class="function-link"><span class="function-syntax">TargetVMs::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Z-Machine"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"z8"</span><span class="plain-syntax">, </span><span class="identifier-syntax">VersionNumbers::from_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"8"</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="string-syntax">"vm_z8.png"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Parchment"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"zblorb"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"16d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="constant-syntax">15</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"zcode"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> hat tip: Andrew Plotkin, 2000</span>
<span class="plain-syntax"> </span><a href="2-tvm.html#SP1" class="function-link"><span class="function-syntax">TargetVMs::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Glulx"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"ulx"</span><span class="plain-syntax">, </span><span class="identifier-syntax">VersionNumbers::from_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"3.1.2"</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="string-syntax">"vm_glulx.png"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Quixe"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"gblorb"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"32"</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="constant-syntax">256</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"glulx"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-tvm.html#SP1" class="function-link"><span class="function-syntax">TargetVMs::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"Glulx"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"ulx"</span><span class="plain-syntax">, </span><span class="identifier-syntax">VersionNumbers::from_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"3.1.2"</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="string-syntax">"vm_glulx.png"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Quixe"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"gblorb"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"32d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="constant-syntax">256</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"glulx"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="function-syntax">TargetVMs::find</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ext</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">debug</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">result</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">ext</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">ext</span><span class="plain-syntax"> = </span><span class="identifier-syntax">I</span><span class="string-syntax">"ulx"</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">file_extension</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">file_extension</span><span class="plain-syntax">, </span><span class="identifier-syntax">ext</span><span 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">file_extension</span><span class="plain-syntax">) == </span><span class="character-syntax">'.'</span><span class="plain-syntax">) </span><span class="identifier-syntax">Str::delete_first_character</span><span class="plain-syntax">(</span><span class="identifier-syntax">file_extension</span><span 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">file_extension</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_first_character</span><span class="plain-syntax">(</span><span class="identifier-syntax">file_extension</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">file_extension</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::put</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">Characters::tolower</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">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">;</span>
@ -153,8 +185,16 @@ function togglePopup(material_id) {
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">file_extension</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6"></a><b>&#167;6. </b>A somewhat sharper method finds specific versions: for example, it can pick
out version 5 rather than version 8 of the Z-machine. Note that the version
numbers must match exactly, and not simply be compatible according to semver
rules.
</p>
<span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="function-syntax">TargetVMs::find_in_family</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">family</span><span class="plain-syntax">, </span><span class="identifier-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">debug</span><span class="plain-syntax">) {</span>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="function-syntax">TargetVMs::find_in_family</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">family</span><span class="plain-syntax">, </span><span class="identifier-syntax">semantic_version_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">V</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">debug</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span 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_insensitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">family</span><span class="plain-syntax">)) &amp;&amp;</span>
@ -163,23 +203,26 @@ function togglePopup(material_id) {
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">VM</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">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7"></a><b>&#167;7. Miscellaneous provisions. </b></p>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">TargetVMs::is_16_bit</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">TargetVMs::is_16_bit</span></span>:<br/>Compatibility - <a href="2-cmp.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">) {</span>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">TargetVMs::is_16_bit</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">TargetVMs::is_16_bit</span></span>:<br/>Compatibility - <a href="2-cmp.html#SP10_2">&#167;10.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">VM</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no VM"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-arc.html#SP1" class="function-link"><span class="function-syntax">Architectures::is_16_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">architecture</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-arc.html#SP6" class="function-link"><span class="function-syntax">Architectures::is_16_bit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">architecture</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">TargetVMs::debug_enabled</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">TargetVMs::debug_enabled</span></span>:<br/>Compatibility - <a href="2-cmp.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">TargetVMs::debug_enabled</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">TargetVMs::debug_enabled</span></span>:<br/>Compatibility - <a href="2-cmp.html#SP10_1">&#167;10.1</a>, <a href="2-cmp.html#SP10_2">&#167;10.2</a>, <a href="2-cmp.html#SP10_3">&#167;10.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">VM</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no VM"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-arc.html#SP1" class="function-link"><span class="function-syntax">Architectures::debug_enabled</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">architecture</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-arc.html#SP6" class="function-link"><span class="function-syntax">Architectures::debug_enabled</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">architecture</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">TargetVMs::supports_floating_point</span><span class="plain-syntax">(</span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">VM</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no VM"</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">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">supports_floating_point</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure target_vm is accessed in 2/cmp and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2"></a><b>&#167;2. </b>The limits are different on each platform. On Z, the maximum is fixed
at 15, but Glulx allows it to be set with an I6 memory setting.
<p class="commentary firstcommentary"><a id="SP8"></a><b>&#167;8. </b>The limits on local variables per routine are different on each platform.
On Z, the maximum is fixed at 15, but Glulx allows it to be set with an I6
memory setting.
</p>
<pre class="displayed-code all-displayed-code code-font">
@ -194,10 +237,10 @@ at 15, but Glulx allows it to be set with an I6 memory setting.
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3"></a><b>&#167;3. </b>When releasing a blorbed story file, the file extension depends on the
<p class="commentary firstcommentary"><a id="SP9"></a><b>&#167;9. </b>When releasing a blorbed story file, the file extension depends on the
story file wrapped inside. (This is a dubious idea, in the opinion of
the author of Inform &mdash; should not blorb be one unified wrapper? &mdash; but
interpreter writers disagree.)
the author of Inform &mdash; should not "blorb" be one unified wrapper? &mdash; but
that ship seems to have sailed.)
</p>
<pre class="displayed-code all-displayed-code code-font">
@ -210,7 +253,13 @@ interpreter writers disagree.)
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">VM</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no VM"</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">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">VM_blorbed_extension</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10"></a><b>&#167;10. </b>This is the format name as expressed in an iFiction bibliographic record,
where it's not meaningful to talk about debugging features or the number
of bits, and where it's currently not possible to express a VM version number.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">TargetVMs::get_iFiction_format</span><span class="plain-syntax">(</span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">VM</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no VM"</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">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">iFiction_format_name</span><span class="plain-syntax">;</span>
@ -221,9 +270,9 @@ interpreter writers disagree.)
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">VM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">architecture</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4"></a><b>&#167;4. </b>Different VMs have different in-browser interpreters, which means that
<p class="commentary firstcommentary"><a id="SP11"></a><b>&#167;11. </b>Different VMs have different in-browser interpreters, which means that
Inblorb needs to be given different release instructions for them. If the
user doesn't specify any particular interpreter, he gets:
user doesn't specify any particular interpreter, she gets:
</p>
<pre class="displayed-code all-displayed-code code-font">
@ -233,7 +282,7 @@ user doesn't specify any particular interpreter, he gets:
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="2-arc.html">&#10094;</a></li><li class="progresschapter"><a href="1-am.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresssection"><a href="2-arc.html">arc</a></li><li class="progresscurrent">tvm</li><li class="progresssection"><a href="2-cmp.html">cmp</a></li><li class="progressnext"><a href="2-cmp.html">&#10095;</a></li></ul></div>
<ul class="progressbar"><li class="progressprev"><a href="2-arc.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-am.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresssection"><a href="2-arc.html">arc</a></li><li class="progresscurrent">tvm</li><li class="progresssection"><a href="2-cmp.html">cmp</a></li><li class="progressnext"><a href="2-cmp.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>

View file

@ -0,0 +1,148 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>What This Module Does</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Inform.png" height=72">
</a></h1>
<ul><li><a href="../compiler.html">compiler tools</a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul><h2>Compiler Webs</h2><ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
</ul><h2>Inbuild Modules</h2><ul>
<li><a href="../supervisor-module/index.html">supervisor</a></li>
</ul><h2>Inform7 Modules</h2><ul>
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../index-module/index.html">index</a></li>
</ul><h2>Inter Modules</h2><ul>
<li><a href="../bytecode-module/index.html">bytecode</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul><h2>Shared Modules</h2><ul>
<li><a href="index.html"><span class="selectedlink">arch</span></a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../html-module/index.html">html</a></li>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'What This Module Does' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Shared Modules</a></li><li><a href="index.html">arch</a></li><li><a href="index.html#P">Preliminaries</a></li><li><b>What This Module Does</b></li></ul></div>
<p class="purpose">An overview of the arch module's role and abilities.</p>
<ul class="toc"><li><a href="P-wtmd.html#SP1">&#167;1. Prerequisites</a></li><li><a href="P-wtmd.html#SP2">&#167;2. Architecture versus VM</a></li><li><a href="P-wtmd.html#SP4">&#167;4. Compatibility</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. Prerequisites. </b>The arch module is a part of the Inform compiler toolset. It is
presented as a literate program or "web". Before diving in:
</p>
<ul class="items"><li>(a) It helps to have some experience of reading webs: see <a href="../../../inweb/docs/index.html" class="internal">inweb</a> for more.
</li><li>(b) The module is written in C, in fact ANSI C99, but this is disguised by the
fact that it uses some extension syntaxes provided by the <a href="../../../inweb/docs/index.html" class="internal">inweb</a> literate
programming tool, making it a dialect of C called InC. See <a href="../../../inweb/docs/index.html" class="internal">inweb</a> for
full details, but essentially: it's C without predeclarations or header files,
and where functions have names like <span class="extract"><span class="extract-syntax">Tags::add_by_name</span></span> rather than <span class="extract"><span class="extract-syntax">add_by_name</span></span>.
</li><li>(c) This module uses other modules drawn from the <a href="../compiler.html" class="internal">compiler</a>, and also
uses a module of utility functions called <a href="../../../inweb/docs/foundation-module/index.html" class="internal">foundation</a>.
For more, see <a href="../../../inweb/docs/foundation-module/P-abgtf.html" class="internal">A Brief Guide to Foundation (in foundation)</a>.
</li></ul>
<p class="commentary firstcommentary"><a id="SP2"></a><b>&#167;2. Architecture versus VM. </b>The Inform 7 build process ultimately wants to make code for some target
virtual machine &mdash; traditionally, the Z or Glulx machines. But it does this
in two stages: first generating abstract Inter code, then further generating
VM code from that.
</p>
<p class="commentary">It's an appealing notion that this first stage might be VM-independent: that
is, that <a href="../inform7/index.html" class="internal">inform7</a> could generate the same Inter code regardless of the
final VM, and that only the second stage would vary according to target.
And this is nearly true, but not quite. There are (currently) two reasons
why not:
</p>
<ul class="items"><li>(a) <a href="../inform7/index.html" class="internal">inform7</a> has to generate different code if integers are 16 rather
than 32 bits wide, and
</li><li>(b) it also generates different code with debugging enabled than without.
</li></ul>
<p class="commentary">Reason (b) could be avoided, at some cost in complexity, but reason (a) is
something we cannot sensibly avoid without making Inter a much higher-level
form of bytecode. Instead, we have "architectures" for Inter: for example,
32-bit with debugging enabled is the <span class="extract"><span class="extract-syntax">32d</span></span> architecture. See <a href="2-arc.html" class="internal">Architectures</a>;
if ever we introduce a 64-bit VM, that will need new architectures, and
this is where they would go.
</p>
<p class="commentary firstcommentary"><a id="SP3"></a><b>&#167;3. </b>A <a href="2-tvm.html#SP1" class="internal">target_vm</a> object, on the other hand, represents an actual choice of
virtual machine. For example, Glulx is a <a href="2-tvm.html#SP1" class="internal">target_vm</a>. The compilation
process thus involves a combination of both architecture and target:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="element-syntax">Source</span><span class="plain-syntax"> </span><span class="element-syntax">text</span><span class="plain-syntax"> -----------&gt; </span><span class="element-syntax">Inter</span><span class="plain-syntax"> </span><span class="element-syntax">code</span><span class="plain-syntax"> --------------&gt; </span><span class="element-syntax">Bytecode</span><span class="plain-syntax"> </span><span class="element-syntax">for</span>
<span class="plain-syntax"> </span><span class="function-syntax">INFORM7</span><span class="plain-syntax"> </span><span class="element-syntax">for</span><span class="plain-syntax"> </span><span class="element-syntax">architecture</span><span class="plain-syntax"> </span><span class="element-syntax">via</span><span class="plain-syntax"> </span><span class="function-syntax">INFORM6</span><span class="plain-syntax"> </span><span class="element-syntax">target</span><span class="plain-syntax"> </span><span class="element-syntax">virtual</span><span class="plain-syntax"> </span><span class="element-syntax">machine</span>
</pre>
<p class="commentary">Each VM can be used with just one architecture: use the function
<a href="2-tvm.html#SP10" class="internal">TargetVMs::get_architecture</a> to obtain this. It might seem reasonable
to say that Glulx ought to be viable with both <span class="extract"><span class="extract-syntax">32</span></span> and <span class="extract"><span class="extract-syntax">32d</span></span> architectures,
but in fact "Glulx" is not a single virtual machine but a family of them.
A specific member of this family would be the <a href="2-tvm.html#SP1" class="internal">target_vm</a> representing
Glulx version 3.1.2 with debugging enabled, and that can be used with the
<span class="extract"><span class="extract-syntax">32d</span></span> but not the <span class="extract"><span class="extract-syntax">32</span></span> architecture.
</p>
<p class="commentary">There can in principle be numerous VMs in any given family; see
<a href="2-tvm.html#SP6" class="internal">TargetVMs::find_in_family</a> to obtain family members with given behaviour,
and in general see <a href="2-tvm.html" class="internal">Target Virtual Machines</a> for more.
</p>
<p class="commentary firstcommentary"><a id="SP4"></a><b>&#167;4. Compatibility. </b>Not all software in the Inform stack &mdash; source text from the user, extensions,
kits of Inter code &mdash; will be compatible with every architecture, or with
every VM. We represent that by giving something a <a href="2-cmp.html#SP1" class="internal">compatibility_specification</a>
object to say what it can work with: the function <a href="2-cmp.html#SP11" class="internal">Compatibility::test</a>
determines whether any given VM is allowed with this specification.
</p>
<p class="commentary">A specification can be converted to or from text: see <a href="2-cmp.html#SP5" class="internal">Compatibility::write</a>
and <a href="2-cmp.html#SP6" class="internal">Compatibility::from_text</a>. Typically, such text might read "for 32d only".
</p>
<p class="commentary">Lastly, <a href="2-cmp.html#SP2" class="internal">Compatibility::all</a> returns a specification meaning "works with
anything". This should be the default; <a href="2-cmp.html#SP11" class="internal">Compatibility::test_universal</a> tests
whether a specification is equivalent to this.
</p>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprevoff">&#10094;</li><li class="progresscurrentchapter">P</li><li class="progresscurrent">wtmd</li><li class="progresschapter"><a href="1-am.html">1</a></li><li class="progresschapter"><a href="2-arc.html">2</a></li><li class="progressnext"><a href="1-am.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>

View file

@ -56,6 +56,17 @@
<hr>
<div class="contentspage">
<ul class="chapterlist">
<li>
<p class="chapterentry"><a name="P"></a>
<span class="chaptertitle">Preliminaries</span></p>
<ul class="sectionlist">
<li>
<p class="sectionentry"><a href="P-wtmd.html">
<spon class="sectiontitle">What This Module Does</span></a> -
<span class="sectionpurpose">An overview of the arch module's role and abilities.</span></p>
</li>
</ul>
</li>
<li>
<p class="chapterentry"><a name="1"></a>
<span class="chaptertitle">Chapter 1: Setting Up</span></p>
@ -69,7 +80,7 @@
</li>
<li>
<p class="chapterentry"><a name="2"></a>
<span class="chaptertitle">Chapter 2: Architectures</span></p>
<span class="chaptertitle">Chapter 2: Architectures and VMs</span></p>
<ul class="sectionlist">
<li>
<p class="sectionentry"><a href="2-arc.html">
@ -79,12 +90,12 @@
<li>
<p class="sectionentry"><a href="2-tvm.html">
<spon class="sectiontitle">Target Virtual Machines</span></a> -
<span class="sectionpurpose">To deal with multiple inter architectures.</span></p>
<span class="sectionpurpose">To deal with multiple object code formats.</span></p>
</li>
<li>
<p class="sectionentry"><a href="2-cmp.html">
<spon class="sectiontitle">Compatibility</span></a> -
<span class="sectionpurpose">To manage compatibility lists: what can be compiled to what format.</span></p>
<span class="sectionpurpose">To manage specifications of compatibility with some VMs but not others.</span></p>
</li>
</ul>
</li>

View file

@ -80,14 +80,14 @@ function togglePopup(material_id) {
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Unit::test_one</span><span class="plain-syntax">(</span><span class="constant-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">test</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">"'%S': "</span><span class="plain-syntax">, </span><span class="identifier-syntax">test</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">compatibility_specification</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax"> = </span><a href="../arch-module/2-cmp.html#SP1" class="function-link"><span class="function-syntax">Compatibility::from_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">test</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">compatibility_specification</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax"> = </span><a href="../arch-module/2-cmp.html#SP6" class="function-link"><span class="function-syntax">Compatibility::from_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">test</span><span 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="identifier-syntax">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"not a valid compatibility specification\n\n"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><a href="../arch-module/2-cmp.html#SP1" class="function-link"><span class="function-syntax">Compatibility::write</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="../arch-module/2-cmp.html#SP5" class="function-link"><span class="function-syntax">Compatibility::write</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</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">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">":\n"</span><span class="plain-syntax">); </span><span class="constant-syntax">INDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">, </span><span class="reserved-syntax">target_vm</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../arch-module/2-cmp.html#SP1" class="function-link"><span class="function-syntax">Compatibility::with</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><a href="../arch-module/2-tvm.html#SP1" class="function-link"><span class="function-syntax">TargetVMs::write</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../arch-module/2-cmp.html#SP11" class="function-link"><span class="function-syntax">Compatibility::test</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><a href="../arch-module/2-tvm.html#SP4" class="function-link"><span class="function-syntax">TargetVMs::write</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</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">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>

View file

@ -58,7 +58,7 @@
<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">bytecode</a></li><li><a href="index.html#1">Chapter 1: Setting Up</a></li><li><b>Bytecode Module</b></li></ul></div>
<p class="purpose">Setting up the use of this module.</p>
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <span class="extract"><span class="extract-syntax">foundation</span></span>, and
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <a href="../../../inweb/docs/foundation-module/index.html" class="internal">foundation</a>, and
contains no code of interest. The following constant exists only in tools
which use this module:
</p>

View file

@ -58,7 +58,7 @@
<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">codegen</a></li><li><a href="index.html#1">Chapter 1: Setting Up</a></li><li><b>Codegen Module</b></li></ul></div>
<p class="purpose">Setting up the use of this module.</p>
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <span class="extract"><span class="extract-syntax">foundation</span></span>, and
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <a href="../../../inweb/docs/foundation-module/index.html" class="internal">foundation</a>, and
contains no code of interest. The following constant exists only in tools
which use this module:
</p>

View file

@ -80,7 +80,7 @@ MathJax = {
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7 Modules</a></li><li><a href="index.html">core</a></li><li><a href="index.html#1">Chapter 1: Configuration and Control</a></li><li><b>Core Module</b></li></ul></div>
<p class="purpose">Setting up the use of this module.</p>
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <span class="extract"><span class="extract-syntax">foundation</span></span>, and
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <a href="../../../inweb/docs/foundation-module/index.html" class="internal">foundation</a>, and
contains no code of interest. The following constant exists only in tools
which use this module:
</p>

View file

@ -58,7 +58,7 @@
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Shared Modules</a></li><li><a href="index.html">html</a></li><li><a href="index.html#1">Chapter 1: Starting Up</a></li><li><b>HTML Module</b></li></ul></div>
<p class="purpose">Setting up the use of this module.</p>
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <span class="extract"><span class="extract-syntax">foundation</span></span>, and
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <a href="../../../inweb/docs/foundation-module/index.html" class="internal">foundation</a>, and
contains no code of interest. The following constant exists only in tools
which use this module:
</p>
@ -70,10 +70,10 @@ which use this module:
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">HTMLModule::start</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-hm.html#SP2_1" class="named-paragraph-link"><span class="named-paragraph">Register this module's memory allocation reasons</span><span class="named-paragraph-number">2.1</span></a></span><span class="character-syntax">;</span>
<span class="character-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-hm.html#SP2_2" class="named-paragraph-link"><span class="named-paragraph">Register this module's stream writers</span><span class="named-paragraph-number">2.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-hm.html#SP2_3" class="named-paragraph-link"><span class="named-paragraph">Register this module's debugging log aspects</span><span class="named-paragraph-number">2.3</span></a></span><span class="character-syntax">;</span>
<span class="character-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-hm.html#SP2_4" class="named-paragraph-link"><span class="named-paragraph">Register this module's debugging log writers</span><span class="named-paragraph-number">2.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-hm.html#SP2_1" class="named-paragraph-link"><span class="named-paragraph">Register this module's memory allocation reasons</span><span class="named-paragraph-number">2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-hm.html#SP2_2" class="named-paragraph-link"><span class="named-paragraph">Register this module's stream writers</span><span class="named-paragraph-number">2.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-hm.html#SP2_3" class="named-paragraph-link"><span class="named-paragraph">Register this module's debugging log aspects</span><span class="named-paragraph-number">2.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-hm.html#SP2_4" class="named-paragraph-link"><span class="named-paragraph">Register this module's debugging log writers</span><span class="named-paragraph-number">2.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">HTMLModule::end</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">}</span>

View file

@ -35,6 +35,7 @@ function togglePopup(material_id) {
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Preform-Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
@ -149,18 +150,19 @@ to see if it might be a heading. For instance, a paragraph consisting of
"Black Gold".
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">&lt;</span><span class="identifier-syntax">extension</span><span class="plain-syntax">-</span><span class="identifier-syntax">documentation</span><span class="plain-syntax">-</span><span class="identifier-syntax">heading</span><span class="plain-syntax">&gt; ::=</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">chapter</span><span class="plain-syntax"> : ... | ==&gt; </span><span class="constant-syntax">1</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">section</span><span class="plain-syntax"> : ... ==&gt; </span><span class="constant-syntax">2</span>
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;extension-documentation-heading&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">chapter</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">:</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> 1</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">section</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">:</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> 2</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP4"></a><b>&#167;4. </b></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">HTML::Documentation::extension_documentation_heading</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">HTML::Documentation::extension_documentation_heading</span></span>:<br/><a href="2-hd.html#SP7">&#167;7</a>, <a href="2-hd.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">level</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> *</span><span class="identifier-syntax">HW</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (&lt;</span><span class="identifier-syntax">extension</span><span class="plain-syntax">-</span><span class="identifier-syntax">documentation</span><span class="plain-syntax">-</span><span class="identifier-syntax">heading</span><span class="plain-syntax">&gt;(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;extension-documentation-heading&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::length</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">10</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="comment-syntax"> not enough space: this runs into the end-of-file padding</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">level</span><span class="plain-syntax"> = &lt;&lt;</span><span class="identifier-syntax">r</span><span class="plain-syntax">&gt;&gt;;</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">level</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;r&gt;&gt;</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::trim_first_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::trim_first_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">end</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">end</span><span class="plain-syntax">&lt;=</span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">end</span><span class="plain-syntax">) != </span><span class="identifier-syntax">PARBREAK_V</span><span class="plain-syntax">)) </span><span class="identifier-syntax">end</span><span class="plain-syntax">++;</span>
@ -183,32 +185,33 @@ more exacting specification: a paragraph in the shape
an asterisk count of 3, and the rubric being "A Tale of the Texas Oilmen".
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">&lt;</span><span class="identifier-syntax">extension</span><span class="plain-syntax">-</span><span class="identifier-syntax">example</span><span class="plain-syntax">-</span><span class="identifier-syntax">header</span><span class="plain-syntax">&gt; ::=</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">example</span><span class="plain-syntax"> : &lt;</span><span class="identifier-syntax">row</span><span class="plain-syntax">-</span><span class="identifier-syntax">of</span><span class="plain-syntax">-</span><span class="identifier-syntax">asterisks</span><span class="plain-syntax">&gt; ... - ... | ==&gt; </span><span class="identifier-syntax">R</span><span class="plain-syntax">[1]</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">example</span><span class="plain-syntax"> : ... - ... ==&gt; </span><span class="constant-syntax">0</span>
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;extension-example-header&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">example</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">:</span><span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;row-of-asterisks&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">-</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> R[1]</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">example</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">:</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">-</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> 0</span>
<span class="plain-syntax">&lt;</span><span class="identifier-syntax">row</span><span class="plain-syntax">-</span><span class="identifier-syntax">of</span><span class="plain-syntax">-</span><span class="identifier-syntax">asterisks</span><span class="plain-syntax">&gt; ::=</span>
<span class="plain-syntax"> * | ==&gt; </span><span class="constant-syntax">1</span>
<span class="plain-syntax"> ** | ==&gt; </span><span class="constant-syntax">2</span>
<span class="plain-syntax"> \*** | ==&gt; </span><span class="constant-syntax">3</span>
<span class="plain-syntax"> **** ==&gt; </span><span class="constant-syntax">4</span>
<span class="Preform-function-syntax">&lt;row-of-asterisks&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">*</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> 1</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">**</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> 2</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">\***</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> 3</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">****</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> 4</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP6"></a><b>&#167;6. </b></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">HTML::Documentation::extension_documentation_example</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">HTML::Documentation::extension_documentation_example</span></span>:<br/><a href="2-hd.html#SP7">&#167;7</a>, <a href="2-hd.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">asterisks</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> *</span><span class="identifier-syntax">egn</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> *</span><span class="identifier-syntax">egr</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::length</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">10</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">; </span><span class="comment-syntax"> not enough space: this runs into the end-of-file padding</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (&lt;</span><span class="identifier-syntax">extension</span><span class="plain-syntax">-</span><span class="identifier-syntax">example</span><span class="plain-syntax">-</span><span class="identifier-syntax">header</span><span class="plain-syntax">&gt;(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">NW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(&lt;</span><span class="identifier-syntax">extension</span><span class="plain-syntax">-</span><span class="identifier-syntax">example</span><span class="plain-syntax">-</span><span class="identifier-syntax">header</span><span class="plain-syntax">&gt;, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">RW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(&lt;</span><span class="identifier-syntax">extension</span><span class="plain-syntax">-</span><span class="identifier-syntax">example</span><span class="plain-syntax">-</span><span class="identifier-syntax">header</span><span class="plain-syntax">&gt;, </span><span class="constant-syntax">2</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;extension-example-header&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">NW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;extension-example-header&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">RW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_word</span><span class="plain-syntax">(</span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;extension-example-header&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">r2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">RW</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">r2</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) &amp;&amp; ((</span><span class="identifier-syntax">Lexer::word</span><span class="plain-syntax">(</span><span class="identifier-syntax">r2</span><span class="plain-syntax">) == </span><span class="identifier-syntax">PARBREAK_V</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) </span><span class="identifier-syntax">r2</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">r2</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">r2</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> a successful match has now been made</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">asterisks</span><span class="plain-syntax"> = &lt;&lt;</span><span class="identifier-syntax">r</span><span class="plain-syntax">&gt;&gt;; *</span><span class="identifier-syntax">egn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NW</span><span class="plain-syntax">; *</span><span class="identifier-syntax">egr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RW</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">asterisks</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;r&gt;&gt;</span><span class="plain-syntax">; *</span><span class="identifier-syntax">egn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NW</span><span class="plain-syntax">; *</span><span class="identifier-syntax">egr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">RW</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
@ -344,14 +347,15 @@ far as the user is concerned it opens the example and goes there.
<ul class="endnotetexts"><li>This code is used in <a href="2-hd.html#SP7">&#167;7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8"></a><b>&#167;8. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">&lt;</span><span class="identifier-syntax">table</span><span class="plain-syntax">-</span><span class="identifier-syntax">sentence</span><span class="plain-syntax">&gt; ::=</span>
<span class="plain-syntax"> &lt;</span><span class="reserved-syntax">if</span><span class="plain-syntax">-</span><span class="identifier-syntax">start</span><span class="plain-syntax">-</span><span class="identifier-syntax">of</span><span class="plain-syntax">-</span><span class="identifier-syntax">paragraph</span><span class="plain-syntax">&gt; </span><span class="identifier-syntax">table</span><span class="plain-syntax"> ...</span>
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;table-sentence&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;if-start-of-paragraph&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">table</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP9"></a><b>&#167;9. Setting the body text. </b></p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">EDOC_ALL_EXAMPLES_CLOSED</span><span class="plain-syntax"> -1 </span><span class="comment-syntax"> do not change this without also changing Extensions</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">EDOC_FRAGMENT_ONLY</span><span class="plain-syntax"> -2 </span><span class="comment-syntax"> must differ from this and from all example variant numbers</span>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="Preform-constant-syntax">EDOC_ALL_EXAMPLES_CLOSED</span><span class="Preform-plain-syntax"> -1 </span><span class="Preform-comment-syntax"> do not change this without also changing Extensions</span>
<span class="definition-keyword">define</span> <span class="Preform-constant-syntax">EDOC_FRAGMENT_ONLY</span><span class="Preform-plain-syntax"> -2 </span><span class="Preform-comment-syntax"> must differ from this and from all example variant numbers</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">HTML::Documentation::set_body_text</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">HTML::Documentation::set_body_text</span></span>:<br/><a href="2-hd.html#SP7_1">&#167;7.1</a>, <a href="2-hd.html#SP7_2">&#167;7.2</a>, <a href="2-hd.html#SP9_6">&#167;9.6</a>, <a href="2-hd.html#SP9_7">&#167;9.7</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">,</span>
@ -385,12 +389,12 @@ far as the user is concerned it opens the example and goes there.
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">example_count</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">26</span><span class="plain-syntax">) &amp;&amp; (</span><a href="2-hd.html#SP6" class="function-link"><span class="function-syntax">HTML::Documentation::extension_documentation_example</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Wordings::from</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">), &amp;</span><span class="identifier-syntax">asterisks</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">NW</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">RUBW</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">skipping_text_of_an_example</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mid_example</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-hd.html#SP9_9" class="named-paragraph-link"><span class="named-paragraph">Close the previous example's text</span><span class="named-paragraph-number">9.9</span></a></span><span class="character-syntax">;</span>
<span class="character-syntax"> mid_example = FALSE;</span>
<span class="character-syntax"> example_count++;</span>
<span class="character-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-hd.html#SP9_7" class="named-paragraph-link"><span class="named-paragraph">Typeset the heading of this example</span><span class="named-paragraph-number">9.7</span></a></span><span class="character-syntax">;</span>
<span class="character-syntax"> if (example_count == example_which_is_open) {</span>
<span class="character-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-hd.html#SP9_8" class="named-paragraph-link"><span class="named-paragraph">Open the new example's text</span><span class="named-paragraph-number">9.8</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mid_example</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-hd.html#SP9_9" class="named-paragraph-link"><span class="named-paragraph">Close the previous example's text</span><span class="named-paragraph-number">9.9</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mid_example</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">example_count</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-hd.html#SP9_7" class="named-paragraph-link"><span class="named-paragraph">Typeset the heading of this example</span><span class="named-paragraph-number">9.7</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">example_count</span><span class="plain-syntax"> == </span><span class="identifier-syntax">example_which_is_open</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-hd.html#SP9_8" class="named-paragraph-link"><span class="named-paragraph">Open the new example's text</span><span class="named-paragraph-number">9.8</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mid_example</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">skipping_text_of_an_example</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::last_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">RUBW</span><span class="plain-syntax">); </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
@ -402,11 +406,11 @@ far as the user is concerned it opens the example and goes there.
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-hd.html#SP9_5" class="named-paragraph-link"><span class="named-paragraph">Transcribe an ordinary word of the documentation</span><span class="named-paragraph-number">9.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">close_I6_position</span><span class="plain-syntax"> == </span><span class="identifier-syntax">i</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" -)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mid_example</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-hd.html#SP9_9" class="named-paragraph-link"><span class="named-paragraph">Close the previous example's text</span><span class="named-paragraph-number">9.9</span></a></span><span class="character-syntax">;</span>
<span class="character-syntax"> if (example_which_is_open != EDOC_FRAGMENT_ONLY) </span><span class="named-paragraph-container code-font"><a href="2-hd.html#SP9_1" class="named-paragraph-link"><span class="named-paragraph">Handle a paragraph break</span><span class="named-paragraph-number">9.1</span></a></span><span class="character-syntax">;</span>
<span class="character-syntax"> HTML_CLOSE("p");</span>
<span class="character-syntax"> return example_count;</span>
<span class="character-syntax">}</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mid_example</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-hd.html#SP9_9" class="named-paragraph-link"><span class="named-paragraph">Close the previous example's text</span><span class="named-paragraph-number">9.9</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">example_which_is_open</span><span class="plain-syntax"> != </span><span class="constant-syntax">EDOC_FRAGMENT_ONLY</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-hd.html#SP9_1" class="named-paragraph-link"><span class="named-paragraph">Handle a paragraph break</span><span class="named-paragraph-number">9.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">example_count</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9_1"></a><b>&#167;9.1. Typesetting the standard matter. </b>A paragraph break might mean the end of displayed matter (and if so, then also
the end of any table being displayed). Otherwise, it just means a paragraph
@ -448,25 +452,26 @@ paragraph.
asterisk and colon:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">&lt;</span><span class="identifier-syntax">extension</span><span class="plain-syntax">-</span><span class="identifier-syntax">documentation</span><span class="plain-syntax">-</span><span class="identifier-syntax">paste</span><span class="plain-syntax">-</span><span class="identifier-syntax">marker</span><span class="plain-syntax">&gt; ::=</span>
<span class="plain-syntax"> * : ...</span>
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;extension-documentation-paste-marker&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">*</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">:</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-prf.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP9_4"></a><b>&#167;9.4. </b>Two lower-level sorts of breaks can also occur in the middle of a paragraph:
line breaks, indicated by newlines plus some tabs, and column breaks inside
I7 source tables, indicated by tabs. We have to deal with those before we
can move on to the subsequent word.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Handle a line or column break, if there is one</span><span class="named-paragraph-number">9.4</span></span><span class="comment-syntax"> =</span>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Handle a line or column break, if there is one</span><span class="named-paragraph-number">9.4</span></span><span class="Preform-comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Lexer::indentation_level</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">indentation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexer::indentation_level</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">indentation</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-hd.html#SP9_4_2" class="named-paragraph-link"><span class="named-paragraph">Handle the start of a line which is indented</span><span class="named-paragraph-number">9.4.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (&lt;</span><span class="identifier-syntax">extension</span><span class="plain-syntax">-</span><span class="identifier-syntax">documentation</span><span class="plain-syntax">-</span><span class="identifier-syntax">paste</span><span class="plain-syntax">-</span><span class="identifier-syntax">marker</span><span class="plain-syntax">&gt;(</span><span class="identifier-syntax">Wordings::from</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(&lt;</span><span class="identifier-syntax">extension</span><span class="plain-syntax">-</span><span class="identifier-syntax">documentation</span><span class="plain-syntax">-</span><span class="identifier-syntax">paste</span><span class="plain-syntax">-</span><span class="identifier-syntax">marker</span><span class="plain-syntax">&gt;, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;extension-documentation-paste-marker&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::from</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;extension-documentation-paste-marker&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="2-hd.html#SP9_4_1" class="named-paragraph-link"><span class="named-paragraph">Incorporate an icon linking to a Javascript function to paste the text which follows</span><span class="named-paragraph-number">9.4.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">++; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
@ -548,7 +553,7 @@ need to achieve with an HTML <span class="extract"><span class="extract-syntax">
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_OPEN</span><span class="plain-syntax">(</span><span class="string-syntax">"blockquote"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::begin_colour</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"000080"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mid_displayed_source_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (&lt;</span><span class="identifier-syntax">table</span><span class="plain-syntax">-</span><span class="identifier-syntax">sentence</span><span class="plain-syntax">&gt;(</span><span class="identifier-syntax">Wordings::from</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;table-sentence&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::from</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">start_table_next_line</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">indentation</span><span class="plain-syntax">--;</span>

View file

@ -60,7 +60,7 @@
<ul class="toc"><li><a href="1-im.html#SP3">&#167;3. The beginning</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <span class="extract"><span class="extract-syntax">foundation</span></span>, and
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <a href="../../../inweb/docs/foundation-module/index.html" class="internal">foundation</a>, and
contains no code of interest. The following constant exists only in tools
which use this module:
</p>

View file

@ -58,7 +58,7 @@
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7 Modules</a></li><li><a href="index.html">index</a></li><li><a href="index.html#1">Chapter 1: Starting Up</a></li><li><b>Index Module</b></li></ul></div>
<p class="purpose">Setting up the use of this module.</p>
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <span class="extract"><span class="extract-syntax">foundation</span></span>, and
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <a href="../../../inweb/docs/foundation-module/index.html" class="internal">foundation</a>, and
contains no code of interest. The following constant exists only in tools
which use this module:
</p>

View file

@ -58,7 +58,7 @@
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7 Modules</a></li><li><a href="index.html">inflections</a></li><li><a href="index.html#1">Chapter 1: Starting Up</a></li><li><b>Inflections Module</b></li></ul></div>
<p class="purpose">Setting up the use of this module.</p>
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <span class="extract"><span class="extract-syntax">foundation</span></span>, and
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <a href="../../../inweb/docs/foundation-module/index.html" class="internal">foundation</a>, and
contains no code of interest. The following constant exists only in tools
which use this module:
</p>

View file

@ -58,7 +58,7 @@
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7 Modules</a></li><li><a href="index.html">kinds</a></li><li><a href="index.html#1">Chapter 1: Starting Up</a></li><li><b>Kinds Module</b></li></ul></div>
<p class="purpose">Setting up the use of this module.</p>
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <span class="extract"><span class="extract-syntax">foundation</span></span>, and
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <a href="../../../inweb/docs/foundation-module/index.html" class="internal">foundation</a>, and
contains no code of interest. The following constant exists only in tools
which use this module:
</p>

View file

@ -58,7 +58,7 @@
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7 Modules</a></li><li><a href="index.html">linguistics</a></li><li><a href="index.html#1">Chapter 1: Setting Up</a></li><li><b>Linguistics Module</b></li></ul></div>
<p class="purpose">Setting up the use of this module.</p>
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <span class="extract"><span class="extract-syntax">foundation</span></span>, and
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <a href="../../../inweb/docs/foundation-module/index.html" class="internal">foundation</a>, and
contains no code of interest. The following constant exists only in tools
which use this module:
</p>

View file

@ -58,7 +58,7 @@
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7 Modules</a></li><li><a href="index.html">multimedia</a></li><li><a href="index.html#1">Chapter 1: Starting Up</a></li><li><b>Multimedia Module</b></li></ul></div>
<p class="purpose">Setting up the use of this module.</p>
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <span class="extract"><span class="extract-syntax">foundation</span></span>, and
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <a href="../../../inweb/docs/foundation-module/index.html" class="internal">foundation</a>, and
contains no code of interest. The following constant exists only in tools
which use this module:
</p>

View file

@ -58,7 +58,7 @@
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inform7 Modules</a></li><li><a href="index.html">problems</a></li><li><a href="index.html#1">Chapter 1: Starting Up</a></li><li><b>Problems Module</b></li></ul></div>
<p class="purpose">Setting up the use of this module.</p>
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <span class="extract"><span class="extract-syntax">foundation</span></span>, and
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <a href="../../../inweb/docs/foundation-module/index.html" class="internal">foundation</a>, and
contains no code of interest. The following constant exists only in tools
which use this module:
</p>
@ -70,10 +70,10 @@ which use this module:
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ProblemsModule::start</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-pm.html#SP2_1" class="named-paragraph-link"><span class="named-paragraph">Register this module's memory allocation reasons</span><span class="named-paragraph-number">2.1</span></a></span><span class="character-syntax">;</span>
<span class="character-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-pm.html#SP2_2" class="named-paragraph-link"><span class="named-paragraph">Register this module's stream writers</span><span class="named-paragraph-number">2.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-pm.html#SP2_3" class="named-paragraph-link"><span class="named-paragraph">Register this module's debugging log aspects</span><span class="named-paragraph-number">2.3</span></a></span><span class="character-syntax">;</span>
<span class="character-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-pm.html#SP2_4" class="named-paragraph-link"><span class="named-paragraph">Register this module's debugging log writers</span><span class="named-paragraph-number">2.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-pm.html#SP2_1" class="named-paragraph-link"><span class="named-paragraph">Register this module's memory allocation reasons</span><span class="named-paragraph-number">2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-pm.html#SP2_2" class="named-paragraph-link"><span class="named-paragraph">Register this module's stream writers</span><span class="named-paragraph-number">2.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-pm.html#SP2_3" class="named-paragraph-link"><span class="named-paragraph">Register this module's debugging log aspects</span><span class="named-paragraph-number">2.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-pm.html#SP2_4" class="named-paragraph-link"><span class="named-paragraph">Register this module's debugging log writers</span><span class="named-paragraph-number">2.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ParseTree::allow_annotation_to_category</span><span class="plain-syntax">(</span><span class="identifier-syntax">L2_NCAT</span><span class="plain-syntax">, </span><span class="constant-syntax">problem_falls_under_ANNOT</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">ProblemsModule::end</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>

View file

@ -279,7 +279,7 @@ in the parse tree, or with a literal word range.
<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">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ParseTree::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (&lt;</span><span class="identifier-syntax">phrase</span><span class="plain-syntax">-</span><span class="identifier-syntax">beginning</span><span class="plain-syntax">-</span><span class="identifier-syntax">block</span><span class="plain-syntax">&gt;(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(&lt;</span><span class="identifier-syntax">phrase</span><span class="plain-syntax">-</span><span class="identifier-syntax">beginning</span><span class="plain-syntax">-</span><span class="identifier-syntax">block</span><span class="plain-syntax">&gt;, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;phrase-beginning-block&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;phrase-beginning-block&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><a href="2-pl2.html#SP5" class="function-link"><span class="function-syntax">Problems::problem_quote_textual</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t</span><span class="plain-syntax">, </span><span class="character-syntax">'S'</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>

View file

@ -540,7 +540,7 @@ a message which diagnoses the problem rather better.
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_WORDING</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">AW</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">i</span><span class="plain-syntax"> != </span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">ParseTree::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">))) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Word::unexpectedly_upper_case</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = &lt;</span><span class="identifier-syntax">meaningful</span><span class="plain-syntax">-</span><span class="identifier-syntax">nonimperative</span><span class="plain-syntax">-</span><span class="identifier-syntax">verb</span><span class="plain-syntax">&gt;(</span><span class="identifier-syntax">Wordings::from</span><span class="plain-syntax">(</span><span class="identifier-syntax">ParseTree::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">), </span><span class="identifier-syntax">i</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;meaningful-nonimperative-verb&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::from</span><span class="plain-syntax">(</span><span class="identifier-syntax">ParseTree::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">), </span><span class="identifier-syntax">i</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">RTW</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Wordings::new</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="2-pl2.html#SP6" class="function-link"><span class="function-syntax">Problems::quote_source</span></a><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>

View file

@ -58,7 +58,7 @@
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inbuild Modules</a></li><li><a href="index.html">supervisor</a></li><li><a href="index.html#1">Chapter 1: Setting Up</a></li><li><b>Supervisor Module</b></li></ul></div>
<p class="purpose">Setting up the use of this module.</p>
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <span class="extract"><span class="extract-syntax">foundation</span></span>, and
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <a href="../../../inweb/docs/foundation-module/index.html" class="internal">foundation</a>, and
contains no code of interest. The following constant exists only in tools
which use this module:
</p>

View file

@ -130,7 +130,7 @@ contributes only the un-filename-extended leafname <span class="extract"><span c
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Editions::inspect</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">Editions::inspect</span></span>:<br/>Copies - <a href="2-cps.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">inbuild_edition</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="2-edt.html#SP1" class="function-link"><span class="function-syntax">Editions::write</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">E</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Compatibility::universal</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">compatibility</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Compatibility::test_universal</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">compatibility</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">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" ("</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Compatibility::write</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">compatibility</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">")"</span><span class="plain-syntax">);</span>

View file

@ -485,7 +485,7 @@ otherwise.
<span class="Preform-function-syntax">&lt;current-virtual-machine&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">internal</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">{</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">if</span><span class="Preform-plain-syntax"> (</span><span class="Preform-function-syntax">&lt;virtual-machine&gt;</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">W</span><span class="Preform-plain-syntax">)) {</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">compatibility_specification</span><span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">vms</span><span class="Preform-plain-syntax"> = (</span><span class="Preform-identifier-syntax">compatibility_specification</span><span class="Preform-plain-syntax"> *) </span><span class="Preform-function-syntax">&lt;&lt;rp&gt;&gt;</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">X</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">Compatibility::with</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">vms</span><span class="Preform-plain-syntax">, </span><a href="1-ic.html#SP9" class="function-link"><span class="Preform-function-syntax">Supervisor::current_vm</span></a><span class="Preform-plain-syntax">());</span>
<span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">X</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">Compatibility::test</span><span class="Preform-plain-syntax">(</span><span class="Preform-identifier-syntax">vms</span><span class="Preform-plain-syntax">, </span><a href="1-ic.html#SP9" class="function-link"><span class="Preform-function-syntax">Supervisor::current_vm</span></a><span class="Preform-plain-syntax">());</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">return</span><span class="Preform-plain-syntax"> </span><span class="Preform-identifier-syntax">TRUE</span><span class="Preform-plain-syntax">;</span>
<span class="Preform-plain-syntax"> } </span><span class="Preform-reserved-syntax">else</span><span class="Preform-plain-syntax"> {</span>
<span class="Preform-plain-syntax"> *</span><span class="Preform-identifier-syntax">X</span><span class="Preform-plain-syntax"> = </span><span class="Preform-identifier-syntax">FALSE</span><span class="Preform-plain-syntax">;</span>

View file

@ -278,7 +278,7 @@ Sausages by Mr Punch, and loaded it, but then read the sentence
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-nst.html#SP2" class="function-link"><span class="function-syntax">Nests::get_tag</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">search_result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">nest</span><span class="plain-syntax">) == </span><span class="constant-syntax">INTERNAL_NEST_TAG</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">loaded_from_built_in_area</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">compatibility_specification</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax"> = </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_copy</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">compatibility</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Compatibility::with</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="1-ic.html#SP9" class="function-link"><span class="function-syntax">Supervisor::current_vm</span></a><span class="plain-syntax">()) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Compatibility::test</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="1-ic.html#SP9" class="function-link"><span class="function-syntax">Supervisor::current_vm</span></a><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="6-inc.html#SP5_1_1" class="named-paragraph-link"><span class="named-paragraph">Issue a problem message saying that the VM does not meet requirements</span><span class="named-paragraph-number">5.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">LinkedLists::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">search_result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">copy</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">errors_reading_source_text</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>

View file

@ -799,14 +799,14 @@ has no restriction on its use).
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">something</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">everything</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">target_vm</span><span class="plain-syntax"> *</span><span class="identifier-syntax">VM</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">, </span><span class="identifier-syntax">target_vm</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Compatibility::with</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Compatibility::test</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">something</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">everything</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">something</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"none"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">everything</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">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">, </span><span class="identifier-syntax">target_vm</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Compatibility::with</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">TargetVMs::debug_enabled</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Compatibility::test</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">TargetVMs::debug_enabled</span><span class="plain-syntax">(</span><span class="identifier-syntax">VM</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><a href="7-ip.html#SP2" class="function-link"><span class="function-syntax">ExtensionIndex::plot_icon</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">VM</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>

View file

@ -58,7 +58,7 @@
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Shared Modules</a></li><li><a href="index.html">syntax</a></li><li><a href="index.html#1">Chapter 1: Setting Up</a></li><li><b>Syntax Module</b></li></ul></div>
<p class="purpose">Setting up the use of this module.</p>
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <span class="extract"><span class="extract-syntax">foundation</span></span>, and
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <a href="../../../inweb/docs/foundation-module/index.html" class="internal">foundation</a>, and
contains no code of interest. The following constant exists only in tools
which use this module:
</p>

View file

@ -58,7 +58,7 @@
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Shared Modules</a></li><li><a href="index.html">words</a></li><li><a href="index.html#1">Chapter 1: Setting Up</a></li><li><b>Words Module</b></li></ul></div>
<p class="purpose">Setting up the use of this module.</p>
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <span class="extract"><span class="extract-syntax">foundation</span></span>, and
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>This section simoly sets up the module in ways expected by <a href="../../../inweb/docs/foundation-module/index.html" class="internal">foundation</a>, and
contains no code of interest. The following constant exists only in tools
which use this module:
</p>

View file

@ -2,7 +2,7 @@
Setting up the use of this module.
@ This section simoly sets up the module in ways expected by |foundation|, and
@ This section simoly sets up the module in ways expected by //foundation//, and
contains no code of interest. The following constant exists only in tools
which use this module:

View file

@ -60,7 +60,7 @@ void Editions::write_canonical_leaf(OUTPUT_STREAM, inbuild_edition *E) {
=
void Editions::inspect(OUTPUT_STREAM, inbuild_edition *E) {
Editions::write(OUT, E);
if (Compatibility::universal(E->compatibility) == FALSE) {
if (Compatibility::test_universal(E->compatibility) == FALSE) {
WRITE(" (");
Compatibility::write(OUT, E->compatibility);
WRITE(")");

View file

@ -357,7 +357,7 @@ otherwise.
<current-virtual-machine> internal {
if (<virtual-machine>(W)) {
compatibility_specification *vms = (compatibility_specification *) <<rp>>;
*X = Compatibility::with(vms, Supervisor::current_vm());
*X = Compatibility::test(vms, Supervisor::current_vm());
return TRUE;
} else {
*X = FALSE;

View file

@ -183,7 +183,7 @@ inform_extension *Inclusions::load(parse_node *last_H0, parse_node *at,
if (Nests::get_tag(search_result->nest) == INTERNAL_NEST_TAG)
E->loaded_from_built_in_area = TRUE;
compatibility_specification *C = E->as_copy->edition->compatibility;
if (Compatibility::with(C, Supervisor::current_vm()) == FALSE)
if (Compatibility::test(C, Supervisor::current_vm()) == FALSE)
@<Issue a problem message saying that the VM does not meet requirements@>;
if (LinkedLists::len(search_result->copy->errors_reading_source_text) == 0) {

View file

@ -608,14 +608,14 @@ void ExtensionIndex::write_icons(OUTPUT_STREAM, compatibility_specification *C)
int something = FALSE, everything = TRUE;
target_vm *VM;
LOOP_OVER(VM, target_vm)
if (Compatibility::with(C, VM))
if (Compatibility::test(C, VM))
something = TRUE;
else
everything = FALSE;
if (something == FALSE) WRITE("none");
if (everything == FALSE)
LOOP_OVER(VM, target_vm)
if ((Compatibility::with(C, VM)) && (TargetVMs::debug_enabled(VM)))
if ((Compatibility::test(C, VM)) && (TargetVMs::debug_enabled(VM)))
ExtensionIndex::plot_icon(OUT, VM);
}

View file

@ -2,7 +2,7 @@
Setting up the use of this module.
@ This section simoly sets up the module in ways expected by |foundation|, and
@ This section simoly sets up the module in ways expected by //foundation//, and
contains no code of interest. The following constant exists only in tools
which use this module:

View file

@ -2,7 +2,7 @@
Setting up the use of this module.
@ This section simoly sets up the module in ways expected by |foundation|, and
@ This section simoly sets up the module in ways expected by //foundation//, and
contains no code of interest. The following constant exists only in tools
which use this module:

View file

@ -2,7 +2,7 @@
Setting up the use of this module.
@ This section simoly sets up the module in ways expected by |foundation|, and
@ This section simoly sets up the module in ways expected by //foundation//, and
contains no code of interest. The following constant exists only in tools
which use this module:

View file

@ -2,7 +2,7 @@
Setting up the use of this module.
@ This section simoly sets up the module in ways expected by |foundation|, and
@ This section simoly sets up the module in ways expected by //foundation//, and
contains no code of interest. The following constant exists only in tools
which use this module:

View file

@ -2,7 +2,7 @@
Setting up the use of this module.
@ This section simoly sets up the module in ways expected by |foundation|, and
@ This section simoly sets up the module in ways expected by //foundation//, and
contains no code of interest. The following constant exists only in tools
which use this module:

View file

@ -2,7 +2,7 @@
Setting up the use of this module.
@ This section simoly sets up the module in ways expected by |foundation|, and
@ This section simoly sets up the module in ways expected by //foundation//, and
contains no code of interest. The following constant exists only in tools
which use this module:

View file

@ -2,7 +2,7 @@
Setting up the use of this module.
@ This section simoly sets up the module in ways expected by |foundation|, and
@ This section simoly sets up the module in ways expected by //foundation//, and
contains no code of interest. The following constant exists only in tools
which use this module:

View file

@ -2,7 +2,7 @@
Setting up the use of this module.
@ This section simoly sets up the module in ways expected by |foundation|, and
@ This section simoly sets up the module in ways expected by //foundation//, and
contains no code of interest. The following constant exists only in tools
which use this module:

View file

@ -2,7 +2,7 @@
Setting up the use of this module.
@ This section simoly sets up the module in ways expected by |foundation|, and
@ This section simoly sets up the module in ways expected by //foundation//, and
contains no code of interest. The following constant exists only in tools
which use this module:

View file

@ -2,7 +2,7 @@
Setting up the use of this module.
@ This section simoly sets up the module in ways expected by |foundation|, and
@ This section simoly sets up the module in ways expected by //foundation//, and
contains no code of interest. The following constant exists only in tools
which use this module:

View file

@ -2,7 +2,7 @@
Setting up the use of this module.
@ This section simoly sets up the module in ways expected by |foundation|, and
@ This section simoly sets up the module in ways expected by //foundation//, and
contains no code of interest. The following constant exists only in tools
which use this module:

View file

@ -3,6 +3,14 @@
To deal with multiple inter architectures.
@h Architectures.
An "architecture" is a choice of how to use Inter code: for example, with the
expectation that it will have 32-bit rather than 16-bit integers. These are
not different Inter formats: two Inter files could, in fact, be identical
and yet one could be intended to be code-generated to a 32-bit program
and another to 16-bit. In effect, an "architecture" holds the settings which
//inform7// uses when turning source text into Inter code.
Each different architecture is represented by one of these:
=
typedef struct inter_architecture {
@ -12,6 +20,7 @@ typedef struct inter_architecture {
CLASS_DEFINITION
} inter_architecture;
@ =
inter_architecture *Architectures::new(text_stream *code, int s, int d) {
inter_architecture *A = CREATE(inter_architecture);
A->shorthand = Str::duplicate(code);
@ -20,6 +29,11 @@ inter_architecture *Architectures::new(text_stream *code, int s, int d) {
return A;
}
@h Standard set.
This is called when the //arch// module starts up; no other architectures
are ever made.
=
void Architectures::create(void) {
Architectures::new(I"16", TRUE, FALSE);
Architectures::new(I"16d", TRUE, TRUE);
@ -27,6 +41,11 @@ void Architectures::create(void) {
Architectures::new(I"32d", FALSE, TRUE);
}
@h Canonical filenames.
When a kit is assimilated, its Inter code is stored in files with these
leafnames:
=
filename *Architectures::canonical_binary(pathname *P, inter_architecture *A) {
if (A == NULL) internal_error("no arch");
TEMPORARY_TEXT(leafname);
@ -45,6 +64,10 @@ filename *Architectures::canonical_textual(pathname *P, inter_architecture *A) {
return F;
}
@h Shorthand.
These functions turn an architecture into a text like |16d| and back again:
=
text_stream *Architectures::to_codename(inter_architecture *A) {
if (A == NULL) return NULL;
return A->shorthand;
@ -58,6 +81,10 @@ inter_architecture *Architectures::from_codename(text_stream *name) {
return NULL;
}
@h What an architecture offers.
At present, this all there is, so in a sense all possible architectures exist:
=
int Architectures::is_16_bit(inter_architecture *A) {
if (A == NULL) internal_error("no arch");
return A->sixteen_bit;

View file

@ -1,17 +1,23 @@
[Compatibility::] Compatibility.
To manage compatibility lists: what can be compiled to what format.
To manage specifications of compatibility with some VMs but not others.
@
@h Specifications.
An object of the following class can represent any subset of VMs, so
it's a fully general way to express which VMs some piece of software works with:
=
typedef struct compatibility_specification {
struct text_stream *parsed_from;
struct text_stream *parsed_from; /* if it came from text */
int default_allows;
struct linked_list *exceptions; /* of |target_vm| */
CLASS_DEFINITION
} compatibility_specification;
@ The creator function for this always begins with a specification meaning
"works with all VMs":
=
compatibility_specification *Compatibility::all(void) {
compatibility_specification *C = CREATE(compatibility_specification);
C->parsed_from = NULL;
@ -20,13 +26,32 @@ compatibility_specification *Compatibility::all(void) {
return C;
}
int Compatibility::universal(compatibility_specification *C) {
if (C == NULL) return FALSE;
if (LinkedLists::len(C->exceptions) > 0) return FALSE;
if (C->default_allows == FALSE) return FALSE;
return TRUE;
@ We can then change this in two ways: one is to reverse the default...
=
void Compatibility::reverse(compatibility_specification *C) {
C->default_allows = (C->default_allows)?FALSE:TRUE;
}
@ ...and the other is to add an exception:
=
int Compatibility::add_exception(compatibility_specification *C, target_vm *VM) {
int already_there = FALSE;
target_vm *X;
LOOP_OVER_LINKED_LIST(X, target_vm, C->exceptions)
if (VM == X)
already_there = TRUE;
if (already_there == FALSE)
ADD_TO_LINKED_LIST(VM, target_vm, C->exceptions);
return already_there;
}
@h Converting to text.
This often produces something verbose; the |parsed_from| text probably reads
better, if available.
=
void Compatibility::write(OUTPUT_STREAM, compatibility_specification *C) {
if (C == NULL) { WRITE("for none"); return; }
int x = LinkedLists::len(C->exceptions);
@ -47,13 +72,47 @@ void Compatibility::write(OUTPUT_STREAM, compatibility_specification *C) {
}
}
@h Converting from text.
This is quite a tricky little parser, which has to read, for example,
text like "for Glulx only" used in Inform extension headings. A syntactically
invalid description returns |NULL| but prints no error message; an empty
description returns the universally valid specification.
A question we might return to is whether an unrecognisable description --
say, "for Marzipan version 28.1 only" -- should return a universally-false
specification rather than returning |NULL|: this would enable current Inform
tools to work with future resources which use VMs currently unthought of.
But for now, it seems best to generate errors, because the more likely thing
is that an extension author is botching the wording of something, or
writing "Z machine" instead of "Z-machine", or something like that.
It might seem better to all of this with a Preform grammar, rather than by
hand. But we want to make it work in tools which don't have Preform available,
and we want it to run quickly.
Unless the text is empty, we start with the "works with nothing" specification
and then add each VM with which |C| does work as an exception.
=
compatibility_specification *Compatibility::from_text(text_stream *text) {
compatibility_specification *C = Compatibility::all();
int incorrect = FALSE;
C->parsed_from = Str::duplicate(text);
if (Str::len(text) == 0) return C;
Compatibility::reverse(C); /* now |C| works with nothing */
int error_in_syntax = FALSE;
match_results mr = Regexp::create_mr();
TEMPORARY_TEXT(parse);
WRITE_TO(parse, "%S", text);
C->parsed_from = Str::duplicate(parse);
@<Remove excess space and/or enclosing brackets and lower in case@>;
@<Actually parse the description@>;
DISCARD_TEXT(parse);
Regexp::dispose_of(&mr);
return (error_in_syntax)?NULL:C;
}
@<Remove excess space and/or enclosing brackets and lower in case@> =
Str::trim_white_space(parse);
if ((Str::get_first_char(parse) == '(') && (Str::get_last_char(parse) == ')')) {
Str::delete_first_character(parse);
@ -63,45 +122,51 @@ compatibility_specification *Compatibility::from_text(text_stream *text) {
LOOP_THROUGH_TEXT(pos, parse)
Str::put(pos, Characters::tolower(Str::get(pos)));
C->default_allows = FALSE;
match_results mr = Regexp::create_mr();
@<Actually parse the description@> =
int negated = FALSE;
@<Parse out the prefix not@>;
@<Remove the meaningless word for@>;
@<Parse out the suffix only@>;
if (Str::eq(parse, I"all")) {
if (negated) error_in_syntax = TRUE; /* "not for all" */
C->default_allows = TRUE;
} else if (Str::eq(parse, I"none")) {
if (negated) error_in_syntax = TRUE; /* "not for none" */
C->default_allows = FALSE;
} else if (Compatibility::parse_specifics(C, parse) == FALSE)
error_in_syntax = TRUE;
@<Parse out the prefix not@> =
if (Regexp::match(&mr, parse, L"not (%c+)")) {
Str::clear(parse);
WRITE_TO(parse, "%S", mr.exp[0]);
Str::trim_white_space(parse);
C->default_allows = TRUE;
Compatibility::reverse(C);
negated = TRUE;
}
@<Remove the meaningless word for@> =
if (Regexp::match(&mr, parse, L"for (%c+)")) {
Str::clear(parse);
WRITE_TO(parse, "%S", mr.exp[0]);
Str::trim_white_space(parse);
}
@<Parse out the suffix only@> =
if (Regexp::match(&mr, parse, L"(%c+) only")) {
Str::clear(parse);
WRITE_TO(parse, "%S", mr.exp[0]);
Str::trim_white_space(parse);
if (negated) incorrect = TRUE; /* "not for 32d only" */
if (negated) error_in_syntax = TRUE; /* "not for 32d only" */
}
if (Str::eq(parse, I"all")) {
if (negated) incorrect = TRUE; /* "not for all" */
C->default_allows = TRUE;
} else if (Str::eq(parse, I"none")) {
if (negated) incorrect = TRUE; /* "not for none" */
C->default_allows = FALSE;
} else if (Compatibility::clause(C, parse) == FALSE)
incorrect = TRUE;
DISCARD_TEXT(parse);
Regexp::dispose_of(&mr);
if (incorrect) C = NULL;
return C;
}
@ The above gets us down from, say, "for Glulx only" to just "Glulx", and
calls the function //Compatibility::parse_specifics// to handle that specific part --
though it may be more complicated. See the //arch-test// unit test for
examples. While parsing those specifics we maintain a state in the following
structure:
=
typedef struct compat_parser_state {
compatibility_specification *C;
text_stream *current_family;
@ -110,14 +175,38 @@ typedef struct compat_parser_state {
int family_used;
} compat_parser_state;
int Compatibility::clause(compatibility_specification *C, text_stream *text) {
int correct = TRUE;
match_results mr = Regexp::create_mr();
compat_parser_state Compatibility::initial_state(compatibility_specification *C) {
compat_parser_state cps;
cps.C = C; cps.version_allowed = FALSE; cps.version_required = FALSE;
cps.current_family = NULL; cps.family_used = FALSE;
return cps;
}
@ So here's the specific details parser, then. We return |TRUE| if no syntax
errors occurred, and we change |C| according to what |text| says.
=
int Compatibility::parse_specifics(compatibility_specification *C, text_stream *text) {
int okay = TRUE;
match_results mr = Regexp::create_mr();
compat_parser_state cps = Compatibility::initial_state(C);
@<Reduce the text to a sequence of tokens@>;
Regexp::dispose_of(&mr);
return okay;
}
@ This is essentially simple -- it splits up text like "Z-machine versions 5 or 8"
into tokens, sending them one at a time to //Compatibility::parse_token//.
Note that commas are converted to the token |or|: e.g., "Z-machine versions 5, 6
or 8" would be treated as "Z-machine versions 5 or 6 or 8"; and note also that
"with debugging" and "without debugging" are handled specially.
We end the sequence of tokens with a |NULL|, telling the token-parser that
it has reached the end.
@<Reduce the text to a sequence of tokens@> =
while (Regexp::match(&mr, text, L"(%C+) (%c+)")) {
int comma = FALSE;
if (Str::get_last_char(mr.exp[0]) == ',') {
@ -125,63 +214,59 @@ int Compatibility::clause(compatibility_specification *C, text_stream *text) {
Str::delete_last_character(mr.exp[0]);
Str::trim_white_space(mr.exp[0]);
}
int with = NOT_APPLICABLE;
match_results mr2 = Regexp::create_mr();
if (Regexp::match(&mr2, mr.exp[1], L"with debugging,* *(%c*)")) {
Str::clear(mr.exp[1]);
Str::copy(mr.exp[1], mr2.exp[0]);
with = TRUE;
} else if (Regexp::match(&mr2, mr.exp[1], L"without debugging,* *(%c*)")) {
Str::clear(mr.exp[1]);
Str::copy(mr.exp[1], mr2.exp[0]);
with = FALSE;
}
Regexp::dispose_of(&mr2);
correct = (correct && Compatibility::word(&cps, mr.exp[0], with));
if (comma) correct = (correct && Compatibility::word(&cps, I"or", with));
int with = Compatibility::parse_debugging(mr.exp[1]);
okay = (okay && Compatibility::parse_token(&cps, mr.exp[0], with));
if (comma) okay = (okay && Compatibility::parse_token(&cps, I"or", with));
Str::clear(text); Str::copy(text, mr.exp[1]);
}
if (Str::len(text) > 0)
correct = (correct && Compatibility::word(&cps, text, NOT_APPLICABLE));
if ((correct) && (cps.family_used == FALSE) && (Str::len(cps.current_family) > 0)) {
target_vm *VM;
LOOP_OVER(VM, target_vm)
if (Str::eq_insensitive(cps.current_family, VM->family_name))
Compatibility::add(C, VM);
}
okay = (okay && Compatibility::parse_token(&cps, text, NOT_APPLICABLE));
okay = (okay && Compatibility::parse_token(&cps, NULL, NOT_APPLICABLE));
@ Returns |TRUE| if the text |T| begins "with debugging", and trims that text
away from |T|; returns |FALSE| if it begins "without debugging", and similarly
trims; and otherwise returns |NOT_APPLICABLE| and leaves |T| unaltered.
=
int Compatibility::parse_debugging(text_stream *T) {
int with = NOT_APPLICABLE;
match_results mr = Regexp::create_mr();
if (Regexp::match(&mr, T, L"with debugging,* *(%c*)")) {
Str::clear(T);
Str::copy(T, mr.exp[0]);
with = TRUE;
} else if (Regexp::match(&mr, T, L"without debugging,* *(%c*)")) {
Str::clear(T);
Str::copy(T, mr.exp[0]);
with = FALSE;
}
Regexp::dispose_of(&mr);
return correct;
return with;
}
int Compatibility::word(compat_parser_state *cps, text_stream *word, int with) {
@ Once again we return |TRUE| if no syntax errors occurred, and we change |C|
according to what the |token| says.
=
int Compatibility::parse_token(compat_parser_state *cps, text_stream *token, int with) {
if (Str::len(token) == 0) @<Construe the token as the end-marker@>;
if (cps->version_allowed) {
semantic_version_number V = VersionNumbers::from_text(word);
semantic_version_number V = VersionNumbers::from_text(token);
if (VersionNumbers::is_null(V)) {
if (cps->version_required) return FALSE;
} else {
if (Str::len(cps->current_family) == 0) return FALSE;
cps->family_used = TRUE;
target_vm *VM;
int seen = FALSE;
LOOP_OVER(VM, target_vm)
if (Str::eq_insensitive(VM->family_name, cps->current_family)) {
seen = TRUE;
if ((VersionNumbers::eq(VM->version, V)) &&
((with == NOT_APPLICABLE) || (TargetVMs::debug_enabled(VM) == with)))
Compatibility::add(cps->C, VM);
}
cps->version_required = FALSE;
return seen;
@<Construe token as a version number@>;
}
}
if (Str::eq_insensitive(word, I"or")) {
if (Str::eq_insensitive(token, I"or")) {
if (with != NOT_APPLICABLE) return FALSE;
return TRUE;
}
if ((Str::eq_insensitive(word, I"version")) ||
(Str::eq_insensitive(word, I"versions"))) {
if ((Str::eq_insensitive(token, I"version")) ||
(Str::eq_insensitive(token, I"versions"))) {
if (with != NOT_APPLICABLE) return FALSE;
cps->version_required = TRUE;
cps->version_allowed = TRUE;
@ -192,54 +277,74 @@ int Compatibility::word(compat_parser_state *cps, text_stream *word, int with) {
cps->version_allowed = FALSE;
int bits = NOT_APPLICABLE;
if (Str::eq_insensitive(word, I"16-bit")) bits = TRUE;
if (Str::eq_insensitive(word, I"32-bit")) bits = FALSE;
if (bits != NOT_APPLICABLE) {
target_vm *VM;
LOOP_OVER(VM, target_vm)
if (TargetVMs::is_16_bit(VM) == bits)
if ((with == NOT_APPLICABLE) || (TargetVMs::debug_enabled(VM) == with))
Compatibility::add(cps->C, VM);
cps->current_family = NULL;
cps->family_used = FALSE;
return TRUE;
}
if (Str::eq_insensitive(token, I"16-bit")) bits = TRUE;
if (Str::eq_insensitive(token, I"32-bit")) bits = FALSE;
if (bits != NOT_APPLICABLE) @<Construe token as a bit count@>;
if (with != NOT_APPLICABLE) {
int seen = FALSE;
target_vm *VM;
LOOP_OVER(VM, target_vm)
if (Str::eq_insensitive(VM->family_name, word)) {
seen = TRUE;
if (TargetVMs::debug_enabled(VM) == with)
Compatibility::add(cps->C, VM);
}
cps->current_family = NULL;
cps->family_used = FALSE;
return seen;
}
if (with != NOT_APPLICABLE) @<Construe token as a family name subject to debugging@>;
@<Construe token as a family name@>;
}
@<Construe token as a version number@> =
cps->family_used = TRUE;
target_vm *VM;
int seen = FALSE;
LOOP_OVER(VM, target_vm)
if (Str::eq_insensitive(VM->family_name, cps->current_family)) {
seen = TRUE;
if ((VersionNumbers::eq(VM->version, V)) &&
((with == NOT_APPLICABLE) || (TargetVMs::debug_enabled(VM) == with)))
Compatibility::add_exception(cps->C, VM);
}
cps->version_required = FALSE;
return seen;
@<Construe token as a bit count@> =
target_vm *VM;
LOOP_OVER(VM, target_vm)
if (Str::eq_insensitive(VM->family_name, word)) {
if (TargetVMs::is_16_bit(VM) == bits)
if ((with == NOT_APPLICABLE) || (TargetVMs::debug_enabled(VM) == with))
Compatibility::add_exception(cps->C, VM);
cps->current_family = NULL;
cps->family_used = FALSE;
return TRUE;
@<Construe token as a family name subject to debugging@> =
int seen = FALSE;
target_vm *VM;
LOOP_OVER(VM, target_vm)
if (Str::eq_insensitive(VM->family_name, token)) {
seen = TRUE;
if (TargetVMs::debug_enabled(VM) == with)
Compatibility::add_exception(cps->C, VM);
}
cps->current_family = NULL;
cps->family_used = FALSE;
return seen;
@<Construe token as a family name@> =
target_vm *VM;
LOOP_OVER(VM, target_vm)
if (Str::eq_insensitive(VM->family_name, token)) {
cps->current_family = VM->family_name;
return TRUE;
}
return FALSE;
}
int Compatibility::add(compatibility_specification *C, target_vm *VM) {
int already_there = FALSE;
target_vm *X;
LOOP_OVER_LINKED_LIST(X, target_vm, C->exceptions)
if (VM == X)
already_there = TRUE;
if (already_there == FALSE)
ADD_TO_LINKED_LIST(VM, target_vm, C->exceptions);
return already_there;
}
@<Construe the token as the end-marker@> =
if ((cps->family_used == FALSE) && (Str::len(cps->current_family) > 0)) {
target_vm *VM;
LOOP_OVER(VM, target_vm)
if (Str::eq_insensitive(cps->current_family, VM->family_name))
Compatibility::add_exception(cps->C, VM);
}
return TRUE;
int Compatibility::with(compatibility_specification *C, target_vm *VM) {
@h Testing.
=
int Compatibility::test(compatibility_specification *C, target_vm *VM) {
if (C == NULL) return FALSE;
int decision = C->default_allows;
target_vm *X;
@ -248,3 +353,10 @@ int Compatibility::with(compatibility_specification *C, target_vm *VM) {
decision = decision?FALSE:TRUE;
return decision;
}
int Compatibility::test_universal(compatibility_specification *C) {
if (C == NULL) return FALSE;
if (LinkedLists::len(C->exceptions) > 0) return FALSE;
if (C->default_allows == FALSE) return FALSE;
return TRUE;
}

View file

@ -1,8 +1,19 @@
[TargetVMs::] Target Virtual Machines.
To deal with multiple inter architectures.
To deal with multiple object code formats.
@h Architectures.
@h Object code.
The end result of compilation is traditionally called "object code" and
people tend to use words like "binary" or even "machine code" about it,
though in fact the world is more diverse nowadays. Inform 7 has always
generated "object code" which is itself a program for a virtual machine;
for example, it makes Glulx bytecode rather than x86 or ARM instructions.
Because of that, we use the customary term "virtual machine" for the format
of the end product of the Inform build process. But it doesn't have to be
virtual. If Inter-to-x86-via-C is properly implemented, we will probably
want to add a VM to represent something like "32-bit binary via ANSI C".
Each different target VM is represented by one of these objects:
=
typedef struct target_vm {
@ -21,6 +32,7 @@ typedef struct target_vm {
CLASS_DEFINITION
} target_vm;
@ =
target_vm *TargetVMs::new(text_stream *code, text_stream *nick, semantic_version_number V,
text_stream *image, text_stream *interpreter, text_stream *blorbed, text_stream *arch,
int debug, int max_locals, text_stream *iFiction) {
@ -42,16 +54,11 @@ target_vm *TargetVMs::new(text_stream *code, text_stream *nick, semantic_version
return VM;
}
void TargetVMs::write(OUTPUT_STREAM, target_vm *VM) {
if (VM == NULL) WRITE("none");
else {
WRITE("%S", VM->family_name);
semantic_version_number V = VM->version;
if (VersionNumbers::is_null(V) == FALSE) WRITE(" version %v", &V);
if (VM->with_debugging_enabled) WRITE(" with debugging");
}
}
@h Standard set.
This is called when the //arch// module starts up; no other architectures
are ever made.
=
void TargetVMs::create(void) {
/* hat tip: Joel Berez and Marc Blank, 1979, and later hands */
TargetVMs::new(I"Z-Machine", I"z5", VersionNumbers::from_text(I"5"),
@ -71,12 +78,32 @@ void TargetVMs::create(void) {
I"vm_glulx.png", I"Quixe", I"gblorb", I"32d", TRUE, 256, I"glulx");
}
@h Describing and finding.
This is the longhand form of the VM name:
=
void TargetVMs::write(OUTPUT_STREAM, target_vm *VM) {
if (VM == NULL) WRITE("none");
else {
WRITE("%S", VM->family_name);
semantic_version_number V = VM->version;
if (VersionNumbers::is_null(V) == FALSE) WRITE(" version %v", &V);
if (VM->with_debugging_enabled) WRITE(" with debugging");
}
}
@ Here we deduce a VM from the given filename extension, which is the rather
clumsy way that VMs are referred to on the //inform7// command line. For
example, |ulx| produces one of the Glulx VMs.
=
target_vm *TargetVMs::find(text_stream *ext, int debug) {
target_vm *result = NULL;
if (Str::len(ext) == 0) ext = I"ulx";
TEMPORARY_TEXT(file_extension);
Str::copy(file_extension, ext);
if (Str::get_first_char(file_extension) == '.') Str::delete_first_character(file_extension);
if (Str::get_first_char(file_extension) == '.')
Str::delete_first_character(file_extension);
LOOP_THROUGH_TEXT(pos, file_extension)
Str::put(pos, Characters::tolower(Str::get(pos)));
target_vm *VM;
@ -88,7 +115,14 @@ target_vm *TargetVMs::find(text_stream *ext, int debug) {
return result;
}
target_vm *TargetVMs::find_in_family(text_stream *family, semantic_version_number V, int debug) {
@ A somewhat sharper method finds specific versions: for example, it can pick
out version 5 rather than version 8 of the Z-machine. Note that the version
numbers must match exactly, and not simply be compatible according to semver
rules.
=
target_vm *TargetVMs::find_in_family(text_stream *family, semantic_version_number V,
int debug) {
target_vm *VM;
LOOP_OVER(VM, target_vm)
if ((Str::eq_insensitive(VM->family_name, family)) &&
@ -98,6 +132,9 @@ target_vm *TargetVMs::find_in_family(text_stream *family, semantic_version_numbe
return NULL;
}
@h Miscellaneous provisions.
=
int TargetVMs::is_16_bit(target_vm *VM) {
if (VM == NULL) internal_error("no VM");
return Architectures::is_16_bit(VM->architecture);
@ -111,8 +148,9 @@ int TargetVMs::supports_floating_point(target_vm *VM) {
return VM->supports_floating_point;
}
@ The limits are different on each platform. On Z, the maximum is fixed
at 15, but Glulx allows it to be set with an I6 memory setting.
@ The limits on local variables per routine are different on each platform.
On Z, the maximum is fixed at 15, but Glulx allows it to be set with an I6
memory setting.
=
int TargetVMs::allow_this_many_locals(target_vm *VM, int N) {
@ -128,8 +166,8 @@ int TargetVMs::allow_MAX_LOCAL_VARIABLES(target_vm *VM) {
@ When releasing a blorbed story file, the file extension depends on the
story file wrapped inside. (This is a dubious idea, in the opinion of
the author of Inform -- should not blorb be one unified wrapper? -- but
interpreter writers disagree.)
the author of Inform -- should not "blorb" be one unified wrapper? -- but
that ship seems to have sailed.)
=
text_stream *TargetVMs::get_unblorbed_extension(target_vm *VM) {
@ -142,6 +180,11 @@ text_stream *TargetVMs::get_blorbed_extension(target_vm *VM) {
return VM->VM_blorbed_extension;
}
@ This is the format name as expressed in an iFiction bibliographic record,
where it's not meaningful to talk about debugging features or the number
of bits, and where it's currently not possible to express a VM version number.
=
text_stream *TargetVMs::get_iFiction_format(target_vm *VM) {
if (VM == NULL) internal_error("no VM");
return VM->iFiction_format_name;
@ -154,7 +197,7 @@ inter_architecture *TargetVMs::get_architecture(target_vm *VM) {
@ Different VMs have different in-browser interpreters, which means that
Inblorb needs to be given different release instructions for them. If the
user doesn't specify any particular interpreter, he gets:
user doesn't specify any particular interpreter, she gets:
=
text_stream *TargetVMs::get_default_interpreter(target_vm *VM) {

View file

@ -4,10 +4,13 @@ Purpose: Definitions of Inter and final VM architectures.
Language: InC
Licence: Artistic License 2.0
Preliminaries
What This Module Does
Chapter 1: Setting Up
Arch Module
Chapter 2: Architectures
Chapter 2: Architectures and VMs
Architectures
Target Virtual Machines
Compatibility

View file

@ -0,0 +1,71 @@
What This Module Does.
An overview of the arch module's role and abilities.
@h Prerequisites.
The arch module is a part of the Inform compiler toolset. It is
presented as a literate program or "web". Before diving in:
(a) It helps to have some experience of reading webs: see //inweb// for more.
(b) The module is written in C, in fact ANSI C99, but this is disguised by the
fact that it uses some extension syntaxes provided by the //inweb// literate
programming tool, making it a dialect of C called InC. See //inweb// for
full details, but essentially: it's C without predeclarations or header files,
and where functions have names like |Tags::add_by_name| rather than |add_by_name|.
(c) This module uses other modules drawn from the //compiler//, and also
uses a module of utility functions called //foundation//.
For more, see //foundation: A Brief Guide to Foundation//.
@h Architecture versus VM.
The Inform 7 build process ultimately wants to make code for some target
virtual machine -- traditionally, the Z or Glulx machines. But it does this
in two stages: first generating abstract Inter code, then further generating
VM code from that.
It's an appealing notion that this first stage might be VM-independent: that
is, that //inform7// could generate the same Inter code regardless of the
final VM, and that only the second stage would vary according to target.
And this is nearly true, but not quite. There are (currently) two reasons
why not:
(a) //inform7// has to generate different code if integers are 16 rather
than 32 bits wide, and
(b) it also generates different code with debugging enabled than without.
Reason (b) could be avoided, at some cost in complexity, but reason (a) is
something we cannot sensibly avoid without making Inter a much higher-level
form of bytecode. Instead, we have "architectures" for Inter: for example,
32-bit with debugging enabled is the |32d| architecture. See //Architectures//;
if ever we introduce a 64-bit VM, that will need new architectures, and
this is where they would go.
@ A //target_vm// object, on the other hand, represents an actual choice of
virtual machine. For example, Glulx is a //target_vm//. The compilation
process thus involves a combination of both architecture and target:
= (text as BoxArt)
Source text -----------> Inter code --------------> Bytecode for
INFORM7 for architecture via INFORM6 target virtual machine
=
Each VM can be used with just one architecture: use the function
//TargetVMs::get_architecture// to obtain this. It might seem reasonable
to say that Glulx ought to be viable with both |32| and |32d| architectures,
but in fact "Glulx" is not a single virtual machine but a family of them.
A specific member of this family would be the //target_vm// representing
Glulx version 3.1.2 with debugging enabled, and that can be used with the
|32d| but not the |32| architecture.
There can in principle be numerous VMs in any given family; see
//TargetVMs::find_in_family// to obtain family members with given behaviour,
and in general see //Target Virtual Machines// for more.
@h Compatibility.
Not all software in the Inform stack -- source text from the user, extensions,
kits of Inter code -- will be compatible with every architecture, or with
every VM. We represent that by giving something a //compatibility_specification//
object to say what it can work with: the function //Compatibility::test//
determines whether any given VM is allowed with this specification.
A specification can be converted to or from text: see //Compatibility::write//
and //Compatibility::from_text//. Typically, such text might read "for 32d only".
Lastly, //Compatibility::all// returns a specification meaning "works with
anything". This should be the default; //Compatibility::test_universal// tests
whether a specification is equivalent to this.

View file

@ -35,7 +35,7 @@ void Unit::test_one(OUTPUT_STREAM, text_stream *test) {
WRITE(":\n"); INDENT;
target_vm *VM;
LOOP_OVER(VM, target_vm) {
if (Compatibility::with(C, VM)) {
if (Compatibility::test(C, VM)) {
TargetVMs::write(OUT, VM);
WRITE("\n");
}

View file

@ -2,7 +2,7 @@
Setting up the use of this module.
@ This section simoly sets up the module in ways expected by |foundation|, and
@ This section simoly sets up the module in ways expected by //foundation//, and
contains no code of interest. The following constant exists only in tools
which use this module:

View file

@ -2,7 +2,7 @@
Setting up the use of this module.
@ This section simoly sets up the module in ways expected by |foundation|, and
@ This section simoly sets up the module in ways expected by //foundation//, and
contains no code of interest. The following constant exists only in tools
which use this module:

View file

@ -2,7 +2,7 @@
Setting up the use of this module.
@ This section simoly sets up the module in ways expected by |foundation|, and
@ This section simoly sets up the module in ways expected by //foundation//, and
contains no code of interest. The following constant exists only in tools
which use this module: