1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 10:04:21 +03:00
inform7/docs/inflections-module/3-vc.html

1321 lines
174 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/pp</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/vc' 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">inflections</a></li><li><a href="index.html#3">Chapter 3: Grammatical Uses of Inflection</a></li><li><b>Verb Conjugation</b></li></ul><p class="purpose">Conjugating verbs into the many different forms they can take.</p>
2019-03-17 14:40:57 +02:00
<ul class="toc"><li><a href="#SP2">&#167;2. Making conjugations</a></li><li><a href="#SP4">&#167;4. Follow instructions</a></li><li><a href="#SP5">&#167;5. Merge verb material</a></li><li><a href="#SP8">&#167;8. Parsing verb form numbers</a></li><li><a href="#SP9">&#167;9. Parsing tense and sense indicators</a></li><li><a href="#SP10">&#167;10. Parsing utilities</a></li><li><a href="#SP12">&#167;12. Errors</a></li><li><a href="#SP15">&#167;15. Testing</a></li></ul><hr class="tocbar">
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b>We will need to turn a base form of a verb &mdash; in English, this is always the
infinitive &mdash; into up to 123 variants; we manage this with quite an extensive
data structure. There will typically only be a few dozen fully conjugated
verbs in any source text, though, so the memory cost isn't too extreme. For
English it looks wasteful, since so many forms are the same, but for French
</p>
<ul class="items"><li>(say) they are almost all different.
</li></ul>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">verb_conjugation</span><span class="plain"> {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">infinitive</span><span class="plain">; </span><span class="comment">not counting the "to", in English</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">past_participle</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">present_participle</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">verb_tabulation</span><span class="plain"> </span><span class="identifier">tabulations</span><span class="plain">[</span><span class="constant">NO_KNOWN_MOODS</span><span class="plain">];</span>
<span class="identifier">PREFORM_LANGUAGE_TYPE</span><span class="plain"> *</span><span class="identifier">defined_in</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">LINGUISTICS_MODULE</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">verb_identity</span><span class="plain"> *</span><span class="identifier">vc_conjugates</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">where_vc_created</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">vc_iname</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">auxiliary_only</span><span class="plain">; </span><span class="comment">used only as an auxiliary, e.g. the "have" in "I have gone"</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">instance_of_verb</span><span class="plain">; </span><span class="comment">defines an instance of kind "verb" at run-time</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">verb_conjugation</span><span class="plain">;</span>
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">verb_tabulation</span><span class="plain"> {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">to_be_auxiliary</span><span class="plain">; </span><span class="comment">use this if non-empty</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">vc_text</span><span class="plain">[</span><span class="constant">NO_KNOWN_TENSES</span><span class="plain">][2][6];</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">modal_auxiliary_usage</span><span class="plain">[</span><span class="constant">NO_KNOWN_TENSES</span><span class="plain">][2][6];</span>
<span class="plain">} </span><span class="reserved">verb_tabulation</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure verb_conjugation is accessed in 3/plr and here.</p>
<p class="endnote">The structure verb_tabulation is private to this section.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. Making conjugations. </b>The following will make more sense if read alongside the examples in "English
Inflections", which explains the format in full. In fact English itself is a
little tame, though &mdash; try the French Language extension for the real deal.
</p>
<p class="inwebparagraph">The crucial early step here is <code class="display"><span class="extract">Conjugation::follow_instructions</span></code>, which has
two tasks to perform: it works out the numbered verb forms, and it chooses
which tabulation will be used. Verb form number 0 is always the base text,
and subsequent numbers include some which are universal across all verbs
(these have <code class="display"><span class="extract">*_FORM_TYPE</span></code> constants), and others which vary from one
conjugation to another.
</p>
<pre class="display">
<span class="reserved">verb_conjugation</span><span class="plain"> *</span><span class="functiontext">Conjugation::conjugate</span><span class="plain">(</span><span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">base_text</span><span class="plain">,</span>
<span class="identifier">PREFORM_LANGUAGE_TYPE</span><span class="plain"> *</span><span class="identifier">nl</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">Conjugation::conjugate_with_overrides</span><span class="plain">(</span><span class="identifier">base_text</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">nl</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="reserved">verb_conjugation</span><span class="plain"> *</span><span class="functiontext">Conjugation::conjugate_with_overrides</span><span class="plain">(</span><span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">base_text</span><span class="plain">,</span>
<span class="identifier">word_assemblage</span><span class="plain"> *</span><span class="identifier">overrides</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_overrides</span><span class="plain">, </span><span class="identifier">PREFORM_LANGUAGE_TYPE</span><span class="plain"> *</span><span class="identifier">nl</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nl</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">nl</span><span class="plain"> = </span><span class="identifier">English_language</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">WordAssemblages::nonempty</span><span class="plain">(</span><span class="identifier">base_text</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"No base text for verb conjugation"</span><span class="plain">);</span>
<span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">verb_forms</span><span class="plain">[</span><span class="constant">MAX_FORM_TYPES</span><span class="plain">+1];</span>
&lt;<span class="cwebmacro">Initialise all verb forms to the base text</span> <span class="cwebmacronumber">2.1</span>&gt;<span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">n</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">, </span><span class="identifier">aux_len</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">avo_flag</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">niv_flag</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">nonterminal</span><span class="plain"> *</span><span class="identifier">tabulation</span><span class="plain"> =</span>
<span class="functiontext">Conjugation::follow_instructions</span><span class="plain">(</span><span class="identifier">verb_forms</span><span class="plain">, &amp;</span><span class="identifier">n</span><span class="plain">, &amp;</span><span class="identifier">aux_len</span><span class="plain">, &amp;</span><span class="identifier">avo_flag</span><span class="plain">, &amp;</span><span class="identifier">niv_flag</span><span class="plain">, </span><span class="identifier">nl</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Override any verb forms with supplied irregularities</span> <span class="cwebmacronumber">2.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Use the verb forms and the tabulation to make the conjugation</span> <span class="cwebmacronumber">2.3</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Conjugation::conjugate is used in <a href="#SP5_4">&#167;5.4</a>, <a href="#SP15">&#167;15</a>, <a href="#SP16">&#167;16</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="endnote">The function Conjugation::conjugate_with_overrides appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP2_1"></a><b>&#167;2.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Initialise all verb forms to the base text</span> <span class="cwebmacronumber">2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain">=0; </span><span class="identifier">k</span><span class="plain">&lt;=</span><span class="constant">MAX_FORM_TYPES</span><span class="plain">; </span><span class="identifier">k</span><span class="plain">++) </span><span class="identifier">verb_forms</span><span class="plain">[</span><span class="identifier">k</span><span class="plain">] = </span><span class="identifier">base_text</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_2"></a><b>&#167;2.2. </b>This feature is provided so that English verb definitions can override the
usual grammatical rules, which enables us to create new irregular verbs.
For example, Inform will by default make the past participle "blended" out
of the verb "to blend", but a definition like
</p>
<blockquote>
<p>To blend (I blend, he blends, it is blent) ...</p>
</blockquote>
<p class="inwebparagraph">will cause "blent" to override "blended" in the <code class="display"><span class="extract">PAST_PARTICIPLE_FORM_TYPE</span></code>.
(Philip Larkin's poem "Church Going" uses "blent", but I've never seen
anybody else try this one on.)
</p>
<p class="inwebparagraph">Note that verb form 0 can't be overridden: that was the base text.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Override any verb forms with supplied irregularities</span> <span class="cwebmacronumber">2.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain">=1; </span><span class="identifier">k</span><span class="plain">&lt;</span><span class="identifier">no_overrides</span><span class="plain">; </span><span class="identifier">k</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">WordAssemblages::nonempty</span><span class="plain">(</span><span class="identifier">overrides</span><span class="plain">[</span><span class="identifier">k</span><span class="plain">]))</span>
<span class="identifier">verb_forms</span><span class="plain">[</span><span class="identifier">k</span><span class="plain">] = </span><span class="identifier">overrides</span><span class="plain">[</span><span class="identifier">k</span><span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_3"></a><b>&#167;2.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Use the verb forms and the tabulation to make the conjugation</span> <span class="cwebmacronumber">2.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">verb_conjugation</span><span class="plain"> *</span><span class="identifier">vc</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">verb_conjugation</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">LINGUISTICS_MODULE</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">vc_conjugates</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">#</span><span class="identifier">endif</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">infinitive</span><span class="plain"> = </span><span class="identifier">verb_forms</span><span class="plain">[</span><span class="constant">INFINITIVE_FORM_TYPE</span><span class="plain">];</span>
<span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">present_participle</span><span class="plain"> = </span><span class="identifier">verb_forms</span><span class="plain">[</span><span class="constant">PRESENT_PARTICIPLE_FORM_TYPE</span><span class="plain">];</span>
<span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">past_participle</span><span class="plain"> = </span><span class="identifier">verb_forms</span><span class="plain">[</span><span class="constant">PAST_PARTICIPLE_FORM_TYPE</span><span class="plain">];</span>
<span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">defined_in</span><span class="plain"> = </span><span class="identifier">nl</span><span class="plain">;</span>
<span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">auxiliary_only</span><span class="plain"> = </span><span class="identifier">avo_flag</span><span class="plain">;</span>
<span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">instance_of_verb</span><span class="plain"> = (</span><span class="identifier">niv_flag</span><span class="plain">)?</span><span class="identifier">FALSE:TRUE</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">where_vc_created</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
<span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">vc_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">#</span><span class="identifier">endif</span>
&lt;<span class="cwebmacro">Start by blanking out all the passive and active slots</span> <span class="cwebmacronumber">2.3.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Work through the supplied tabulation, filling in slots as directed</span> <span class="cwebmacronumber">2.3.2</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">vc</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_3_1"></a><b>&#167;2.3.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Start by blanking out all the passive and active slots</span> <span class="cwebmacronumber">2.3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
2020-04-07 03:06:09 +03:00
<span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">tabulations</span><span class="plain">[</span><span class="constant">ACTIVE_MOOD</span><span class="plain">].</span><span class="element">to_be_auxiliary</span><span class="plain"> = </span><span class="identifier">WordAssemblages::lit_0</span><span class="plain">();</span>
<span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">tabulations</span><span class="plain">[</span><span class="constant">PASSIVE_MOOD</span><span class="plain">].</span><span class="element">to_be_auxiliary</span><span class="plain"> = </span><span class="identifier">WordAssemblages::lit_0</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">i</span><span class="plain">, </span><span class="identifier">tense</span><span class="plain">, </span><span class="identifier">sense</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">tense</span><span class="plain">=0; </span><span class="identifier">tense</span><span class="plain">&lt;</span><span class="constant">NO_KNOWN_TENSES</span><span class="plain">; </span><span class="identifier">tense</span><span class="plain">++)</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">sense</span><span class="plain">=0; </span><span class="identifier">sense</span><span class="plain">&lt;2; </span><span class="identifier">sense</span><span class="plain">++)</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;6; </span><span class="identifier">i</span><span class="plain">++) {</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">tabulations</span><span class="plain">[</span><span class="constant">ACTIVE_MOOD</span><span class="plain">].</span><span class="element">vc_text</span><span class="plain">[</span><span class="identifier">tense</span><span class="plain">][</span><span class="identifier">sense</span><span class="plain">][</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">WordAssemblages::lit_0</span><span class="plain">();</span>
<span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">tabulations</span><span class="plain">[</span><span class="constant">PASSIVE_MOOD</span><span class="plain">].</span><span class="element">vc_text</span><span class="plain">[</span><span class="identifier">tense</span><span class="plain">][</span><span class="identifier">sense</span><span class="plain">][</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">WordAssemblages::lit_0</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">This code is used in <a href="#SP2_3">&#167;2.3</a>.</p>
<p class="inwebparagraph"><a id="SP2_3_2"></a><b>&#167;2.3.2. </b>A tabulation is a sort of program laying out what to put in which slots,
active or passive. Each production is a step in this program, and it consists
of a "selector" followed by a "line". For example, the production:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">a3 ( t1 avoir ) 3+*</span>
</pre>
<p class="inwebparagraph">contains six tokens; the selector is <code class="display"><span class="extract">a3</span></code>, and the line is made up from the
rest. (The selector is always just a single token.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Work through the supplied tabulation, filling in slots as directed</span> <span class="cwebmacronumber">2.3.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">production_list</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">pl</span><span class="plain"> = </span><span class="identifier">tabulation</span><span class="plain">-&gt;</span><span class="identifier">first_production_list</span><span class="plain">; </span><span class="identifier">pl</span><span class="plain">; </span><span class="identifier">pl</span><span class="plain"> = </span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="identifier">next_production_list</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nl</span><span class="plain"> == </span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="identifier">definition_language</span><span class="plain">) {</span>
<span class="identifier">production</span><span class="plain"> *</span><span class="identifier">pr</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">pr</span><span class="plain"> = </span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="identifier">first_production</span><span class="plain">; </span><span class="identifier">pr</span><span class="plain">; </span><span class="identifier">pr</span><span class="plain"> = </span><span class="identifier">pr</span><span class="plain">-&gt;</span><span class="identifier">next_production</span><span class="plain">) {</span>
<span class="identifier">ptoken</span><span class="plain"> *</span><span class="identifier">selector</span><span class="plain"> = </span><span class="identifier">pr</span><span class="plain">-&gt;</span><span class="identifier">first_ptoken</span><span class="plain">;</span>
<span class="identifier">ptoken</span><span class="plain"> *</span><span class="identifier">line</span><span class="plain"> = (</span><span class="identifier">selector</span><span class="plain">)?(</span><span class="identifier">selector</span><span class="plain">-&gt;</span><span class="identifier">next_ptoken</span><span class="plain">):</span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">selector</span><span class="plain">) &amp;&amp; (</span><span class="identifier">selector</span><span class="plain">-&gt;</span><span class="identifier">ptoken_category</span><span class="plain"> == </span><span class="identifier">FIXED_WORD_PTC</span><span class="plain">) &amp;&amp; (</span><span class="identifier">line</span><span class="plain">)) {</span>
&lt;<span class="cwebmacro">Apply the given tabulation line to the slots selected</span> <span class="cwebmacronumber">2.3.2.1</span>&gt;<span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Conjugation::error</span><span class="plain">(</span><span class="identifier">base_text</span><span class="plain">, </span><span class="identifier">tabulation</span><span class="plain">, </span><span class="identifier">pr</span><span class="plain">,</span>
<span class="string">"tabulation row doesn't consist of a selector and then text"</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="#SP2_3">&#167;2.3</a>.</p>
<p class="inwebparagraph"><a id="SP2_3_2_1"></a><b>&#167;2.3.2.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Apply the given tabulation line to the slots selected</span> <span class="cwebmacronumber">2.3.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">active_set</span><span class="plain"> = </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">, </span><span class="identifier">tense_set</span><span class="plain"> = -1, </span><span class="identifier">sense_set</span><span class="plain"> = -1, </span><span class="identifier">set_tba</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Parse the slot selector</span> <span class="cwebmacronumber">2.3.2.1.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">set_tba</span><span class="plain">)</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">tabulations</span><span class="plain">[</span><span class="constant">PASSIVE_MOOD</span><span class="plain">].</span><span class="element">to_be_auxiliary</span><span class="plain"> =</span>
<span class="functiontext">Conjugation::merge</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">, </span><span class="constant">0</span><span class="plain">, </span><span class="constant">0</span><span class="plain">, </span><span class="constant">0</span><span class="plain">, </span><span class="constant">MAX_FORM_TYPES</span><span class="plain">+1, </span><span class="identifier">verb_forms</span><span class="plain">, </span><span class="identifier">nl</span><span class="plain">, </span><span class="identifier">NULL</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">person</span><span class="plain">, </span><span class="identifier">tense</span><span class="plain">, </span><span class="identifier">sense</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">tense</span><span class="plain">=0; </span><span class="identifier">tense</span><span class="plain">&lt;</span><span class="constant">NO_KNOWN_TENSES</span><span class="plain">; </span><span class="identifier">tense</span><span class="plain">++)</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">sense</span><span class="plain">=0; </span><span class="identifier">sense</span><span class="plain">&lt;2; </span><span class="identifier">sense</span><span class="plain">++)</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">person</span><span class="plain">=0; </span><span class="identifier">person</span><span class="plain">&lt;6; </span><span class="identifier">person</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">sense_set</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">sense</span><span class="plain"> != </span><span class="identifier">sense_set</span><span class="plain">)) </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">tense_set</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">tense</span><span class="plain"> != </span><span class="identifier">tense_set</span><span class="plain">)) </span><span class="reserved">continue</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">active_set</span><span class="plain">)</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">tabulations</span><span class="plain">[</span><span class="constant">ACTIVE_MOOD</span><span class="plain">].</span><span class="element">vc_text</span><span class="plain">[</span><span class="identifier">tense</span><span class="plain">][</span><span class="identifier">sense</span><span class="plain">][</span><span class="identifier">person</span><span class="plain">] =</span>
2019-03-17 14:40:57 +02:00
<span class="functiontext">Conjugation::merge</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">, </span><span class="identifier">sense</span><span class="plain">, </span><span class="identifier">tense</span><span class="plain">, </span><span class="identifier">person</span><span class="plain">, </span><span class="constant">MAX_FORM_TYPES</span><span class="plain">+1, </span><span class="identifier">verb_forms</span><span class="plain">, </span><span class="identifier">nl</span><span class="plain">,</span>
2020-04-07 03:06:09 +03:00
<span class="plain">&amp;(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">tabulations</span><span class="plain">[</span><span class="constant">ACTIVE_MOOD</span><span class="plain">].</span><span class="element">modal_auxiliary_usage</span><span class="plain">[</span><span class="identifier">tense</span><span class="plain">][</span><span class="identifier">sense</span><span class="plain">][</span><span class="identifier">person</span><span class="plain">]));</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">else</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">tabulations</span><span class="plain">[</span><span class="constant">PASSIVE_MOOD</span><span class="plain">].</span><span class="element">vc_text</span><span class="plain">[</span><span class="identifier">tense</span><span class="plain">][</span><span class="identifier">sense</span><span class="plain">][</span><span class="identifier">person</span><span class="plain">] =</span>
2019-03-17 14:40:57 +02:00
<span class="functiontext">Conjugation::merge</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">, </span><span class="identifier">sense</span><span class="plain">, </span><span class="identifier">tense</span><span class="plain">, </span><span class="identifier">person</span><span class="plain">, </span><span class="constant">MAX_FORM_TYPES</span><span class="plain">+1, </span><span class="identifier">verb_forms</span><span class="plain">, </span><span class="identifier">nl</span><span class="plain">,</span>
2020-04-07 03:06:09 +03:00
<span class="plain">&amp;(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">tabulations</span><span class="plain">[</span><span class="constant">PASSIVE_MOOD</span><span class="plain">].</span><span class="element">modal_auxiliary_usage</span><span class="plain">[</span><span class="identifier">tense</span><span class="plain">][</span><span class="identifier">sense</span><span class="plain">][</span><span class="identifier">person</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">This code is used in <a href="#SP2_3_2">&#167;2.3.2</a>.</p>
<p class="inwebparagraph"><a id="SP2_3_2_1_1"></a><b>&#167;2.3.2.1.1. </b>The selector tells us which tense(s), sense(s) and mood(s) to apply the
line to; <code class="display"><span class="extract">a3</span></code>, for example, means active mood, tense 3, in both positive
and negative senses.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Parse the slot selector</span> <span class="cwebmacronumber">2.3.2.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">vocabulary_entry</span><span class="plain"> *</span><span class="identifier">ve</span><span class="plain"> = </span><span class="identifier">selector</span><span class="plain">-&gt;</span><span class="identifier">ve_pt</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="identifier">Vocabulary::get_exemplar</span><span class="plain">(</span><span class="identifier">ve</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">p</span><span class="plain">[0] == </span><span class="character">'a'</span><span class="plain">) </span><span class="identifier">active_set</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">p</span><span class="plain">[0] == </span><span class="character">'p'</span><span class="plain">) </span><span class="identifier">active_set</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">active_set</span><span class="plain"> == </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">)</span>
<span class="functiontext">Conjugation::error</span><span class="plain">(</span><span class="identifier">base_text</span><span class="plain">, </span><span class="identifier">tabulation</span><span class="plain">, </span><span class="identifier">pr</span><span class="plain">,</span>
<span class="string">"tabulation row doesn't begin with 'a' or 'p'"</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">at</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">if</span><span class="plain"> (</span><span class="identifier">Characters::isdigit</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">at</span><span class="plain">])) { </span><span class="identifier">tense_set</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">at</span><span class="plain">++]-</span><span class="character">'1'</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">p</span><span class="plain">[</span><span class="identifier">at</span><span class="plain">] == </span><span class="character">'+'</span><span class="plain">) { </span><span class="identifier">sense_set</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">at</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">p</span><span class="plain">[</span><span class="identifier">at</span><span class="plain">] == </span><span class="character">'-'</span><span class="plain">) { </span><span class="identifier">sense_set</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="identifier">at</span><span class="plain">++; }</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">at</span><span class="plain">] == </span><span class="character">'*'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">tense_set</span><span class="plain"> == -1) &amp;&amp; (</span><span class="identifier">active_set</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)) {</span>
<span class="identifier">set_tba</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="identifier">at</span><span class="plain">++;</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">p</span><span class="plain">[</span><span class="identifier">at</span><span class="plain">] != </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"The selector here is: &lt;%w&gt;\n"</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="functiontext">Conjugation::error</span><span class="plain">(</span><span class="identifier">base_text</span><span class="plain">, </span><span class="identifier">tabulation</span><span class="plain">, </span><span class="identifier">pr</span><span class="plain">,</span>
<span class="string">"unrecognised selector in tabulation row"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2_3_2_1">&#167;2.3.2.1</a>.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b></p>
<pre class="display">
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Conjugation::conj_iname</span><span class="plain">(</span><span class="reserved">verb_conjugation</span><span class="plain"> *</span><span class="identifier">vc</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">vc</span><span class="plain">-&gt;</span><span class="element">vc_iname</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">vc_conjugates</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="identifier">Hierarchy::package</span><span class="plain">(</span><span class="identifier">Modules::find</span><span class="plain">(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">where_vc_created</span><span class="plain">), </span><span class="identifier">MVERBS_HAP</span><span class="plain">);</span>
2019-04-24 01:31:35 +03:00
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">ANT</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">ANT</span><span class="plain">, </span><span class="string">"%A (modal)"</span><span class="plain">, </span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">tabulations</span><span class="plain">[</span><span class="constant">ACTIVE_MOOD</span><span class="plain">].</span><span class="element">vc_text</span><span class="plain">[0][0][2]);</span>
2019-04-24 01:31:35 +03:00
<span class="identifier">Hierarchy::markup</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">, </span><span class="identifier">MVERB_NAME_HMD</span><span class="plain">, </span><span class="identifier">ANT</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">ANT</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">vc_iname</span><span class="plain"> = </span><span class="identifier">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="identifier">MODAL_CONJUGATION_FN_HL</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="identifier">Verbs::verb_package</span><span class="plain">(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">vc_conjugates</span><span class="plain">, </span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">where_vc_created</span><span class="plain">);</span>
2019-04-24 01:31:35 +03:00
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">ANT</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">ANT</span><span class="plain">, </span><span class="string">"to %A"</span><span class="plain">, </span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">infinitive</span><span class="plain">);</span>
2019-04-24 01:31:35 +03:00
<span class="identifier">Hierarchy::markup</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">, </span><span class="identifier">VERB_NAME_HMD</span><span class="plain">, </span><span class="identifier">ANT</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">ANT</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">vc_iname</span><span class="plain"> = </span><span class="identifier">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="identifier">NONMODAL_CONJUGATION_FN_HL</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</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">vc</span><span class="plain">-&gt;</span><span class="identifier">vc_iname</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Conjugation::conj_iname appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Follow instructions. </b>That completes the top level of the routine, but it depended on two major
sub-steps: a preliminary pass called <code class="display"><span class="extract">Conjugation::follow_instructions</span></code> and
a routine to deal with the final results called <code class="display"><span class="extract">Conjugation::merge</span></code>.
</p>
<p class="inwebparagraph">Here's the first of these. Note that the routine indirects through three main
nonterminals; it always starts with <code class="display"><span class="extract">&lt;verb-conjugation-instructions&gt;</span></code> and
uses this to choose a "conjugation" nonterminal. It then chugs through
the conjugation, which ends by choosing a "tabulation". For example, in
English, the base text "do" passes through <code class="display"><span class="extract">&lt;verb-conjugation-instructions&gt;</span></code>,
which chooses the conjugation <code class="display"><span class="extract">&lt;to-do-conjugation&gt;</span></code>, which in turn sets some
participles and then chooses the tabulation <code class="display"><span class="extract">&lt;to-do-tabulation&gt;</span></code>.
</p>
<pre class="display">
<span class="identifier">nonterminal</span><span class="plain"> *</span><span class="functiontext">Conjugation::follow_instructions</span><span class="plain">(</span><span class="identifier">word_assemblage</span><span class="plain"> *</span><span class="identifier">verb_forms</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">highest_form_written</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> *</span><span class="identifier">aux_len</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">avo_flag</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">niv_flag</span><span class="plain">, </span><span class="identifier">PREFORM_LANGUAGE_TYPE</span><span class="plain"> *</span><span class="identifier">nl</span><span class="plain">) {</span>
<span class="identifier">nonterminal</span><span class="plain"> *</span><span class="identifier">instructions_nt</span><span class="plain"> = &lt;</span><span class="identifier">verb</span><span class="plain">-</span><span class="identifier">conjugation</span><span class="plain">-</span><span class="identifier">instructions</span><span class="plain">&gt;;</span>
<span class="identifier">nonterminal</span><span class="plain"> *</span><span class="identifier">tabulation_nt</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">conjugation_nt</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">*</span><span class="identifier">highest_form_written</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="plain">*</span><span class="identifier">aux_len</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; *</span><span class="identifier">avo_flag</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; *</span><span class="identifier">niv_flag</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
&lt;<span class="cwebmacro">Pattern match on the base text to decide which conjugation to use</span> <span class="cwebmacronumber">4.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">conjugation_nt</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="functiontext">Conjugation::error</span><span class="plain">(</span><span class="identifier">verb_forms</span><span class="plain">[0], </span><span class="identifier">instructions_nt</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">,</span>
<span class="string">"the instructions here failed to choose a conjugation"</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Process the conjugation and determine the tabulation</span> <span class="cwebmacronumber">4.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tabulation_nt</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="functiontext">Conjugation::error</span><span class="plain">(</span><span class="identifier">verb_forms</span><span class="plain">[0], </span><span class="identifier">conjugation_nt</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">,</span>
<span class="string">"the conjugation here failed to choose a tabulation"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">tabulation_nt</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Conjugation::follow_instructions is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP4_1"></a><b>&#167;4.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Pattern match on the base text to decide which conjugation to use</span> <span class="cwebmacronumber">4.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">vocabulary_entry</span><span class="plain"> **</span><span class="identifier">base_text_words</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">base_text_word_count</span><span class="plain">;</span>
<span class="identifier">WordAssemblages::as_array</span><span class="plain">(&amp;(</span><span class="identifier">verb_forms</span><span class="plain">[</span><span class="constant">BASE_FORM_TYPE</span><span class="plain">]), &amp;</span><span class="identifier">base_text_words</span><span class="plain">, &amp;</span><span class="identifier">base_text_word_count</span><span class="plain">);</span>
<span class="identifier">production_list</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">pl</span><span class="plain"> = </span><span class="identifier">instructions_nt</span><span class="plain">-&gt;</span><span class="identifier">first_production_list</span><span class="plain">; </span><span class="identifier">pl</span><span class="plain">; </span><span class="identifier">pl</span><span class="plain"> = </span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="identifier">next_production_list</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nl</span><span class="plain"> == </span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="identifier">definition_language</span><span class="plain">) {</span>
<span class="identifier">production</span><span class="plain"> *</span><span class="identifier">pr</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">pr</span><span class="plain"> = </span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="identifier">first_production</span><span class="plain">; </span><span class="identifier">pr</span><span class="plain">; </span><span class="identifier">pr</span><span class="plain"> = </span><span class="identifier">pr</span><span class="plain">-&gt;</span><span class="identifier">next_production</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Try to match the base text against this production</span> <span class="cwebmacronumber">4.1.1</span>&gt;<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="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP4_1_1"></a><b>&#167;4.1.1. </b>Each production in this language's <code class="display"><span class="extract">&lt;verb-conjugation-instructions&gt;</span></code> grammar
consists of a (possibly empty) pattern to match, followed by the name of a
nonterminal to use as the conjugation if it matches. For example, in
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">-querir &lt;fr-querir-conjugation&gt;</span>
</pre>
<p class="inwebparagraph">the pattern part is a single token, <code class="display"><span class="extract">-querir</span></code>, which matches if the base text
is a single word whose last six characters are "querir". A more complicated
case is:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">be able to ... &lt;to-be-able-to-auxiliary&gt;</span>
</pre>
<p class="inwebparagraph">Here the wildcard <code class="display"><span class="extract">...</span></code> matches one or more words, and the "auxiliary
infinitive" form is set to the part matched by <code class="display"><span class="extract">...</span></code>: for example,
"be able to see" matches with auxiliary infinitive "see".
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Try to match the base text against this production</span> <span class="cwebmacronumber">4.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">ptoken</span><span class="plain"> *</span><span class="identifier">pt</span><span class="plain">, *</span><span class="identifier">last</span><span class="plain"> = </span><span class="identifier">NULL</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">len</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">malformed</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">for</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain"> = </span><span class="identifier">pr</span><span class="plain">-&gt;</span><span class="identifier">first_ptoken</span><span class="plain">; </span><span class="identifier">pt</span><span class="plain">; </span><span class="identifier">pt</span><span class="plain"> = </span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="identifier">next_ptoken</span><span class="plain">) { </span><span class="identifier">last</span><span class="plain"> = </span><span class="identifier">pt</span><span class="plain">; </span><span class="identifier">len</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">len</span><span class="plain"> &gt;= </span><span class="constant">1</span><span class="plain">) &amp;&amp; (</span><span class="identifier">last</span><span class="plain">-&gt;</span><span class="identifier">ptoken_category</span><span class="plain"> == </span><span class="identifier">NONTERMINAL_PTC</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">conjugation_nt</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) { </span><span class="comment">i.e., if we have not yet chosen a conjugation</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">failed_to_match</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">wildcard_from</span><span class="plain"> = -1;</span>
&lt;<span class="cwebmacro">Try to match the base text against the pattern part of the production</span> <span class="cwebmacronumber">4.1.1.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">failed_to_match</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">conjugation_nt</span><span class="plain"> = </span><span class="identifier">last</span><span class="plain">-&gt;</span><span class="identifier">nt_pt</span><span class="plain">;</span>
<span class="identifier">verb_forms</span><span class="plain">[</span><span class="constant">ADJOINT_INFINITIVE_FORM_TYPE</span><span class="plain">] = </span><span class="identifier">verb_forms</span><span class="plain">[</span><span class="constant">BASE_FORM_TYPE</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">wildcard_from</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">)</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">WordAssemblages::truncate</span><span class="plain">(&amp;(</span><span class="identifier">verb_forms</span><span class="plain">[</span><span class="constant">ADJOINT_INFINITIVE_FORM_TYPE</span><span class="plain">]), </span><span class="identifier">wildcard_from</span><span class="plain">);</span>
<span class="plain">*</span><span class="identifier">aux_len</span><span class="plain"> = </span><span class="identifier">wildcard_from</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">malformed</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">malformed</span><span class="plain">)</span>
<span class="functiontext">Conjugation::error</span><span class="plain">(</span><span class="identifier">verb_forms</span><span class="plain">[</span><span class="constant">BASE_FORM_TYPE</span><span class="plain">], &lt;</span><span class="identifier">verb</span><span class="plain">-</span><span class="identifier">conjugation</span><span class="plain">-</span><span class="identifier">instructions</span><span class="plain">&gt;, </span><span class="identifier">pr</span><span class="plain">,</span>
<span class="string">"malformed line"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4_1">&#167;4.1</a>.</p>
<p class="inwebparagraph"><a id="SP4_1_1_1"></a><b>&#167;4.1.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Try to match the base text against the pattern part of the production</span> <span class="cwebmacronumber">4.1.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
2020-04-07 03:06:09 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">word_count</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">for</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain"> = </span><span class="identifier">pr</span><span class="plain">-&gt;</span><span class="identifier">first_ptoken</span><span class="plain">; ((</span><span class="identifier">pt</span><span class="plain">) &amp;&amp; (</span><span class="identifier">pt</span><span class="plain"> != </span><span class="identifier">last</span><span class="plain">)); </span><span class="identifier">pt</span><span class="plain"> = </span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="identifier">next_ptoken</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="identifier">ptoken_category</span><span class="plain"> == </span><span class="identifier">FIXED_WORD_PTC</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">word_count</span><span class="plain"> &lt; </span><span class="identifier">base_text_word_count</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Conjugation::compare_ve_with_tails</span><span class="plain">(</span><span class="identifier">base_text_words</span><span class="plain">[</span><span class="identifier">word_count</span><span class="plain">], </span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="identifier">ve_pt</span><span class="plain">)))</span>
<span class="identifier">word_count</span><span class="plain">++;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">failed_to_match</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="identifier">ptoken_category</span><span class="plain"> == </span><span class="identifier">MULTIPLE_WILDCARD_PTC</span><span class="plain">) {</span>
<span class="identifier">wildcard_from</span><span class="plain"> = </span><span class="identifier">word_count</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">base_text_word_count</span><span class="plain"> &lt;= </span><span class="identifier">word_count</span><span class="plain">)</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">failed_to_match</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="comment">must match at least one word</span>
2019-03-17 14:40:57 +02:00
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">malformed</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">wildcard_from</span><span class="plain"> == -1) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">word_count</span><span class="plain"> != </span><span class="identifier">base_text_word_count</span><span class="plain">) </span><span class="identifier">failed_to_match</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">wildcard_from</span><span class="plain"> = </span><span class="constant">0</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">This code is used in <a href="#SP4_1_1">&#167;4.1.1</a>.</p>
<p class="inwebparagraph"><a id="SP4_2"></a><b>&#167;4.2. </b>In a conjugation, productions have two possible forms: either just a single
nonterminal, which usually identifies the tabulation, or a number followed by some
tokens.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Process the conjugation and determine the tabulation</span> <span class="cwebmacronumber">4.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">production_list</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">pl</span><span class="plain"> = </span><span class="identifier">conjugation_nt</span><span class="plain">-&gt;</span><span class="identifier">first_production_list</span><span class="plain">; </span><span class="identifier">pl</span><span class="plain">; </span><span class="identifier">pl</span><span class="plain"> = </span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="identifier">next_production_list</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nl</span><span class="plain"> == </span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="identifier">definition_language</span><span class="plain">) {</span>
<span class="identifier">production</span><span class="plain"> *</span><span class="identifier">pr</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">pr</span><span class="plain"> = </span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="identifier">first_production</span><span class="plain">; </span><span class="identifier">pr</span><span class="plain">; </span><span class="identifier">pr</span><span class="plain"> = </span><span class="identifier">pr</span><span class="plain">-&gt;</span><span class="identifier">next_production</span><span class="plain">) {</span>
<span class="identifier">ptoken</span><span class="plain"> *</span><span class="identifier">pt</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">len</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">malformed</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">for</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain"> = </span><span class="identifier">pr</span><span class="plain">-&gt;</span><span class="identifier">first_ptoken</span><span class="plain">; </span><span class="identifier">pt</span><span class="plain">; </span><span class="identifier">pt</span><span class="plain"> = </span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="identifier">next_ptoken</span><span class="plain">) </span><span class="identifier">len</span><span class="plain">++;</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">len</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">case</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">if</span><span class="plain"> (</span><span class="identifier">pr</span><span class="plain">-&gt;</span><span class="identifier">first_ptoken</span><span class="plain">-&gt;</span><span class="identifier">ptoken_category</span><span class="plain"> == </span><span class="identifier">NONTERMINAL_PTC</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pr</span><span class="plain">-&gt;</span><span class="identifier">first_ptoken</span><span class="plain">-&gt;</span><span class="identifier">nt_pt</span><span class="plain"> == &lt;</span><span class="identifier">auxiliary</span><span class="plain">-</span><span class="identifier">verb</span><span class="plain">-</span><span class="identifier">only</span><span class="plain">&gt;)</span>
<span class="plain">*</span><span class="identifier">avo_flag</span><span class="plain"> = </span><span class="identifier">TRUE</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">pr</span><span class="plain">-&gt;</span><span class="identifier">first_ptoken</span><span class="plain">-&gt;</span><span class="identifier">nt_pt</span><span class="plain"> == &lt;</span><span class="identifier">not</span><span class="plain">-</span><span class="identifier">instance</span><span class="plain">-</span><span class="identifier">of</span><span class="plain">-</span><span class="identifier">verb</span><span class="plain">-</span><span class="identifier">at</span><span class="plain">-</span><span class="identifier">run</span><span class="plain">-</span><span class="identifier">time</span><span class="plain">&gt;)</span>
<span class="plain">*</span><span class="identifier">niv_flag</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">else</span>
<span class="identifier">tabulation_nt</span><span class="plain"> = </span><span class="identifier">pr</span><span class="plain">-&gt;</span><span class="identifier">first_ptoken</span><span class="plain">-&gt;</span><span class="identifier">nt_pt</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">malformed</span><span class="plain"> = </span><span class="identifier">TRUE</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="constant">2</span><span class="plain">:</span>
2019-03-17 14:40:57 +02:00
&lt;<span class="cwebmacro">Set a verb form from the conjugation line</span> <span class="cwebmacronumber">4.2.1</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">malformed</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">malformed</span><span class="plain">)</span>
<span class="functiontext">Conjugation::error</span><span class="plain">(</span><span class="identifier">verb_forms</span><span class="plain">[</span><span class="constant">BASE_FORM_TYPE</span><span class="plain">], </span><span class="identifier">conjugation_nt</span><span class="plain">, </span><span class="identifier">pr</span><span class="plain">,</span>
<span class="string">"malformed line"</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="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP4_2_1"></a><b>&#167;4.2.1. </b>So here we check the more interesting case. The number identifies which
verb form to set, and the token which follows it provides the content.
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">2 having</span>
set to the literal text "having" <span class="plain">3 1+ed</span>
set to verb form 1 with "ed" suffixed <span class="plain">3 &lt;en-trie-past-participle&gt;</span>
run this trie on the base text and take the result
&lt;<span class="cwebmacrodefn">Set a verb form from the conjugation line</span> <span class="cwebmacronumber">4.2.1</span>&gt; =
<span class="identifier">ptoken</span><span class="plain"> *</span><span class="identifier">number_token</span><span class="plain"> = </span><span class="identifier">pr</span><span class="plain">-&gt;</span><span class="identifier">first_ptoken</span><span class="plain">;</span>
<span class="identifier">ptoken</span><span class="plain"> *</span><span class="identifier">content_token</span><span class="plain"> = </span><span class="identifier">number_token</span><span class="plain">-&gt;</span><span class="identifier">next_ptoken</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">n</span><span class="plain"> = </span><span class="functiontext">Conjugation::ptoken_to_verb_form_number</span><span class="plain">(</span><span class="identifier">number_token</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">n</span><span class="plain"> &gt;= </span><span class="constant">0</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">n</span><span class="plain"> &gt; *</span><span class="identifier">highest_form_written</span><span class="plain">) { *</span><span class="identifier">highest_form_written</span><span class="plain"> = </span><span class="identifier">n</span><span class="plain">; }</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">content_token</span><span class="plain">-&gt;</span><span class="identifier">ptoken_category</span><span class="plain"> == </span><span class="identifier">NONTERMINAL_PTC</span><span class="plain">)</span>
<span class="identifier">verb_forms</span><span class="plain">[</span><span class="identifier">n</span><span class="plain">] =</span>
<span class="functiontext">Inflections::apply_trie_to_wa</span><span class="plain">(</span>
<span class="identifier">verb_forms</span><span class="plain">[</span><span class="constant">BASE_FORM_TYPE</span><span class="plain">],</span>
<span class="functiontext">Preform::Nonparsing::define_trie</span><span class="plain">(</span><span class="identifier">content_token</span><span class="plain">-&gt;</span><span class="identifier">nt_pt</span><span class="plain">, </span><span class="identifier">TRIE_END</span><span class="plain">, </span><span class="identifier">nl</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">content_token</span><span class="plain">-&gt;</span><span class="identifier">ptoken_category</span><span class="plain"> == </span><span class="identifier">FIXED_WORD_PTC</span><span class="plain">)</span>
<span class="identifier">verb_forms</span><span class="plain">[</span><span class="identifier">n</span><span class="plain">] =</span>
<span class="functiontext">Conjugation::expand_with_endings</span><span class="plain">(</span><span class="identifier">content_token</span><span class="plain">-&gt;</span><span class="identifier">ve_pt</span><span class="plain">, </span><span class="identifier">verb_forms</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">malformed</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">malformed</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4_2">&#167;4.2</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Merge verb material. </b>Now the final main step. <code class="display"><span class="extract">row</span></code> points to a list of ptokens containing text,
and we have to copy that text into a word assemblage and return it.
</p>
<p class="inwebparagraph">In theory that's a one-line routine, but it's made complicated by the number
of special syntaxes which can go into the row of text. For example, if <code class="display"><span class="extract">row</span></code>
is only
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">will not do</span>
</pre>
<p class="inwebparagraph">then the word assemblage comes out to just "will not do"; but if it is
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">( t1 auxiliary-have ) done</span>
</pre>
<p class="inwebparagraph">then we consult tense 1 (present) of the verb "auxiliary-have", extract
the relevant slot, then append "done". (This might produce "have done"
or "has done" or "haven't done" or "hasn't done", depending on the
current sense and person.) We call the business of extracting text from
a different verb's conjugation "lifting".
</p>
<p class="inwebparagraph">There are other complications, too. See "English Inflections" for more.
</p>
<pre class="display">
<span class="identifier">word_assemblage</span><span class="plain"> </span><span class="functiontext">Conjugation::merge</span><span class="plain">(</span><span class="identifier">ptoken</span><span class="plain"> *</span><span class="identifier">row</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">sense</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">tense</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">person</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">num_ingredients</span><span class="plain">, </span><span class="identifier">word_assemblage</span><span class="plain"> *</span><span class="identifier">ingredients</span><span class="plain">,</span>
<span class="identifier">PREFORM_LANGUAGE_TYPE</span><span class="plain"> *</span><span class="identifier">nl</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">modal_following</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">modal_following</span><span class="plain">) { *</span><span class="identifier">modal_following</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">word_assemblage</span><span class="plain"> </span><span class="identifier">wa</span><span class="plain"> = </span><span class="identifier">WordAssemblages::lit_0</span><span class="plain">();</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">verb_form_to_lift</span><span class="plain"> = -1;</span>
<span class="identifier">ptoken</span><span class="plain"> *</span><span class="identifier">chunk</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">chunk</span><span class="plain"> = </span><span class="identifier">row</span><span class="plain">; </span><span class="identifier">chunk</span><span class="plain">; </span><span class="identifier">chunk</span><span class="plain"> = </span><span class="identifier">chunk</span><span class="plain">-&gt;</span><span class="identifier">next_ptoken</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">A plus-plus-digit indicates auxiliary modal usage</span> <span class="cwebmacronumber">5.5</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">A form number followed by a bracketed verb lifts the relevant form</span> <span class="cwebmacronumber">5.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">A bracketed verb becomes a lift</span> <span class="cwebmacronumber">5.4</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">A fixed word is simply added to the result</span> <span class="cwebmacronumber">5.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">A nonterminal is a table of persons</span> <span class="cwebmacronumber">5.2</span>&gt;<span class="plain">;</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Error in merge material line"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Conjugation::shorten_with_contractions</span><span class="plain">(</span><span class="identifier">wa</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Conjugation::merge is used in <a href="#SP2_3_2_1">&#167;2.3.2.1</a>, <a href="#SP5_2">&#167;5.2</a>.</p>
<p class="inwebparagraph"><a id="SP5_1"></a><b>&#167;5.1. </b>To take the easiest case first. If we read a word like <code class="display"><span class="extract">trailing</span></code>, we simply
add it. But note that <code class="display"><span class="extract">Conjugation::expand_with_endings</span></code> has other tricks up its sleeve,
and might expand <code class="display"><span class="extract">3+ed</span></code> to "trailed".
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">A fixed word is simply added to the result</span> <span class="cwebmacronumber">5.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">chunk</span><span class="plain">-&gt;</span><span class="identifier">ptoken_category</span><span class="plain"> == </span><span class="identifier">FIXED_WORD_PTC</span><span class="plain">) {</span>
<span class="identifier">wa</span><span class="plain"> = </span><span class="identifier">WordAssemblages::join</span><span class="plain">(</span><span class="identifier">wa</span><span class="plain">, </span><span class="functiontext">Conjugation::expand_with_endings</span><span class="plain">(</span><span class="identifier">chunk</span><span class="plain">-&gt;</span><span class="identifier">ve_pt</span><span class="plain">, </span><span class="identifier">ingredients</span><span class="plain">));</span>
<span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_2"></a><b>&#167;5.2. </b>If we read a nonterminal name, such as <code class="display"><span class="extract">&lt;fr-vivre-present&gt;</span></code>, then this must
be a grammar with six productions, giving the text to use for the six different
persons. We consult <code class="display"><span class="extract">person</span></code> and extract the relevant text. For example, if
<code class="display"><span class="extract">person</span></code> is 3, we extract "vivons". Note that this material is itself read
in by a recursive use of <code class="display"><span class="extract">Conjugation::merge()</span></code>, because this enables it to
make use of the same fancy features we're allowing here.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">A nonterminal is a table of persons</span> <span class="cwebmacronumber">5.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">chunk</span><span class="plain">-&gt;</span><span class="identifier">ptoken_category</span><span class="plain"> == </span><span class="identifier">NONTERMINAL_PTC</span><span class="plain">) {</span>
<span class="identifier">production_list</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">pl</span><span class="plain"> = </span><span class="identifier">chunk</span><span class="plain">-&gt;</span><span class="identifier">nt_pt</span><span class="plain">-&gt;</span><span class="identifier">first_production_list</span><span class="plain">; </span><span class="identifier">pl</span><span class="plain">; </span><span class="identifier">pl</span><span class="plain"> = </span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="identifier">next_production_list</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">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">production</span><span class="plain"> *</span><span class="identifier">pr</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">pr</span><span class="plain"> = </span><span class="identifier">pl</span><span class="plain">-&gt;</span><span class="identifier">first_production</span><span class="plain">; </span><span class="identifier">pr</span><span class="plain">; </span><span class="identifier">pr</span><span class="plain"> = </span><span class="identifier">pr</span><span class="plain">-&gt;</span><span class="identifier">next_production</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> == </span><span class="identifier">person</span><span class="plain">)</span>
<span class="identifier">wa</span><span class="plain"> = </span><span class="identifier">WordAssemblages::join</span><span class="plain">(</span><span class="identifier">wa</span><span class="plain">,</span>
<span class="functiontext">Conjugation::merge</span><span class="plain">(</span><span class="identifier">pr</span><span class="plain">-&gt;</span><span class="identifier">first_ptoken</span><span class="plain">,</span>
<span class="identifier">sense</span><span class="plain">, </span><span class="identifier">tense</span><span class="plain">, </span><span class="identifier">person</span><span class="plain">, </span><span class="identifier">num_ingredients</span><span class="plain">, </span><span class="identifier">ingredients</span><span class="plain">, </span><span class="identifier">nl</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">));</span>
<span class="identifier">N</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_3"></a><b>&#167;5.3. </b>A number followed by a verb in brackets, like so:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">3 ( avoir )</span>
</pre>
<p class="inwebparagraph">expands to verb form 3 of this verb &mdash; the past participle of "avoir", which
is "eu", as it happens. This is a special kind of lift. It isn't actually
performed now; we make a note and carry it out when we reach the brackets,
on the next iteration.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">A form number followed by a bracketed verb lifts the relevant form</span> <span class="cwebmacronumber">5.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">X</span><span class="plain"> = </span><span class="functiontext">Conjugation::ptoken_to_verb_form_number</span><span class="plain">(</span><span class="identifier">chunk</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">X</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Conjugation::ptoken_as_bracket</span><span class="plain">(</span><span class="identifier">chunk</span><span class="plain">-&gt;</span><span class="identifier">next_ptoken</span><span class="plain">))) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">verb_form_to_lift</span><span class="plain"> = </span><span class="identifier">X</span><span class="plain">;</span>
<span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_4"></a><b>&#167;5.4. </b>And now the lift takes place. We might at this point have <code class="display"><span class="extract">verb_form_to_lift</span></code>
set, in which case we should lift a verb form, or we might not, in which case
we should lift an ordinary usage, such as third-person singular in a particular
tense. A lift can optionally change tense or sense: for example,
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">( t1 have )</span>
</pre>
<p class="inwebparagraph">lifts from the present tense of "to have". If there's no tense indicator,
the tense remains the current one. (It's also possible to change the sense from
positive to negative or vice versa with this, though I can't think of a
language where this would be useful.) Note that, once again, the text of the
infinitive passes through <code class="display"><span class="extract">Conjugation::expand_with_endings</span></code>, so that it can make use
of the numbered verb forms if we want it to.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">A bracketed verb becomes a lift</span> <span class="cwebmacronumber">5.4</span>&gt; =
</code></p>
<pre class="displaydefn">
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Conjugation::ptoken_as_bracket</span><span class="plain">(</span><span class="identifier">chunk</span><span class="plain">) == </span><span class="constant">1</span><span class="plain">) {</span>
<span class="identifier">chunk</span><span class="plain"> = </span><span class="identifier">chunk</span><span class="plain">-&gt;</span><span class="identifier">next_ptoken</span><span class="plain">; </span><span class="comment">move past open bracket</span>
2019-03-17 14:40:57 +02:00
<span class="comment">if there is a tense/sense indicator, use it, and move forward</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">S</span><span class="plain"> = -1;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">T</span><span class="plain"> = </span><span class="functiontext">Conjugation::ptoken_to_tense_indicator</span><span class="plain">(</span><span class="identifier">chunk</span><span class="plain">, &amp;</span><span class="identifier">S</span><span class="plain">) - </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">T</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">chunk</span><span class="plain"> = </span><span class="identifier">chunk</span><span class="plain">-&gt;</span><span class="identifier">next_ptoken</span><span class="plain">; </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">T</span><span class="plain"> = </span><span class="identifier">tense</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">S</span><span class="plain"> == -1) </span><span class="identifier">S</span><span class="plain"> = </span><span class="identifier">sense</span><span class="plain">;</span>
<span class="comment">extract the text of the infinitive</span>
<span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">verb_lifted</span><span class="plain"> = </span><span class="identifier">WordAssemblages::lit_0</span><span class="plain">();</span>
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">chunk</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Conjugation::ptoken_as_bracket</span><span class="plain">(</span><span class="identifier">chunk</span><span class="plain">) != -1)) {</span>
<span class="identifier">verb_lifted</span><span class="plain"> = </span><span class="identifier">WordAssemblages::join</span><span class="plain">(</span><span class="identifier">verb_lifted</span><span class="plain">,</span>
<span class="functiontext">Conjugation::expand_with_endings</span><span class="plain">(</span><span class="identifier">chunk</span><span class="plain">-&gt;</span><span class="identifier">ve_pt</span><span class="plain">, </span><span class="identifier">ingredients</span><span class="plain">));</span>
<span class="identifier">chunk</span><span class="plain"> = </span><span class="identifier">chunk</span><span class="plain">-&gt;</span><span class="identifier">next_ptoken</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">verb_conjugation</span><span class="plain"> *</span><span class="identifier">aux</span><span class="plain"> = </span><span class="functiontext">Conjugation::find_by_infinitive</span><span class="plain">(</span><span class="identifier">verb_lifted</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">aux</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">aux</span><span class="plain"> = </span><span class="functiontext">Conjugation::conjugate</span><span class="plain">(</span><span class="identifier">verb_lifted</span><span class="plain">, </span><span class="identifier">nl</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">aux</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"can't conjugate lifted verb"</span><span class="plain">);</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">verb_form_to_lift</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">case</span><span class="plain"> </span><span class="constant">1</span><span class="plain">: </span><span class="identifier">wa</span><span class="plain"> = </span><span class="identifier">WordAssemblages::join</span><span class="plain">(</span><span class="identifier">wa</span><span class="plain">, </span><span class="identifier">aux</span><span class="plain">-&gt;</span><span class="element">infinitive</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="constant">2</span><span class="plain">: </span><span class="identifier">wa</span><span class="plain"> = </span><span class="identifier">WordAssemblages::join</span><span class="plain">(</span><span class="identifier">wa</span><span class="plain">, </span><span class="identifier">aux</span><span class="plain">-&gt;</span><span class="element">present_participle</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="constant">3</span><span class="plain">: </span><span class="identifier">wa</span><span class="plain"> = </span><span class="identifier">WordAssemblages::join</span><span class="plain">(</span><span class="identifier">wa</span><span class="plain">, </span><span class="identifier">aux</span><span class="plain">-&gt;</span><span class="element">past_participle</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> -1: </span><span class="identifier">wa</span><span class="plain"> = </span><span class="identifier">WordAssemblages::join</span><span class="plain">(</span><span class="identifier">wa</span><span class="plain">, </span><span class="identifier">aux</span><span class="plain">-&gt;</span><span class="element">tabulations</span><span class="plain">[</span><span class="constant">ACTIVE_MOOD</span><span class="plain">].</span><span class="element">vc_text</span><span class="plain">[</span><span class="identifier">T</span><span class="plain">][</span><span class="identifier">S</span><span class="plain">][</span><span class="identifier">person</span><span class="plain">]);</span>
2019-03-17 14:40:57 +02:00
<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">"only parts 1, 2, 3 can be extracted"</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="reserved">continue</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP5_5"></a><b>&#167;5.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">A plus-plus-digit indicates auxiliary modal usage</span> <span class="cwebmacronumber">5.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">chunk</span><span class="plain">-&gt;</span><span class="identifier">ptoken_category</span><span class="plain"> == </span><span class="identifier">FIXED_WORD_PTC</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="identifier">Vocabulary::get_exemplar</span><span class="plain">(</span><span class="identifier">chunk</span><span class="plain">-&gt;</span><span class="identifier">ve_pt</span><span class="plain">, </span><span class="identifier">TRUE</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">p</span><span class="plain">[0] == </span><span class="character">'+'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">[1] == </span><span class="character">'+'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Characters::isdigit</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">[2])) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">[3] == </span><span class="constant">0</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">modal_following</span><span class="plain">) {</span>
<span class="plain">*</span><span class="identifier">modal_following</span><span class="plain"> = ((</span><span class="reserved">int</span><span class="plain">) </span><span class="identifier">p</span><span class="plain">[2]) - ((</span><span class="reserved">int</span><span class="plain">) </span><span class="character">'0'</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">continue</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="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>Whenever we read a single word, it passes through the following. A word
like "fish" will pass through unchanged; a number like "7" will convert
to verb form 7 in the current verb (for example, 2 becomes the present
participle); a plus sign joins two pieces together; and a tilde is a tie,
joining but with a space. Thus <code class="display"><span class="extract">fish~to~fry</span></code> becomes three words.
</p>
<pre class="display">
<span class="identifier">word_assemblage</span><span class="plain"> </span><span class="functiontext">Conjugation::expand_with_endings</span><span class="plain">(</span><span class="identifier">vocabulary_entry</span><span class="plain"> *</span><span class="identifier">ve</span><span class="plain">, </span><span class="identifier">word_assemblage</span><span class="plain"> *</span><span class="identifier">verb_forms</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ve</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">WordAssemblages::lit_0</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="identifier">Vocabulary::get_exemplar</span><span class="plain">(</span><span class="identifier">ve</span><span class="plain">, </span><span class="identifier">TRUE</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="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]; </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">i</span><span class="plain">&gt;0) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">+1]) &amp;&amp; ((</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] == </span><span class="character">'+'</span><span class="plain">) || (</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] == </span><span class="character">'~'</span><span class="plain">))) {</span>
<span class="identifier">vocabulary_entry</span><span class="plain"> *</span><span class="identifier">front</span><span class="plain"> =</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">Vocabulary::entry_for_partial_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">-1);</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">vocabulary_entry</span><span class="plain"> *</span><span class="identifier">back</span><span class="plain"> =</span>
<span class="identifier">Vocabulary::entry_for_partial_text</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">+1, </span><span class="identifier">Wide::len</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">)-1);</span>
<span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">front_wa</span><span class="plain"> = </span><span class="functiontext">Conjugation::expand_with_endings</span><span class="plain">(</span><span class="identifier">front</span><span class="plain">, </span><span class="identifier">verb_forms</span><span class="plain">);</span>
<span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">back_wa</span><span class="plain"> = </span><span class="functiontext">Conjugation::expand_with_endings</span><span class="plain">(</span><span class="identifier">back</span><span class="plain">, </span><span class="identifier">verb_forms</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">, </span><span class="string">"%A"</span><span class="plain">, &amp;</span><span class="identifier">front_wa</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] == </span><span class="character">'~'</span><span class="plain">) </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">, </span><span class="character">' '</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">, </span><span class="string">"%A"</span><span class="plain">, &amp;</span><span class="identifier">back_wa</span><span class="plain">);</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain"> = </span><span class="identifier">Feeds::feed_stream</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">WordAssemblages::from_wording</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">X</span><span class="plain"> = </span><span class="functiontext">Conjugation::ve_to_verb_form_number</span><span class="plain">(</span><span class="identifier">ve</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">X</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">verb_forms</span><span class="plain">[</span><span class="identifier">X</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">WordAssemblages::lit_1</span><span class="plain">(</span><span class="identifier">ve</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Conjugation::expand_with_endings is used in <a href="#SP4_2_1">&#167;4.2.1</a>, <a href="#SP5_1">&#167;5.1</a>, <a href="#SP5_4">&#167;5.4</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>The final step in merging verb material is to pass the result through the
following, which attends to contractions. (Most of the time it does nothing.)
For example, suppose we have:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">ne-' ai pas</span>
</pre>
<p class="inwebparagraph">The <code class="display"><span class="extract">-'</span></code> marker tells us that the word it attaches to should contract if a
vowel follows it. In this case that's what happens, so we convert to:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">n'ai pas</span>
</pre>
<p class="inwebparagraph">On the other hand,
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">ne-' jette pas</span>
</pre>
<p class="inwebparagraph">would convert to
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">ne jette pas</span>
</pre>
<p class="inwebparagraph">with no contraction. Either way, though, we have to take some action when
we see a <code class="display"><span class="extract">-'</span></code> marker.
</p>
<pre class="display">
<span class="identifier">word_assemblage</span><span class="plain"> </span><span class="functiontext">Conjugation::shorten_with_contractions</span><span class="plain">(</span><span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">wa</span><span class="plain">) {</span>
<span class="identifier">vocabulary_entry</span><span class="plain"> **</span><span class="identifier">words</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">word_count</span><span class="plain">;</span>
<span class="identifier">WordAssemblages::as_array</span><span class="plain">(&amp;</span><span class="identifier">wa</span><span class="plain">, &amp;</span><span class="identifier">words</span><span class="plain">, &amp;</span><span class="identifier">word_count</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="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">word_count</span><span class="plain">-1; </span><span class="identifier">i</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="identifier">Vocabulary::get_exemplar</span><span class="plain">(</span><span class="identifier">words</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">], </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">q</span><span class="plain"> = </span><span class="identifier">Vocabulary::get_exemplar</span><span class="plain">(</span><span class="identifier">words</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">+1], </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> = </span><span class="identifier">Wide::len</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">)-2;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">j</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] == </span><span class="character">'-'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">+1] == </span><span class="character">'\''</span><span class="plain">)) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">contract_this</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Decide whether a contraction is needed here</span> <span class="cwebmacronumber">7.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">contract_this</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain">=0; </span><span class="identifier">k</span><span class="plain">&lt;</span><span class="identifier">j</span><span class="plain">-1; </span><span class="identifier">k</span><span class="plain">++) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">, </span><span class="string">"%c"</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">k</span><span class="plain">]); }</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">, </span><span class="string">"'%w"</span><span class="plain">, </span><span class="identifier">q</span><span class="plain">);</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain"> = </span><span class="identifier">Feeds::feed_stream</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">);</span>
<span class="identifier">words</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">));</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain">=</span><span class="identifier">i</span><span class="plain">+1; </span><span class="identifier">k</span><span class="plain">&lt;</span><span class="identifier">word_count</span><span class="plain">; </span><span class="identifier">k</span><span class="plain">++) </span><span class="identifier">words</span><span class="plain">[</span><span class="identifier">k</span><span class="plain">] = </span><span class="identifier">words</span><span class="plain">[</span><span class="identifier">k</span><span class="plain">+1];</span>
<span class="identifier">word_count</span><span class="plain">--;</span>
<span class="identifier">WordAssemblages::truncate_to</span><span class="plain">(&amp;</span><span class="identifier">wa</span><span class="plain">, </span><span class="identifier">word_count</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain">=0; </span><span class="identifier">k</span><span class="plain">&lt;</span><span class="identifier">j</span><span class="plain">; </span><span class="identifier">k</span><span class="plain">++) { </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">, </span><span class="string">"%c"</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">k</span><span class="plain">]); }</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain"> = </span><span class="identifier">Feeds::feed_stream</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">);</span>
<span class="identifier">words</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">TEMP</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">wa</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Conjugation::shorten_with_contractions is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP7_1"></a><b>&#167;7.1. </b>We contract if the following word starts with a (possibly accented) vowel,
and we construe "y" (but not "h" or "w") as a vowel.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Decide whether a contraction is needed here</span> <span class="cwebmacronumber">7.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">incipit</span><span class="plain"> = </span><span class="identifier">q</span><span class="plain">[0];</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">first</span><span class="plain"> = </span><span class="identifier">tolower</span><span class="plain">(</span><span class="identifier">Characters::remove_accent</span><span class="plain">(</span><span class="identifier">incipit</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">first</span><span class="plain"> == </span><span class="character">'a'</span><span class="plain">) || (</span><span class="identifier">first</span><span class="plain"> == </span><span class="character">'e'</span><span class="plain">) || (</span><span class="identifier">first</span><span class="plain"> == </span><span class="character">'i'</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">first</span><span class="plain"> == </span><span class="character">'o'</span><span class="plain">) || (</span><span class="identifier">first</span><span class="plain"> == </span><span class="character">'u'</span><span class="plain">) || (</span><span class="identifier">first</span><span class="plain"> == </span><span class="character">'y'</span><span class="plain">))</span>
<span class="identifier">contract_this</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Parsing verb form numbers. </b>These are easy: they're just written as arabic numbers.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Conjugation::ptoken_to_verb_form_number</span><span class="plain">(</span><span class="identifier">ptoken</span><span class="plain"> *</span><span class="identifier">pt</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">pt</span><span class="plain">) &amp;&amp; (</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="identifier">ptoken_category</span><span class="plain"> == </span><span class="identifier">FIXED_WORD_PTC</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Conjugation::ve_to_verb_form_number</span><span class="plain">(</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="identifier">ve_pt</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> -1;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Conjugation::ve_to_verb_form_number</span><span class="plain">(</span><span class="identifier">vocabulary_entry</span><span class="plain"> *</span><span class="identifier">ve</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Vocabulary::test_vflags</span><span class="plain">(</span><span class="identifier">ve</span><span class="plain">, </span><span class="identifier">NUMBER_MC</span><span class="plain">)) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">Vocabulary::get_literal_number_value</span><span class="plain">(</span><span class="identifier">ve</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">X</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">X</span><span class="plain"> &lt; </span><span class="constant">MAX_FORM_TYPES</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">X</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"> -1;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Conjugation::ptoken_to_verb_form_number is used in <a href="#SP4_2_1">&#167;4.2.1</a>, <a href="#SP5_3">&#167;5.3</a>.</p>
<p class="endnote">The function Conjugation::ve_to_verb_form_number is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Parsing tense and sense indicators. </b>These are a little harder: for example, <code class="display"><span class="extract">t2+</span></code> or <code class="display"><span class="extract">t3</span></code>.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Conjugation::ptoken_to_tense_indicator</span><span class="plain">(</span><span class="identifier">ptoken</span><span class="plain"> *</span><span class="identifier">pt</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">set_sense</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">pt</span><span class="plain">) &amp;&amp; (</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="identifier">ptoken_category</span><span class="plain"> == </span><span class="identifier">FIXED_WORD_PTC</span><span class="plain">)) {</span>
<span class="identifier">vocabulary_entry</span><span class="plain"> *</span><span class="identifier">ve</span><span class="plain"> = </span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="identifier">ve_pt</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="identifier">Vocabulary::get_exemplar</span><span class="plain">(</span><span class="identifier">ve</span><span class="plain">, </span><span class="identifier">FALSE</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">p</span><span class="plain">[0] == </span><span class="character">'t'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Characters::isdigit</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">[1])) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">[2] == </span><span class="constant">0</span><span class="plain">)) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">[1] - </span><span class="character">'1'</span><span class="plain"> + </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">N</span><span class="plain"> &gt;= </span><span class="constant">1</span><span class="plain">) &amp;&amp; (</span><span class="identifier">N</span><span class="plain"> &lt;= </span><span class="constant">NO_KNOWN_TENSES</span><span class="plain">)) </span><span class="reserved">return</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>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">p</span><span class="plain">[0] == </span><span class="character">'t'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Characters::isdigit</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">[1])) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">[2] == </span><span class="character">'+'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">[3] == </span><span class="constant">0</span><span class="plain">)) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">[1] - </span><span class="character">'1'</span><span class="plain"> + </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">N</span><span class="plain"> &gt;= </span><span class="constant">1</span><span class="plain">) &amp;&amp; (</span><span class="identifier">N</span><span class="plain"> &lt;= </span><span class="constant">NO_KNOWN_TENSES</span><span class="plain">)) {</span>
<span class="plain">*</span><span class="identifier">set_sense</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">N</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</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">p</span><span class="plain">[0] == </span><span class="character">'t'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Characters::isdigit</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">[1])) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">[2] == </span><span class="character">'-'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">p</span><span class="plain">[3] == </span><span class="constant">0</span><span class="plain">)) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">[1] - </span><span class="character">'1'</span><span class="plain"> + </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">N</span><span class="plain"> &gt;= </span><span class="constant">1</span><span class="plain">) &amp;&amp; (</span><span class="identifier">N</span><span class="plain"> &lt;= </span><span class="constant">NO_KNOWN_TENSES</span><span class="plain">)) {</span>
<span class="plain">*</span><span class="identifier">set_sense</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="identifier">N</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>
<span class="reserved">return</span><span class="plain"> -1;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Conjugation::ptoken_to_tense_indicator is used in <a href="#SP5_4">&#167;5.4</a>.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. Parsing utilities. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Conjugation::ptoken_as_bracket</span><span class="plain">(</span><span class="identifier">ptoken</span><span class="plain"> *</span><span class="identifier">pt</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">pt</span><span class="plain">) &amp;&amp; (</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="identifier">ptoken_category</span><span class="plain"> == </span><span class="identifier">FIXED_WORD_PTC</span><span class="plain">)) {</span>
<span class="identifier">vocabulary_entry</span><span class="plain"> *</span><span class="identifier">ve</span><span class="plain"> = </span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="identifier">ve_pt</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">ve</span><span class="plain"> == </span><span class="identifier">OPENBRACKET_V</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">if</span><span class="plain"> (</span><span class="identifier">ve</span><span class="plain"> == </span><span class="identifier">CLOSEBRACKET_V</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> -1;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">return</span><span class="plain"> </span><span class="constant">0</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 Conjugation::ptoken_as_bracket is used in <a href="#SP5_3">&#167;5.3</a>, <a href="#SP5_4">&#167;5.4</a>.</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>In the following, for example, "breveter" as <code class="display"><span class="extract">ve</span></code> would match "-veter"
as <code class="display"><span class="extract">pattern</span></code>.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Conjugation::compare_ve_with_tails</span><span class="plain">(</span><span class="identifier">vocabulary_entry</span><span class="plain"> *</span><span class="identifier">ve</span><span class="plain">, </span><span class="identifier">vocabulary_entry</span><span class="plain"> *</span><span class="identifier">pattern</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ve</span><span class="plain"> == </span><span class="identifier">pattern</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="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">Vocabulary::get_exemplar</span><span class="plain">(</span><span class="identifier">pattern</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">p</span><span class="plain">[0] == </span><span class="character">'-'</span><span class="plain">) {</span>
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">q</span><span class="plain"> = </span><span class="identifier">Vocabulary::get_exemplar</span><span class="plain">(</span><span class="identifier">ve</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">j</span><span class="plain"> = </span><span class="identifier">Wide::len</span><span class="plain">(</span><span class="identifier">q</span><span class="plain">)-(</span><span class="identifier">Wide::len</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">)-1);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=1; </span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]; </span><span class="identifier">i</span><span class="plain">++, </span><span class="identifier">j</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">j</span><span class="plain">&lt;0) || (</span><span class="identifier">p</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] != </span><span class="identifier">q</span><span class="plain">[</span><span class="identifier">j</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>
<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 Conjugation::compare_ve_with_tails is used in <a href="#SP4_1_1_1">&#167;4.1.1.1</a>.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. Errors. </b>People are going to get their conjugations wrong; it's a very hard notation
to learn. No end users of Inform will ever write them at all &mdash; this is a
low-level feature for translators only &mdash; but translators need all the help
they can get, so we'll try to provide good problem messages.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Conjugation::trie_definition_error</span><span class="plain">(</span><span class="identifier">nonterminal</span><span class="plain"> *</span><span class="identifier">nt</span><span class="plain">, </span><span class="identifier">production</span><span class="plain"> *</span><span class="identifier">pr</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">message</span><span class="plain">) {</span>
<span class="functiontext">Conjugation::basic_problem_handler</span><span class="plain">(</span><span class="identifier">WordAssemblages::lit_0</span><span class="plain">(), </span><span class="identifier">nt</span><span class="plain">, </span><span class="identifier">pr</span><span class="plain">, </span><span class="identifier">message</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 Conjugation::trie_definition_error is used in 2/np (<a href="2-np.html#SP7_1">&#167;7.1</a>, <a href="2-np.html#SP7_1_1">&#167;7.1.1</a>, <a href="2-np.html#SP7_1_1_1">&#167;7.1.1.1</a>).</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>And similarly:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Conjugation::error</span><span class="plain">(</span><span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">base_text</span><span class="plain">, </span><span class="identifier">nonterminal</span><span class="plain"> *</span><span class="identifier">nt</span><span class="plain">,</span>
<span class="identifier">production</span><span class="plain"> *</span><span class="identifier">pr</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">message</span><span class="plain">) {</span>
<span class="functiontext">Conjugation::basic_problem_handler</span><span class="plain">(</span><span class="identifier">base_text</span><span class="plain">, </span><span class="identifier">nt</span><span class="plain">, </span><span class="identifier">pr</span><span class="plain">, </span><span class="identifier">message</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">exit</span><span class="plain">(1);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Conjugation::error is used in <a href="#SP2_3_2">&#167;2.3.2</a>, <a href="#SP2_3_2_1_1">&#167;2.3.2.1.1</a>, <a href="#SP4">&#167;4</a>, <a href="#SP4_1_1">&#167;4.1.1</a>, <a href="#SP4_2">&#167;4.2</a>.</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. </b>Some tools using this module will want to push simple error messages out to
the command line; others will want to translate them into elaborate problem
texts in HTML. So the client is allowed to define <code class="display"><span class="extract">SYNTAX_PROBLEM_HANDLER</span></code>
to some routine of her own, gazumping this one.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Conjugation::basic_problem_handler</span><span class="plain">(</span><span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">base_text</span><span class="plain">, </span><span class="identifier">nonterminal</span><span class="plain"> *</span><span class="identifier">nt</span><span class="plain">,</span>
<span class="identifier">production</span><span class="plain"> *</span><span class="identifier">pr</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">message</span><span class="plain">) {</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">INFLECTIONS_ERROR_HANDLER</span>
<span class="identifier">INFLECTIONS_ERROR_HANDLER</span><span class="plain">(</span><span class="identifier">base_text</span><span class="plain">, </span><span class="identifier">nt</span><span class="plain">, </span><span class="identifier">pr</span><span class="plain">, </span><span class="identifier">message</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">#</span><span class="identifier">ifndef</span><span class="plain"> </span><span class="identifier">INFLECTIONS_ERROR_HANDLER</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pr</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"The production at fault is:\n"</span><span class="plain">);</span>
<span class="identifier">Preform::log_production</span><span class="plain">(</span><span class="identifier">pr</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">); </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"\n"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">ERM</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nt</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">ERM</span><span class="plain">, </span><span class="string">"(no nonterminal)"</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">ERM</span><span class="plain">, </span><span class="string">"nonterminal %w"</span><span class="plain">, </span><span class="identifier">Vocabulary::get_exemplar</span><span class="plain">(</span><span class="identifier">nt</span><span class="plain">-&gt;</span><span class="identifier">nonterminal_id</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">));</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">ERM</span><span class="plain">, </span><span class="string">": "</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">WordAssemblages::nonempty</span><span class="plain">(</span><span class="identifier">base_text</span><span class="plain">))</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">ERM</span><span class="plain">, </span><span class="string">"can't conjugate verb '%A': "</span><span class="plain">, &amp;</span><span class="identifier">base_text</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pr</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">ptoken</span><span class="plain"> *</span><span class="identifier">pt</span><span class="plain"> = </span><span class="identifier">pr</span><span class="plain">-&gt;</span><span class="identifier">first_ptoken</span><span class="plain">; </span><span class="identifier">pt</span><span class="plain">; </span><span class="identifier">pt</span><span class="plain"> = </span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="identifier">next_ptoken</span><span class="plain">) {</span>
<span class="identifier">Preform::write_ptoken</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">, </span><span class="identifier">pt</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pt</span><span class="plain">-&gt;</span><span class="identifier">next_ptoken</span><span class="plain">) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">, </span><span class="string">" "</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">ERM</span><span class="plain">, </span><span class="string">"line %d ('%S'): "</span><span class="plain">, </span><span class="identifier">pr</span><span class="plain">-&gt;</span><span class="identifier">match_number</span><span class="plain">, </span><span class="identifier">TEMP</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">ERM</span><span class="plain">, </span><span class="string">"%s"</span><span class="plain">, </span><span class="identifier">message</span><span class="plain">);</span>
<span class="identifier">Errors::with_text</span><span class="plain">(</span><span class="string">"Preform error: %S"</span><span class="plain">, </span><span class="identifier">ERM</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">ERM</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Conjugation::basic_problem_handler is used in <a href="#SP12">&#167;12</a>, <a href="#SP13">&#167;13</a>.</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. Testing. </b>Similarly, the following helps translators by giving them unit tests for their
2019-03-17 14:40:57 +02:00
conjugations:
</p>
<blockquote>
<p>Test verb (internal) with appuyer.</p>
</blockquote>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Conjugation::test</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">PREFORM_LANGUAGE_TYPE</span><span class="plain"> *</span><span class="identifier">nl</span><span class="plain">) {</span>
<span class="reserved">verb_conjugation</span><span class="plain"> *</span><span class="identifier">vc</span><span class="plain"> = </span><span class="functiontext">Conjugation::conjugate</span><span class="plain">(</span>
<span class="identifier">WordAssemblages::from_wording</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">), </span><span class="identifier">nl</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">vc</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) { </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Failed test\n"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
2019-03-17 14:40:57 +02:00
<span class="functiontext">Conjugation::write</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">vc</span><span class="plain">);</span>
<span class="identifier">DESTROY</span><span class="plain">(</span><span class="identifier">vc</span><span class="plain">, </span><span class="reserved">verb_conjugation</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Conjugation::write</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">verb_conjugation</span><span class="plain"> *</span><span class="identifier">vc</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Infinitive: %A / Present participle: %A / Past participle: %A^"</span><span class="plain">,</span>
2020-04-07 03:06:09 +03:00
<span class="plain">&amp;(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">infinitive</span><span class="plain">), &amp;(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">present_participle</span><span class="plain">), &amp;(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">past_participle</span><span class="plain">));</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">mood_count</span><span class="plain"> = </span><span class="constant">2</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">WordAssemblages::nonempty</span><span class="plain">(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">tabulations</span><span class="plain">[</span><span class="constant">PASSIVE_MOOD</span><span class="plain">].</span><span class="element">to_be_auxiliary</span><span class="plain">)) </span><span class="identifier">mood_count</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">mood</span><span class="plain">, </span><span class="identifier">sense</span><span class="plain">, </span><span class="identifier">tense</span><span class="plain">, </span><span class="identifier">person</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">mood</span><span class="plain">=0; </span><span class="identifier">mood</span><span class="plain">&lt;</span><span class="identifier">mood_count</span><span class="plain">; </span><span class="identifier">mood</span><span class="plain">++) {</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">sense</span><span class="plain">=0; </span><span class="identifier">sense</span><span class="plain">&lt;2; </span><span class="identifier">sense</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">mood</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Active "</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">"Passive "</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sense</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"positive^"</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">"negative^"</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">tense</span><span class="plain">=0; </span><span class="identifier">tense</span><span class="plain">&lt;7; </span><span class="identifier">tense</span><span class="plain">++) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Tense %d: "</span><span class="plain">, </span><span class="identifier">tense</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">person</span><span class="plain">=0; </span><span class="identifier">person</span><span class="plain">&lt;6; </span><span class="identifier">person</span><span class="plain">++) {</span>
<span class="identifier">word_assemblage</span><span class="plain"> *</span><span class="identifier">wa</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">mood</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">wa</span><span class="plain"> = &amp;(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">tabulations</span><span class="plain">[</span><span class="constant">ACTIVE_MOOD</span><span class="plain">].</span><span class="element">vc_text</span><span class="plain">[</span><span class="identifier">tense</span><span class="plain">][</span><span class="identifier">sense</span><span class="plain">][</span><span class="identifier">person</span><span class="plain">]);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">wa</span><span class="plain"> = &amp;(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">tabulations</span><span class="plain">[</span><span class="constant">PASSIVE_MOOD</span><span class="plain">].</span><span class="element">vc_text</span><span class="plain">[</span><span class="identifier">tense</span><span class="plain">][</span><span class="identifier">sense</span><span class="plain">][</span><span class="identifier">person</span><span class="plain">]);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">person</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" / "</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">WordAssemblages::nonempty</span><span class="plain">(*</span><span class="identifier">wa</span><span class="plain">)) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%A"</span><span class="plain">, </span><span class="identifier">wa</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">"--"</span><span class="plain">);</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>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">WordAssemblages::nonempty</span><span class="plain">(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">tabulations</span><span class="plain">[</span><span class="constant">PASSIVE_MOOD</span><span class="plain">].</span><span class="element">to_be_auxiliary</span><span class="plain">))</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Form passive as to be + %A\n"</span><span class="plain">, &amp;(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">tabulations</span><span class="plain">[</span><span class="constant">PASSIVE_MOOD</span><span class="plain">].</span><span class="element">to_be_auxiliary</span><span class="plain">));</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="reserved">verb_conjugation</span><span class="plain"> *</span><span class="functiontext">Conjugation::find_by_infinitive</span><span class="plain">(</span><span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">infinitive</span><span class="plain">) {</span>
<span class="reserved">verb_conjugation</span><span class="plain"> *</span><span class="identifier">vc</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">vc</span><span class="plain">, </span><span class="reserved">verb_conjugation</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">WordAssemblages::compare</span><span class="plain">(&amp;</span><span class="identifier">infinitive</span><span class="plain">, &amp;(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">infinitive</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">vc</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">verb_conjugation</span><span class="plain"> *</span><span class="functiontext">Conjugation::find_prior</span><span class="plain">(</span><span class="reserved">verb_conjugation</span><span class="plain"> *</span><span class="identifier">nvc</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nvc</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">verb_conjugation</span><span class="plain"> *</span><span class="identifier">vc</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">vc</span><span class="plain">, </span><span class="reserved">verb_conjugation</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">vc</span><span class="plain"> != </span><span class="identifier">nvc</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">WordAssemblages::compare</span><span class="plain">(&amp;(</span><span class="identifier">nvc</span><span class="plain">-&gt;</span><span class="element">infinitive</span><span class="plain">), &amp;(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">infinitive</span><span class="plain">)) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">WordAssemblages::compare</span><span class="plain">(&amp;(</span><span class="identifier">nvc</span><span class="plain">-&gt;</span><span class="element">past_participle</span><span class="plain">), &amp;(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">past_participle</span><span class="plain">)) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">WordAssemblages::compare</span><span class="plain">(&amp;(</span><span class="identifier">nvc</span><span class="plain">-&gt;</span><span class="element">present_participle</span><span class="plain">), &amp;(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">present_participle</span><span class="plain">)) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">continue</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">match</span><span class="plain"> = </span><span class="identifier">TRUE</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">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="constant">NO_KNOWN_MOODS</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">verb_tabulation</span><span class="plain"> *</span><span class="identifier">nvt</span><span class="plain"> = &amp;(</span><span class="identifier">nvc</span><span class="plain">-&gt;</span><span class="element">tabulations</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]);</span>
<span class="reserved">verb_tabulation</span><span class="plain"> *</span><span class="identifier">vt</span><span class="plain"> = &amp;(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">tabulations</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">WordAssemblages::compare</span><span class="plain">(&amp;(</span><span class="identifier">nvt</span><span class="plain">-&gt;</span><span class="element">to_be_auxiliary</span><span class="plain">), &amp;(</span><span class="identifier">vt</span><span class="plain">-&gt;</span><span class="element">to_be_auxiliary</span><span class="plain">)) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">match</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">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">p</span><span class="plain">=0; </span><span class="identifier">p</span><span class="plain">&lt;6; </span><span class="identifier">p</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">s</span><span class="plain">=0; </span><span class="identifier">s</span><span class="plain">&lt;2; </span><span class="identifier">s</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">t</span><span class="plain">=0; </span><span class="identifier">t</span><span class="plain">&lt;</span><span class="constant">NO_KNOWN_TENSES</span><span class="plain">; </span><span class="identifier">t</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">WordAssemblages::compare</span><span class="plain">(&amp;(</span><span class="identifier">nvt</span><span class="plain">-&gt;</span><span class="element">vc_text</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">][</span><span class="identifier">s</span><span class="plain">][</span><span class="identifier">p</span><span class="plain">]), &amp;(</span><span class="identifier">vt</span><span class="plain">-&gt;</span><span class="element">vc_text</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">][</span><span class="identifier">s</span><span class="plain">][</span><span class="identifier">p</span><span class="plain">])) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">match</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">nvt</span><span class="plain">-&gt;</span><span class="element">modal_auxiliary_usage</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">][</span><span class="identifier">s</span><span class="plain">][</span><span class="identifier">p</span><span class="plain">] != </span><span class="identifier">vt</span><span class="plain">-&gt;</span><span class="element">modal_auxiliary_usage</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">][</span><span class="identifier">s</span><span class="plain">][</span><span class="identifier">p</span><span class="plain">]) </span><span class="identifier">match</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">match</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">vc</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">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Conjugation::test appears nowhere else.</p>
<p class="endnote">The function Conjugation::write appears nowhere else.</p>
<p class="endnote">The function Conjugation::find_by_infinitive is used in <a href="#SP5_4">&#167;5.4</a>.</p>
<p class="endnote">The function Conjugation::find_prior appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. </b>This is for testing English only; it helps with the test suite cases derived
2019-03-17 14:40:57 +02:00
from our dictionary of 14,000 or so present and past participles.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Conjugation::test_participle</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">verb_conjugation</span><span class="plain"> *</span><span class="identifier">vc</span><span class="plain"> = </span><span class="functiontext">Conjugation::conjugate</span><span class="plain">(</span>
<span class="identifier">WordAssemblages::from_wording</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">), </span><span class="identifier">English_language</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">vc</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) { </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Failed test\n"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
2019-03-17 14:40:57 +02:00
<span class="functiontext">Conjugation::write_participle</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">vc</span><span class="plain">);</span>
<span class="identifier">DESTROY</span><span class="plain">(</span><span class="identifier">vc</span><span class="plain">, </span><span class="reserved">verb_conjugation</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Conjugation::write_participle</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">verb_conjugation</span><span class="plain"> *</span><span class="identifier">vc</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"To %A: he is %A; it was %A.\n"</span><span class="plain">,</span>
<span class="plain">&amp;(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">infinitive</span><span class="plain">), &amp;(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">present_participle</span><span class="plain">), &amp;(</span><span class="identifier">vc</span><span class="plain">-&gt;</span><span class="element">past_participle</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 Conjugation::test_participle appears nowhere else.</p>
<p class="endnote">The function Conjugation::write_participle appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. </b>As noted above, these nonterminals have no parsing function, and are used only
2019-03-17 14:40:57 +02:00
as markers in verb conjugations.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">auxiliary</span><span class="plain">-</span><span class="identifier">verb</span><span class="plain">-</span><span class="identifier">only</span><span class="plain">&gt; </span><span class="identifier">internal</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">&lt;</span><span class="identifier">not</span><span class="plain">-</span><span class="identifier">instance</span><span class="plain">-</span><span class="identifier">of</span><span class="plain">-</span><span class="identifier">verb</span><span class="plain">-</span><span class="identifier">at</span><span class="plain">-</span><span class="identifier">run</span><span class="plain">-</span><span class="identifier">time</span><span class="plain">&gt; </span><span class="identifier">internal</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>
<hr class="tocbar">
<ul class="toc"><li><a href="3-pp.html">Back to 'Past Participles'</a></li><li><i>(This section ends Chapter 3: Grammatical Uses of Inflection.)</i></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>