1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-16 22:14:23 +03:00
inform7/docs/words-module/3-wrd.html

719 lines
93 KiB
HTML
Raw Normal View History

2019-03-17 14:40:57 +02:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>3/lxr</title>
2020-03-19 02:11:25 +02:00
<meta name="viewport" content="width=device-width initial-scale=1">
2019-03-17 14:40:57 +02:00
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
2020-03-19 02:11:25 +02:00
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
2019-03-17 14:40:57 +02:00
</head>
<body>
2020-03-19 02:11:25 +02:00
<nav role="navigation">
<h1><a href="../webs.html">Sources</a></h1>
<ul>
<li><a href="../compiler.html"><b>compiler tools</b></a></li>
2020-03-19 02:11:25 +02:00
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul>
<h2>Compiler Webs</h2>
<ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
</ul>
<h2>Inbuild Modules</h2>
<ul>
<li><a href="../inbuild-module/index.html">inbuild</a></li>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../html-module/index.html">html</a></li>
</ul>
<h2>Inform7 Modules</h2>
<ul>
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="../index-module/index.html">index</a></li>
</ul>
<h2>Inter Modules</h2>
<ul>
<li><a href="../inter-module/index.html">inter</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul>
<h2>Foundation</h2>
<ul>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
2019-03-17 14:40:57 +02:00
<!--Weave of '3/wrd' generated by 7-->
2020-03-22 12:50:19 +02:00
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Modules</a></li><li><a href="index.html">words</a></li><li><a href="index.html#3">Chapter 3: Words in Sequence</a></li><li><b>Wordings</b></li></ul><p class="purpose">To manage contiguous word ranges.</p>
2019-03-17 14:40:57 +02:00
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li><li><a href="#SP6">&#167;6. Construction</a></li><li><a href="#SP8">&#167;8. Reading</a></li><li><a href="#SP9">&#167;9. Manipulation</a></li><li><a href="#SP10">&#167;10. Widening</a></li><li><a href="#SP11">&#167;11. Position</a></li><li><a href="#SP12">&#167;12. Emptiness</a></li><li><a href="#SP13">&#167;13. Comparing wordings</a></li><li><a href="#SP18">&#167;18. Bracketing</a></li><li><a href="#SP21">&#167;21. Searching for unusual spacing in ranges</a></li><li><a href="#SP22">&#167;22. The Writer</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Wordings are an efficient representation of a multi-word name for
something, using the fact that almost all names derive from contiguous
runs of words in the source text.
</p>
<p class="inwebparagraph">Recall that words are numbered from 0 upwards in order of reading into
the lexer. The wording <code class="display"><span class="extract">Wordings::new(A, B)</span></code> represents both a positional
marker, at word number <code class="display"><span class="extract">A</span></code>, and also some textual content, the text making
up words <code class="display"><span class="extract">A</span></code> to <code class="display"><span class="extract">B</span></code> inclusive. Different wordings can represent the
same text at different positions in the source text, for example if
"brown spotted owl" occurs multiple times.
</p>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">wording</span><span class="plain"> {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">word_A</span><span class="plain">, </span><span class="identifier">word_B</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">wording</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure wording is private to this section.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Note that this applies even to the empty text. A wording holds no text
if both <code class="display"><span class="extract">A</span></code> and <code class="display"><span class="extract">B</span></code> are negative, or if <code class="display"><span class="extract">A</span></code> is larger than <code class="display"><span class="extract">B</span></code>. Thus
the wording <code class="display"><span class="extract">(17, 16)</span></code> represents the empty text at position 17. (Preform
makes use of this when parsing nonterminals which match conditionally
but consume no text, for example.) When we are representing no text and
no position either, we should use the following constant wording:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">EMPTY_WORDING</span><span class="plain"> ((</span><span class="reserved">wording</span><span class="plain">) { -1, -1 })</span>
</pre>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>Annoyingly, <code class="display"><span class="extract">gcc</span></code> (though not <code class="display"><span class="extract">clang</span></code>) rejects this as an initializer, so
we also need:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">EMPTY_WORDING_INIT</span><span class="plain"> { -1, -1 }</span>
</pre>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>We will frequently want to loop through the words in a wording, so
the following macro is convenient. Note that the loop body is not executed
if the wording is empty.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="identifier">LOOP_THROUGH_WORDING</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">)</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">)</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=</span><span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">&lt;=</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Construction. </b></p>
<pre class="display">
<span class="reserved">wording</span><span class="plain"> </span><span class="functiontext">Wordings::new</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">A</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">B</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> (</span><span class="reserved">wording</span><span class="plain">) { </span><span class="identifier">A</span><span class="plain">, </span><span class="identifier">B</span><span class="plain"> };</span>
<span class="plain">}</span>
<span class="reserved">wording</span><span class="plain"> </span><span class="functiontext">Wordings::one_word</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">A</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> (</span><span class="reserved">wording</span><span class="plain">) { </span><span class="identifier">A</span><span class="plain">, </span><span class="identifier">A</span><span class="plain"> };</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
2020-03-11 02:21:09 +02:00
<p class="endnote">The function Wordings::new is used in <a href="#SP10">&#167;10</a>, 3/lxr (<a href="3-lxr.html#SP24">&#167;24</a>, <a href="3-lxr.html#SP24_3">&#167;24.3</a>, <a href="3-lxr.html#SP28">&#167;28</a>), 3/fds (<a href="3-fds.html#SP3">&#167;3</a>), 4/prf (<a href="4-prf.html#SP26_3">&#167;26.3</a>, <a href="4-prf.html#SP50_2_1_2">&#167;50.2.1.2</a>, <a href="4-prf.html#SP50_2_1_2_3_3_5">&#167;50.2.1.2.3.3.5</a>, <a href="4-prf.html#SP50_2_1_2_3_3_3_1">&#167;50.2.1.2.3.3.3.1</a>, <a href="4-prf.html#SP51">&#167;51</a>).</p>
2019-03-17 14:40:57 +02:00
2020-03-11 02:21:09 +02:00
<p class="endnote">The function Wordings::one_word is used in 4/prf (<a href="4-prf.html#SP26">&#167;26</a>, <a href="4-prf.html#SP26_1">&#167;26.1</a>, <a href="4-prf.html#SP29">&#167;29</a>, <a href="4-prf.html#SP50_2_1_2_3_3">&#167;50.2.1.2.3.3</a>).</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>Note that these two are sometimes used to construct empty wordings either
by moving <code class="display"><span class="extract">A</span></code> past <code class="display"><span class="extract">B</span></code>, or moving <code class="display"><span class="extract">B</span></code> before <code class="display"><span class="extract">A</span></code>.
</p>
<pre class="display">
<span class="reserved">wording</span><span class="plain"> </span><span class="functiontext">Wordings::up_to</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">last_wn</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Wordings::empty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">;</span>
<span class="identifier">W</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain"> = </span><span class="identifier">last_wn</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">wording</span><span class="plain"> </span><span class="functiontext">Wordings::from</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">first_wn</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Wordings::empty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain"> = </span><span class="identifier">first_wn</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
2020-03-11 02:21:09 +02:00
<p class="endnote">The function Wordings::up_to is used in 4/prf (<a href="4-prf.html#SP50_2_1_2_3_3">&#167;50.2.1.2.3.3</a>).</p>
2019-03-17 14:40:57 +02:00
<p class="endnote">The function Wordings::from is used in 2/wa (<a href="2-wa.html#SP11">&#167;11</a>).</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Reading. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Wordings::length</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Wordings::empty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain"> - </span><span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain"> + </span><span class="constant">1</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Wordings::phrasual_length</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Wordings::empty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">bl</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">n</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">LOOP_THROUGH_WORDING</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">OPENBRACKET_V</span><span class="plain">) || (</span><span class="functiontext">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">OPENBRACE_V</span><span class="plain">)) </span><span class="identifier">bl</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">CLOSEBRACKET_V</span><span class="plain">) || (</span><span class="functiontext">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">CLOSEBRACE_V</span><span class="plain">)) </span><span class="identifier">bl</span><span class="plain">--;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bl</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">n</span><span class="plain">++;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">n</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Wordings::first_wn</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Wordings::last_wn</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
2020-03-11 02:21:09 +02:00
<p class="endnote">The function Wordings::length is used in <a href="#SP9">&#167;9</a>, <a href="#SP14">&#167;14</a>, <a href="#SP21">&#167;21</a>, 2/wa (<a href="2-wa.html#SP4">&#167;4</a>, <a href="2-wa.html#SP10">&#167;10</a>, <a href="2-wa.html#SP11">&#167;11</a>), 3/lxr (<a href="3-lxr.html#SP28">&#167;28</a>), 4/prf (<a href="4-prf.html#SP29_2">&#167;29.2</a>, <a href="4-prf.html#SP35">&#167;35</a>, <a href="4-prf.html#SP50">&#167;50</a>, <a href="4-prf.html#SP50_2_1">&#167;50.2.1</a>).</p>
2019-03-17 14:40:57 +02:00
<p class="endnote">The function Wordings::phrasual_length appears nowhere else.</p>
2020-03-11 02:21:09 +02:00
<p class="endnote">The function Wordings::first_wn is used in <a href="#SP18">&#167;18</a>, <a href="#SP21">&#167;21</a>, <a href="#SP22_3">&#167;22.3</a>, <a href="#SP22_4">&#167;22.4</a>, 2/vcb (<a href="2-vcb.html#SP17">&#167;17</a>), 2/wa (<a href="2-wa.html#SP9">&#167;9</a>, <a href="2-wa.html#SP10">&#167;10</a>, <a href="2-wa.html#SP11">&#167;11</a>), 3/lxr (<a href="3-lxr.html#SP24">&#167;24</a>, <a href="3-lxr.html#SP28">&#167;28</a>), 4/prf (<a href="4-prf.html#SP21">&#167;21</a>, <a href="4-prf.html#SP26">&#167;26</a>, <a href="4-prf.html#SP29_2">&#167;29.2</a>, <a href="4-prf.html#SP34">&#167;34</a>, <a href="4-prf.html#SP35">&#167;35</a>, <a href="4-prf.html#SP50_2">&#167;50.2</a>, <a href="4-prf.html#SP50_2_1_2_2">&#167;50.2.1.2.2</a>, <a href="4-prf.html#SP50_2_1_2_3_1">&#167;50.2.1.2.3.1</a>, <a href="4-prf.html#SP50_2_1_2_3_3">&#167;50.2.1.2.3.3</a>, <a href="4-prf.html#SP50_2_1_2_3_3_3_1">&#167;50.2.1.2.3.3.3.1</a>), 4/bn (<a href="4-bn.html#SP1">&#167;1</a>, <a href="4-bn.html#SP2">&#167;2</a>, <a href="4-bn.html#SP5">&#167;5</a>, <a href="4-bn.html#SP6">&#167;6</a>, <a href="4-bn.html#SP7">&#167;7</a>).</p>
2019-03-17 14:40:57 +02:00
2020-03-11 02:21:09 +02:00
<p class="endnote">The function Wordings::last_wn is used in <a href="#SP18">&#167;18</a>, <a href="#SP21">&#167;21</a>, <a href="#SP22_1">&#167;22.1</a>, <a href="#SP22_2">&#167;22.2</a>, 2/wa (<a href="2-wa.html#SP11">&#167;11</a>), 3/tff (<a href="3-tff.html#SP5">&#167;5</a>), 4/prf (<a href="4-prf.html#SP26">&#167;26</a>, <a href="4-prf.html#SP26_3">&#167;26.3</a>, <a href="4-prf.html#SP28_1_1">&#167;28.1.1</a>, <a href="4-prf.html#SP28_1_3">&#167;28.1.3</a>, <a href="4-prf.html#SP50_2_1_2_2">&#167;50.2.1.2.2</a>, <a href="4-prf.html#SP50_2_1_2_3_3">&#167;50.2.1.2.3.3</a>, <a href="4-prf.html#SP50_2_1_2_3_3_3">&#167;50.2.1.2.3.3.3</a>, <a href="4-prf.html#SP50_2_1_2_3_3_5">&#167;50.2.1.2.3.3.5</a>, <a href="4-prf.html#SP50_2_1_2_3_3_3_1">&#167;50.2.1.2.3.3.3.1</a>, <a href="4-prf.html#SP51">&#167;51</a>).</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Manipulation. </b>Unlike the construction routines above, these never make positional empty
wordings.
</p>
<pre class="display">
<span class="reserved">wording</span><span class="plain"> </span><span class="functiontext">Wordings::truncate</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">max</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Wordings::length</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">) &gt; </span><span class="identifier">max</span><span class="plain">) </span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain"> + </span><span class="identifier">max</span><span class="plain"> - </span><span class="constant">1</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">wording</span><span class="plain"> </span><span class="functiontext">Wordings::first_word</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Wordings::empty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">EMPTY_WORDING</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">W</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">wording</span><span class="plain"> </span><span class="functiontext">Wordings::last_word</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Wordings::empty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">EMPTY_WORDING</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">wording</span><span class="plain"> </span><span class="functiontext">Wordings::trim_first_word</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Wordings::empty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">EMPTY_WORDING</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain"> &gt; </span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">EMPTY_WORDING</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">wording</span><span class="plain"> </span><span class="functiontext">Wordings::trim_last_word</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Wordings::empty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">EMPTY_WORDING</span><span class="plain">;</span>
<span class="identifier">W</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">--;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain"> &gt; </span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">EMPTY_WORDING</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">wording</span><span class="plain"> </span><span class="functiontext">Wordings::trim_both_ends</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Wordings::empty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">EMPTY_WORDING</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">++; </span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">--;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain"> &gt; </span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">EMPTY_WORDING</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Wordings::truncate appears nowhere else.</p>
<p class="endnote">The function Wordings::first_word appears nowhere else.</p>
<p class="endnote">The function Wordings::last_word appears nowhere else.</p>
2020-03-11 02:21:09 +02:00
<p class="endnote">The function Wordings::trim_first_word is used in 4/prf (<a href="4-prf.html#SP29_2">&#167;29.2</a>).</p>
2019-03-17 14:40:57 +02:00
<p class="endnote">The function Wordings::trim_last_word appears nowhere else.</p>
<p class="endnote">The function Wordings::trim_both_ends is used in <a href="#SP18">&#167;18</a>.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. Widening. </b></p>
<pre class="display">
<span class="reserved">wording</span><span class="plain"> </span><span class="functiontext">Wordings::union</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W1</span><span class="plain">, </span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W2</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Wordings::empty</span><span class="plain">(</span><span class="identifier">W1</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">W2</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Wordings::empty</span><span class="plain">(</span><span class="identifier">W2</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">W1</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">w1</span><span class="plain"> = </span><span class="identifier">W1</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">; </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">w1</span><span class="plain"> &gt; </span><span class="identifier">W2</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">) </span><span class="identifier">w1</span><span class="plain"> = </span><span class="identifier">W2</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">; </span><span class="comment">the min</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">w2</span><span class="plain"> = </span><span class="identifier">W1</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">; </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">w2</span><span class="plain"> &lt; </span><span class="identifier">W2</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">) </span><span class="identifier">w2</span><span class="plain"> = </span><span class="identifier">W2</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">; </span><span class="comment">the max</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Wordings::new</span><span class="plain">(</span><span class="identifier">w1</span><span class="plain">, </span><span class="identifier">w2</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Wordings::union appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. Position. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Wordings::within</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">SMALL</span><span class="plain">, </span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">BIG</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">SMALL</span><span class="plain">)) &amp;&amp; (</span><span class="functiontext">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">BIG</span><span class="plain">)) &amp;&amp;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">(</span><span class="identifier">SMALL</span><span class="plain">.</span><span class="element">word_A</span><span class="plain"> &gt;= </span><span class="identifier">BIG</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">) &amp;&amp; (</span><span class="identifier">SMALL</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain"> &lt;= </span><span class="identifier">BIG</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">))</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">source_location</span><span class="plain"> </span><span class="functiontext">Wordings::location</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Lexer::word_location</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Wordings::within appears nowhere else.</p>
<p class="endnote">The function Wordings::location appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. Emptiness. </b>See above.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Wordings::empty</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain"> &gt;= </span><span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Wordings::nonempty</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain"> &gt;= </span><span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
2020-03-11 02:21:09 +02:00
<p class="endnote">The function Wordings::empty is used in <a href="#SP7">&#167;7</a>, <a href="#SP8">&#167;8</a>, <a href="#SP9">&#167;9</a>, <a href="#SP10">&#167;10</a>, <a href="#SP21">&#167;21</a>, <a href="#SP22_3">&#167;22.3</a>, 2/vcb (<a href="2-vcb.html#SP17">&#167;17</a>), 2/wa (<a href="2-wa.html#SP4">&#167;4</a>, <a href="2-wa.html#SP10">&#167;10</a>), 4/prf (<a href="4-prf.html#SP50_2">&#167;50.2</a>).</p>
2019-03-17 14:40:57 +02:00
2020-03-11 02:21:09 +02:00
<p class="endnote">The function Wordings::nonempty is used in <a href="#SP11">&#167;11</a>, <a href="#SP14">&#167;14</a>, 2/wa (<a href="2-wa.html#SP11">&#167;11</a>), 3/idn (<a href="3-idn.html#SP3">&#167;3</a>), 4/prf (<a href="4-prf.html#SP17">&#167;17</a>, <a href="4-prf.html#SP29_2">&#167;29.2</a>), 4/bn (<a href="4-bn.html#SP6">&#167;6</a>, <a href="4-bn.html#SP7">&#167;7</a>).</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. Comparing wordings. </b>First, though it's little needed, literal equality: two wordings are the
same only if they represent the same word numbers in the source.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Wordings::eq</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W1</span><span class="plain">, </span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W2</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">W1</span><span class="plain">.</span><span class="element">word_A</span><span class="plain"> == </span><span class="identifier">W2</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">) &amp;&amp; (</span><span class="identifier">W1</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain"> == </span><span class="identifier">W2</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">))</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Wordings::eq appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. </b>Two wordings are said to "match" if they are nonempty and contain the same text.
</p>
<p class="inwebparagraph">The calculation overhead makes it marginally not worth using a hash function
to speed up the following comparison, which requires two excerpts to be
absolutely equal.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Wordings::match</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W1</span><span class="plain">, </span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W2</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">W1</span><span class="plain">.</span><span class="element">word_A</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">W1</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Wordings::match_inner</span><span class="plain">(</span><span class="identifier">W1</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">, </span><span class="identifier">W1</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">, </span><span class="identifier">W2</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">, </span><span class="identifier">W2</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">)))</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Wordings::starts_with</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">S</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) &amp;&amp; (</span><span class="functiontext">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Wordings::length</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">) &gt;= </span><span class="functiontext">Wordings::length</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">)) &amp;&amp;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">(</span><span class="functiontext">Wordings::match_inner</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">.</span><span class="element">word_A</span><span class="plain"> + </span><span class="identifier">S</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain"> - </span><span class="identifier">S</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">)))</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Wordings::match_inner</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">w1</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">w2</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">w3</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">w4</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">w4</span><span class="plain">-</span><span class="identifier">w3</span><span class="plain"> != </span><span class="identifier">w2</span><span class="plain">-</span><span class="identifier">w1</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">w1</span><span class="plain">&lt;0) || (</span><span class="identifier">w3</span><span class="plain">&lt;0)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain">&lt;=</span><span class="identifier">w2</span><span class="plain">-</span><span class="identifier">w1</span><span class="plain">; </span><span class="identifier">j</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">compare_words</span><span class="plain">(</span><span class="identifier">w1</span><span class="plain">+</span><span class="identifier">j</span><span class="plain">, </span><span class="identifier">w3</span><span class="plain">+</span><span class="identifier">j</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Wordings::match appears nowhere else.</p>
<p class="endnote">The function Wordings::starts_with is used in 2/wa (<a href="2-wa.html#SP11">&#167;11</a>).</p>
<p class="endnote">The function Wordings::match_inner appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. </b>Case sensitively:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Wordings::match_cs</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W1</span><span class="plain">, </span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W2</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">W1</span><span class="plain">.</span><span class="element">word_A</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">W1</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Wordings::match_cs_inner</span><span class="plain">(</span><span class="identifier">W1</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">, </span><span class="identifier">W1</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">, </span><span class="identifier">W2</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">, </span><span class="identifier">W2</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">)))</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Wordings::match_cs_inner</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">w1</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">w2</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">w3</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">w4</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">w4</span><span class="plain">-</span><span class="identifier">w3</span><span class="plain"> != </span><span class="identifier">w2</span><span class="plain">-</span><span class="identifier">w1</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">w1</span><span class="plain">&lt;0) || (</span><span class="identifier">w3</span><span class="plain">&lt;0)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain">&lt;=</span><span class="identifier">w2</span><span class="plain">-</span><span class="identifier">w1</span><span class="plain">; </span><span class="identifier">j</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">compare_words_cs</span><span class="plain">(</span><span class="identifier">w1</span><span class="plain">+</span><span class="identifier">j</span><span class="plain">, </span><span class="identifier">w3</span><span class="plain">+</span><span class="identifier">j</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Wordings::match_cs appears nowhere else.</p>
<p class="endnote">The function Wordings::match_cs_inner appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. </b>This alternative form is slower, but gets the case where one of the words
holds double-quoted text correctly. (We don't need this often because quoted
text is in general not allowed in identifier names.)
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Wordings::match_perhaps_quoted</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W1</span><span class="plain">, </span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W2</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">w1</span><span class="plain"> = </span><span class="identifier">W1</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">, </span><span class="identifier">w2</span><span class="plain"> = </span><span class="identifier">W1</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">, </span><span class="identifier">w3</span><span class="plain"> = </span><span class="identifier">W2</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">, </span><span class="identifier">w4</span><span class="plain"> = </span><span class="identifier">W2</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">w4</span><span class="plain">-</span><span class="identifier">w3</span><span class="plain"> != </span><span class="identifier">w2</span><span class="plain">-</span><span class="identifier">w1</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">w1</span><span class="plain">&lt;0) || (</span><span class="identifier">w3</span><span class="plain">&lt;0)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain">&lt;=</span><span class="identifier">w2</span><span class="plain">-</span><span class="identifier">w1</span><span class="plain">; </span><span class="identifier">j</span><span class="plain">++) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">compare_words</span><span class="plain">(</span><span class="identifier">w1</span><span class="plain">+</span><span class="identifier">j</span><span class="plain">, </span><span class="identifier">w3</span><span class="plain">+</span><span class="identifier">j</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Vocabulary::test_flags</span><span class="plain">(</span><span class="identifier">w1</span><span class="plain">+</span><span class="identifier">j</span><span class="plain">, (</span><span class="constant">TEXT_MC</span><span class="plain">+</span><span class="constant">TEXTWITHSUBS_MC</span><span class="plain">))) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Vocabulary::test_flags</span><span class="plain">(</span><span class="identifier">w3</span><span class="plain">+</span><span class="identifier">j</span><span class="plain">, (</span><span class="constant">TEXT_MC</span><span class="plain">+</span><span class="constant">TEXTWITHSUBS_MC</span><span class="plain">))) &amp;&amp;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">(</span><span class="identifier">Wide::cmp</span><span class="plain">(</span><span class="functiontext">Lexer::word_raw_text</span><span class="plain">(</span><span class="identifier">w1</span><span class="plain">+</span><span class="identifier">j</span><span class="plain">), </span><span class="functiontext">Lexer::word_raw_text</span><span class="plain">(</span><span class="identifier">w3</span><span class="plain">+</span><span class="identifier">j</span><span class="plain">)) == </span><span class="constant">0</span><span class="plain">))</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">continue</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Wordings::match_perhaps_quoted appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. </b>And relatedly, used for sorting into alphabetical order, a direct analogue
of <code class="display"><span class="extract">strcmp</span></code> but for word ranges:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Wordings::strcmp</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">X</span><span class="plain">, </span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">Y</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">x1</span><span class="plain"> = </span><span class="identifier">X</span><span class="plain">.</span><span class="identifier">word_A</span><span class="plain">, </span><span class="identifier">x2</span><span class="plain"> = </span><span class="identifier">X</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">, </span><span class="identifier">y1</span><span class="plain"> = </span><span class="identifier">Y</span><span class="plain">.</span><span class="element">word_A</span><span class="plain">, </span><span class="identifier">y2</span><span class="plain"> = </span><span class="identifier">Y</span><span class="plain">.</span><span class="identifier">word_B</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">x1</span><span class="plain"> &lt; </span><span class="constant">0</span><span class="plain">) { </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">y1</span><span class="plain"> &lt; </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> -1; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">y1</span><span class="plain"> &lt; </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">n</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">l1</span><span class="plain"> = </span><span class="identifier">x2</span><span class="plain"> - </span><span class="identifier">x1</span><span class="plain"> + </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">l2</span><span class="plain"> = </span><span class="identifier">y2</span><span class="plain"> - </span><span class="identifier">y1</span><span class="plain"> + </span><span class="constant">1</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">n</span><span class="plain">=0; (</span><span class="identifier">n</span><span class="plain">&lt;</span><span class="identifier">l1</span><span class="plain">) &amp;&amp; (</span><span class="identifier">n</span><span class="plain">&lt;</span><span class="identifier">l2</span><span class="plain">); </span><span class="identifier">n</span><span class="plain">++) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">delta</span><span class="plain"> = </span><span class="identifier">Wide::cmp</span><span class="plain">(</span><span class="functiontext">Lexer::word_text</span><span class="plain">(</span><span class="identifier">x1</span><span class="plain"> + </span><span class="identifier">n</span><span class="plain">), </span><span class="functiontext">Lexer::word_text</span><span class="plain">(</span><span class="identifier">y1</span><span class="plain"> + </span><span class="identifier">n</span><span class="plain">));</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">delta</span><span class="plain"> != </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">delta</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">l1</span><span class="plain"> - </span><span class="identifier">l2</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Wordings::strcmp appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. Bracketing. </b>We are going to need to look for paired brackets at the outside of an
excerpt reasonably quickly, and the following routine performs that test.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Wordings::paired_brackets</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Lexer::word</span><span class="plain">(</span><span class="functiontext">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) == </span><span class="identifier">OPENBRACKET_V</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Lexer::word</span><span class="plain">(</span><span class="functiontext">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) == </span><span class="identifier">CLOSEBRACKET_V</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Wordings::mismatched_brackets</span><span class="plain">(</span><span class="functiontext">Wordings::trim_both_ends</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) == </span><span class="identifier">FALSE</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
2020-03-11 02:21:09 +02:00
<p class="endnote">The function Wordings::paired_brackets is used in 4/prf (<a href="4-prf.html#SP50_2_1_2">&#167;50.2.1.2</a>).</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. </b>For problem detection:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Wordings::mismatched_brackets</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">bl</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">LOOP_THROUGH_WORDING</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">OPENBRACKET_V</span><span class="plain">) || (</span><span class="functiontext">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">OPENBRACE_V</span><span class="plain">)) </span><span class="identifier">bl</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">CLOSEBRACKET_V</span><span class="plain">) || (</span><span class="functiontext">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">CLOSEBRACE_V</span><span class="plain">)) </span><span class="identifier">bl</span><span class="plain">--;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bl</span><span class="plain"> &lt; </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">bl</span><span class="plain"> != </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Wordings::mismatched_brackets is used in <a href="#SP18">&#167;18</a>.</p>
<p class="inwebparagraph"><a id="SP20"></a><b>&#167;20. </b>For syntax disambiguation:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Wordings::top_level_comma</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">bl</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">LOOP_THROUGH_WORDING</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">OPENBRACKET_V</span><span class="plain">) || (</span><span class="functiontext">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">OPENBRACE_V</span><span class="plain">)) </span><span class="identifier">bl</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">CLOSEBRACKET_V</span><span class="plain">) || (</span><span class="functiontext">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">CLOSEBRACE_V</span><span class="plain">)) </span><span class="identifier">bl</span><span class="plain">--;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">bl</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Lexer::word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="identifier">COMMA_V</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Wordings::top_level_comma appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP21"></a><b>&#167;21. Searching for unusual spacing in ranges. </b>Looking forward to see how far the current column or row extends,
for formatted tables. The idea is that we have a range <code class="display"><span class="extract">w1</span></code> to <code class="display"><span class="extract">w2</span></code>,
and that the current column or row extends from <code class="display"><span class="extract">w1</span></code> but may run only
part-way through: we look for the first point at which there is a
tab break (for column scanning) or a newline break (for row scanning),
and return the word position just before that break. If we do not find
one, it follows that the entire range holds the current column or row,
and we return <code class="display"><span class="extract">w2</span></code>.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Wordings::last_word_of_formatted_text</span><span class="plain">(</span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">tab_flag</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Wordings::empty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> -1;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Wordings::length</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">) == </span><span class="constant">1</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">LOOP_THROUGH_WORDING</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> &gt; </span><span class="functiontext">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">))</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (((</span><span class="identifier">tab_flag</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Lexer::break_before</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="character">'\t'</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="functiontext">Lexer::indentation_level</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="functiontext">Lexer::break_before</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">) == </span><span class="character">'\n'</span><span class="plain">))</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">-1;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Wordings::last_word_of_formatted_text appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP22"></a><b>&#167;22. The Writer. </b>The following implements the <code class="display"><span class="extract">%W</span></code> escape, which comes in four varieties:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Wordings::writer</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">format_string</span><span class="plain">, </span><span class="reserved">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">format_string</span><span class="plain">[0]) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">case</span><span class="plain"> </span><span class="character">'W'</span><span class="plain">: </span><span class="comment">bare <code class="display"><span class="extract">%W</span></code> means the same as <code class="display"><span class="extract">%-W</span></code>, so fall through to...</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">case</span><span class="plain"> </span><span class="character">'-'</span><span class="plain">: </span>&lt;<span class="cwebmacro">Write the stream with normalised casing</span> <span class="cwebmacronumber">22.1</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'+'</span><span class="plain">: </span>&lt;<span class="cwebmacro">Write the stream raw</span> <span class="cwebmacronumber">22.2</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'&lt;'</span><span class="plain">: </span>&lt;<span class="cwebmacro">Write the stream in an abbreviated raw form</span> <span class="cwebmacronumber">22.3</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'~'</span><span class="plain">: </span>&lt;<span class="cwebmacro">Write the stream in a raw form suitable for use in an I6 literal string</span> <span class="cwebmacronumber">22.4</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">default:</span><span class="plain"> </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"bad %W modifier"</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Wordings::writer is used in 1/wm (<a href="1-wm.html#SP3_2">&#167;3.2</a>).</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP22_1"></a><b>&#167;22.1. </b>Note that the empty wording causes nothing to be written to the stream.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Write the stream with normalised casing</span> <span class="cwebmacronumber">22.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">LOOP_THROUGH_WORDING</span><span class="plain">(</span><span class="identifier">j</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%N"</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">&lt;</span><span class="functiontext">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" "</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP22">&#167;22</a>.</p>
<p class="inwebparagraph"><a id="SP22_2"></a><b>&#167;22.2. </b>Raw, in this context, means that it retains its original case, but not that
it retains its original spacing. This is sometimes problematic: we need to
go to some trouble to make punctuation look reasonably nice again, to obtain,
say,
</p>
<blockquote>
<p>The auctioneer said: "I'm not through yet -".</p>
</blockquote>
<p class="inwebparagraph">in preference to:
</p>
<blockquote>
<p>The auctioneer said : "I'm not through yet -" .</p>
</blockquote>
<p class="inwebparagraph">Note that we are not actually preserving the spacing in the original source &mdash;
that might have line breaks or other curiosities which we don't want: we are
instead imposing what we think are normal English conventions. While this
will sometimes be wrong, this is only likely to affect the index and problem
messages, so the user is not likely to be bothered.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Write the stream raw</span> <span class="cwebmacronumber">22.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">LOOP_THROUGH_WORDING</span><span class="plain">(</span><span class="identifier">j</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%&lt;N"</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">space</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">&lt;</span><span class="functiontext">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) {</span>
<span class="identifier">space</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">compare_word</span><span class="plain">(</span><span class="identifier">j</span><span class="plain">+1, </span><span class="identifier">COMMA_V</span><span class="plain">)) </span><span class="identifier">space</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">compare_word</span><span class="plain">(</span><span class="identifier">j</span><span class="plain">+1, </span><span class="identifier">COLON_V</span><span class="plain">)) </span><span class="identifier">space</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">compare_word</span><span class="plain">(</span><span class="identifier">j</span><span class="plain">+1, </span><span class="identifier">CLOSEBRACKET_V</span><span class="plain">)) </span><span class="identifier">space</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">compare_word</span><span class="plain">(</span><span class="identifier">j</span><span class="plain">, </span><span class="identifier">OPENBRACKET_V</span><span class="plain">)) </span><span class="identifier">space</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">space</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" "</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP22">&#167;22</a>.</p>
<p class="inwebparagraph"><a id="SP22_3"></a><b>&#167;22.3. </b>A variation on this tries to contain unreasonably long pastes of quoted
literals, and is used in printing out problem messages, where quoting
back the offending source text might make unhelpfully vast paragraphs
in which the actual information is more or less hidden.
</p>
<pre class="definitions">
2020-04-07 03:06:09 +03:00
<span class="definitionkeyword">define</span> <span class="constant">STRING_TOLERANCE_LIMIT</span><span class="plain"> </span><span class="constant">70</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Write the stream in an abbreviated raw form</span> <span class="cwebmacronumber">22.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Wordings::empty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&lt;no text&gt;"</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">LOOP_THROUGH_WORDING</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">space</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="functiontext">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="identifier">space</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">compare_word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">COMMA_V</span><span class="plain">)) </span><span class="identifier">space</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">compare_word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">COLON_V</span><span class="plain">)) </span><span class="identifier">space</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">compare_word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">SEMICOLON_V</span><span class="plain">)) </span><span class="identifier">space</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">compare_word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">CLOSEBRACE_V</span><span class="plain">)) </span><span class="identifier">space</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">compare_word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">CLOSEBRACKET_V</span><span class="plain">)) </span><span class="identifier">space</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">compare_word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">-1, </span><span class="identifier">OPENBRACE_V</span><span class="plain">)) </span><span class="identifier">space</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">compare_word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">-1, </span><span class="identifier">OPENBRACKET_V</span><span class="plain">)) </span><span class="identifier">space</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">space</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" "</span><span class="plain">);</span>
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain"> = </span><span class="functiontext">Lexer::word_raw_text</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">L</span><span class="plain"> = </span><span class="identifier">Wide::len</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">L</span><span class="plain"> &gt; </span><span class="constant">STRING_TOLERANCE_LIMIT</span><span class="plain">+5) {</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain">&lt;</span><span class="constant">STRING_TOLERANCE_LIMIT</span><span class="plain">/2; </span><span class="identifier">j</span><span class="plain">++) </span><span class="identifier">PUT</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" [...] "</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">=</span><span class="constant">STRING_TOLERANCE_LIMIT</span><span class="plain">/2; </span><span class="identifier">j</span><span class="plain">&gt;0; </span><span class="identifier">j</span><span class="plain">--) </span><span class="identifier">PUT</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">L</span><span class="plain">-</span><span class="identifier">j</span><span class="plain">]);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%w"</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">i</span><span class="plain"> &gt;= </span><span class="functiontext">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)+1) &amp;&amp; (</span><span class="identifier">compare_word</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">-1, </span><span class="identifier">OPENI6_V</span><span class="plain">))) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"-)"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP22">&#167;22</a>.</p>
<p class="inwebparagraph"><a id="SP22_4"></a><b>&#167;22.4. </b>Another variation, this time formatted for use in I6 double-quoted text.
Here we don't care about punctuation spacing, because we are only writing
in comments and I6 debugging routines, but we do need to use the I6 escape
<code class="display"><span class="extract">~</span></code> for a double-quotation mark.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Write the stream in a raw form suitable for use in an I6 literal string</span> <span class="cwebmacronumber">22.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">LOOP_THROUGH_WORDING</span><span class="plain">(</span><span class="identifier">j</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">str</span><span class="plain"> = </span><span class="functiontext">Lexer::word_raw_text</span><span class="plain">(</span><span class="identifier">j</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">&gt;</span><span class="functiontext">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" "</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">=0; </span><span class="identifier">str</span><span class="plain">[</span><span class="identifier">k</span><span class="plain">] != </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">k</span><span class="plain">++) {</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="identifier">str</span><span class="plain">[</span><span class="identifier">k</span><span class="plain">];</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'@'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"@@"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'"'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"~"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="character">'^'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"[cr]"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">case</span><span class="plain"> </span><span class="character">'\\'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"[backslash]"</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="identifier">default:</span><span class="plain"> </span><span class="identifier">PUT</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP22">&#167;22</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="3-lxr.html">Back to 'Lexer'</a></li><li><a href="3-tff.html">Continue with 'Text From Files'</a></li></ul><hr class="tocbar">
2019-04-22 17:42:10 +03:00
<!--End of weave-->
2020-03-19 02:11:25 +02:00
</main>
2019-03-17 14:40:57 +02:00
</body>
</html>