1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 16:44:21 +03:00
inform7/docs/core-module/3-nl.html
2020-04-07 01:06:09 +01:00

243 lines
22 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/pwst</title>
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<nav role="navigation">
<h1><a href="../webs.html">Sources</a></h1>
<ul>
<li><a href="../compiler.html"><b>compiler tools</b></a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul>
<h2>Compiler Webs</h2>
<ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
</ul>
<h2>Inbuild Modules</h2>
<ul>
<li><a href="../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">
<!--Weave of '3/nl' generated by 7-->
<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">core</a></li><li><a href="index.html#3">Chapter 3: Bridge to Words Module</a></li><li><b>Natural Languages</b></li></ul><p class="purpose">To manage definitions of natural languages, such as English or French, which may be used either to write Inform or to read the works it compiles.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Indexing</a></li><li><a href="#SP3">&#167;3. Parsing</a></li><li><a href="#SP4">&#167;4. The natural language kind</a></li><li><a href="#SP5">&#167;5. The adaptive person</a></li><li><a href="#SP6">&#167;6. Including Preform syntax</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Indexing. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NaturalLanguages::produce_index</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">inform_project</span><span class="plain"> *</span><span class="identifier">project</span><span class="plain"> = </span><span class="functiontext">Task::project</span><span class="plain">();</span>
<span class="functiontext">I6T::interpret_indext</span><span class="plain">(</span>
<span class="identifier">Filenames::in_folder</span><span class="plain">(</span>
<span class="identifier">Languages::path_to_bundle</span><span class="plain">(</span>
<span class="identifier">Projects::get_language_of_index</span><span class="plain">(</span><span class="identifier">project</span><span class="plain">)),</span>
<span class="identifier">Projects::index_structure</span><span class="plain">(</span><span class="identifier">project</span><span class="plain">)));</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NaturalLanguages::produce_index is used in 1/htc (<a href="1-htc.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b></p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">NATURAL_LANGUAGES_PRESENT</span>
</pre>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. Parsing. </b>The following matches the English-language name of a language: for example,
"French". It will only make a match if Inform has successfully found a
bundle for that language during its initial scan.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">natural</span><span class="plain">-</span><span class="identifier">language</span><span class="plain">&gt; </span><span class="identifier">internal</span><span class="plain"> {</span>
<span class="identifier">inform_language</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">, </span><span class="identifier">inform_language</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::match</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">Wordings::first_word</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">-&gt;</span><span class="identifier">instance_name</span><span class="plain">))) {</span>
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">L</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="inwebparagraph"><a id="SP4"></a><b>&#167;4. The natural language kind. </b>Inform has a kind built in called "natural language", whose values are
enumerated names: English language, French language, German language and so on.
When the kind is created, the following routine makes these instances. We do
this exactly as we would to create any other instance &mdash; we write a logical
proposition claiming its existence, then assert this to be true. It's an
interesting question whether the possibility of the game having been written
in German "belongs" in the model world, if in fact the game wasn't written
in German; but this is how we'll do it, anyway.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NaturalLanguages::stock_nl_kind</span><span class="plain">(</span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="identifier">inform_language</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">, </span><span class="identifier">inform_language</span><span class="plain">) {</span>
<span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain"> =</span>
<span class="functiontext">Calculus::Propositions::Abstract::to_create_something</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-&gt;</span><span class="identifier">instance_name</span><span class="plain">);</span>
<span class="functiontext">Calculus::Propositions::Assert::assert_true</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">CERTAIN_CE</span><span class="plain">);</span>
<span class="identifier">L</span><span class="plain">-&gt;</span><span class="identifier">nl_instance</span><span class="plain"> = </span><span class="identifier">latest_instance</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NaturalLanguages::stock_nl_kind appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. The adaptive person. </b>The following is only relevant for the language of play, whose extension will
always be read in. That in turn is expected to contain a declaration like
this one:
</p>
<blockquote>
<p>The adaptive text viewpoint of the French language is second person singular.</p>
</blockquote>
<p class="inwebparagraph">The following routine picks up on the result of this declaration. (We cache
this because we need access to it very quickly when parsing text substitutions.)
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">NaturalLanguages::adaptive_person</span><span class="plain">(</span><span class="identifier">inform_language</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">) {</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">L</span><span class="plain">-&gt;</span><span class="identifier">adaptive_person</span><span class="plain"> == -1) &amp;&amp; (</span><span class="identifier">P_adaptive_text_viewpoint</span><span class="plain">)) {</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="identifier">L</span><span class="plain">-&gt;</span><span class="identifier">nl_instance</span><span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="functiontext">World::Inferences::get_prop_state</span><span class="plain">(</span>
<span class="functiontext">Instances::as_subject</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">P_adaptive_text_viewpoint</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">CONSTANT_NT</span><span class="plain">)) {</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain"> = </span><span class="identifier">ParseTree::get_constant_instance</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="identifier">L</span><span class="plain">-&gt;</span><span class="identifier">adaptive_person</span><span class="plain"> = </span><span class="functiontext">Instances::get_numerical_value</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">)-1;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">L</span><span class="plain">-&gt;</span><span class="identifier">adaptive_person</span><span class="plain"> == -1) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FIRST_PERSON_PLURAL</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">L</span><span class="plain">-&gt;</span><span class="identifier">adaptive_person</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NaturalLanguages::adaptive_person appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Including Preform syntax. </b>At present we do this only for English, but some day...
</p>
<pre class="display">
<span class="identifier">wording</span><span class="plain"> </span><span class="functiontext">NaturalLanguages::load_preform</span><span class="plain">(</span><span class="identifier">inform_language</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">L</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 load preform from null language"</span><span class="plain">);</span>
<span class="identifier">language_being_read_by_Preform</span><span class="plain"> = </span><span class="identifier">L</span><span class="plain">;</span>
<span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">preform_file</span><span class="plain"> = </span><span class="identifier">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">Languages::path_to_bundle</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">), </span><span class="identifier">I</span><span class="string">"Syntax.preform"</span><span class="plain">);</span>
<span class="identifier">PRINT</span><span class="plain">(</span><span class="string">"Reading language definition from &lt;%f&gt;\n"</span><span class="plain">, </span><span class="identifier">preform_file</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Preform::load_from_file</span><span class="plain">(</span><span class="identifier">preform_file</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NaturalLanguages::load_preform is used in 4/its (<a href="4-its.html#SP7">&#167;7</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>Preform errors are handled here:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NaturalLanguages::preform_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="reserved">if</span><span class="plain"> (</span><span class="identifier">pr</span><span class="plain">) {</span>
<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="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">Problems::quote_text</span><span class="plain">(1, </span><span class="string">"(no nonterminal)"</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">Problems::quote_wide_text</span><span class="plain">(1, </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">Problems::quote_text</span><span class="plain">(2, </span><span class="identifier">message</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">Untestable</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">Problems::quote_wa</span><span class="plain">(5, &amp;</span><span class="identifier">base_text</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"I'm having difficulties conjugating the verb '%5'. "</span><span class="plain">);</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">if</span><span class="plain"> (</span><span class="identifier">pr</span><span class="plain">) {</span>
<span class="identifier">Problems::quote_number</span><span class="plain">(3, &amp;(</span><span class="identifier">pr</span><span class="plain">-&gt;</span><span class="identifier">match_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">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">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">Problems::quote_stream</span><span class="plain">(4, </span><span class="identifier">TEMP</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"There's a problem in Inform's linguistic grammar, which is probably "</span>
<span class="string">"set by a translation extension. The problem occurs in line %3 of "</span>
<span class="string">"%1 ('%4'): %2."</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"There's a problem in Inform's linguistic grammar, which is probably "</span>
<span class="string">"set by a translation extension. The problem occurs in the definition of "</span>
<span class="string">"%1: %2."</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">Problems::issue_problem_end</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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NaturalLanguages::preform_error appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 3: Bridge to Words Module.)</i></li><li><a href="3-pd.html">Continue with 'Plural Dictionary'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>