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/5-nv.html
2020-04-07 01:06:09 +01:00

1248 lines
155 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>5/ins</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 '5/nv' 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#5">Chapter 5: Nouns</a></li><li><b>Nonlocal Variables</b></li></ul><p class="purpose">To manage variables whose scope is wider than the current rule.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Though the following structure is rather cluttered, the idea is simple
enough: a non-local variable &mdash; it may be global, or may belong to a rulebook,
an action, or an activity &mdash; is like a property, but simpler. It belongs to
no particular object, so we don't need to worry about permissions for it to
exist; we can simply record inferences about its value.
</p>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">nonlocal_variable_emission</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">iname_form</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">textual_form</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">nothing_form</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">stv_ID</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">stv_index</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">allow_outside</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">use_own_iname</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">nonlocal_variable_emission</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">nonlocal_variable</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">name</span><span class="plain">; </span><span class="comment">text of the name</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">nlv_created_at</span><span class="plain">; </span><span class="comment">sentence creating the variable</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">var_documentation_symbol</span><span class="plain">; </span><span class="comment">reference to manual, if any</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">stacked_variable</span><span class="plain"> *</span><span class="identifier">scope</span><span class="plain">; </span><span class="comment">where it exists, or <code class="display"><span class="extract">NULL</span></code> for everywhere</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">nlv_kind</span><span class="plain">; </span><span class="comment">what kind of value it holds</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">nlv_knowledge</span><span class="plain">; </span><span class="comment">what we know about its initial value</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">constant_at_run_time</span><span class="plain">; </span><span class="comment">for instance, for "story title"</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">alias_to_infs</span><span class="plain">; </span><span class="comment">like "player" to "yourself"</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">housed_in_variables_array</span><span class="plain">; </span><span class="comment">i.e. <code class="display"><span class="extract">FALSE</span></code> if stored elsewhere</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">var_is_initialisable_anyway</span><span class="plain">; </span><span class="comment">despite being stored elsewhere, that is</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">var_is_bibliographic</span><span class="plain">; </span><span class="comment">one of the bibliographic constants set at the end</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">var_is_allowed_to_be_zero</span><span class="plain">; </span><span class="comment">for an empty enumerated kind, despite non-safety</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">nlv_iname</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">nlv_name_translated</span><span class="plain">; </span><span class="comment">has this been given storage as an I6 variable?</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">nonlocal_variable_emission</span><span class="plain"> </span><span class="identifier">rvalue_nve</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">nonlocal_variable_emission</span><span class="plain"> </span><span class="identifier">lvalue_nve</span><span class="plain">;</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">nlv_write_schema</span><span class="plain">; </span><span class="comment">or <code class="display"><span class="extract">NULL</span></code> to assign to the L-value form</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">substitution_marker</span><span class="plain">; </span><span class="comment">to prevent infinite regress when substituting</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">nonlocal_variable</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure nonlocal_variable_emission is private to this section.</p>
<p class="endnote">The structure nonlocal_variable is accessed in 2/sq, 2/si, 5/ins, 8/ef, 9/ma, 9/pk, 11/sm, 14/lv, 14/ds2, 15/pr, 15/ep, 15/vp, 15/spr, 16/in, 16/cmw, 17/rs, 19/tc, 19/tb, 19/tod, 20/eq, 21/rl, 21/rl2, 21/fao, 21/rps, 21/sv, 21/ac, 22/pu, 22/dptd, 22/po, 22/pav, 25/cii, 26/uo, 26/ts and here.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>These three special NLVs are used for the "notable" hacky Standard Rules
variables mentioned below:
</p>
<pre class="display">
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">i6_glob_VAR</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">i6_nothing_VAR</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="comment">the I6 <code class="display"><span class="extract">nothing</span></code> constant</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">command_prompt_VAR</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="comment">the command prompt text</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">parameter_object_VAR</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>We record the one most recently made:
</p>
<pre class="display">
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">latest_nonlocal_variable</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>These are variable names which Inform provides special support for; it
recognises the English names when they are defined by the Standard Rules. (So
there is no need to translate this to other languages.) The first two are
hacky constructs which only the SR should ever refer to.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">notable</span><span class="plain">-</span><span class="identifier">variables</span><span class="plain">&gt; ::=</span>
<span class="identifier">i6</span><span class="plain">-</span><span class="identifier">varying</span><span class="plain">-</span><span class="identifier">global</span><span class="plain"> |</span>
<span class="identifier">i6</span><span class="plain">-</span><span class="identifier">nothing</span><span class="plain">-</span><span class="identifier">constant</span><span class="plain"> |</span>
<span class="identifier">command</span><span class="plain"> </span><span class="identifier">prompt</span><span class="plain"> |</span>
<span class="identifier">parameter</span><span class="plain">-</span><span class="identifier">object</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>We can create a new variable provided we give its name, kind and scope.
When the scope isn't global, the variable is said to be "stacked", which is a
reference to how it's stored at run-time.
</p>
<pre class="display">
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="functiontext">NonlocalVariables::new_global</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">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="constant">PROTECTED_MODEL_PROCEDURE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::new</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="functiontext">NonlocalVariables::new_stacked</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">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">,</span>
<span class="reserved">stacked_variable</span><span class="plain"> *</span><span class="identifier">scope</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">scope</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">"not a stacked nonlocal_variable at all"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::new</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">scope</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NonlocalVariables::new_global is used in 12/ap (<a href="12-ap.html#SP9_5_2">&#167;9.5.2</a>).</p>
<p class="endnote">The function NonlocalVariables::new_stacked is used in 21/sv (<a href="21-sv.html#SP3">&#167;3</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b></p>
<pre class="display">
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="functiontext">NonlocalVariables::new</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">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">, </span><span class="reserved">stacked_variable</span><span class="plain"> *</span><span class="identifier">scope</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</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">"created variable without kind"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Behaviour::definite</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span>&lt;<span class="cwebmacro">Issue problem message for an indefinite variable</span> <span class="cwebmacronumber">7.1</span>&gt;<span class="plain">;</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Actually create the nonlocal variable</span> <span class="cwebmacronumber">7.3</span>&gt;<span class="plain">;</span>
<span class="identifier">latest_nonlocal_variable</span><span class="plain"> = </span><span class="identifier">nlv</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Take note if the notable variables turn up here</span> <span class="cwebmacronumber">7.2</span>&gt;<span class="plain">;</span>
<span class="functiontext">Plugins::Call::new_variable_notify</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">VARIABLE_CREATIONS</span><span class="plain">, </span><span class="string">"Created non-library variable: $Z\n"</span><span class="plain">, </span><span class="identifier">nlv</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">nlv</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NonlocalVariables::new is used in <a href="#SP6">&#167;6</a>, <a href="#SP20">&#167;20</a>.</p>
<p class="inwebparagraph"><a id="SP7_1"></a><b>&#167;7.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue problem message for an indefinite variable</span> <span class="cwebmacronumber">7.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_wording</span><span class="plain">(1, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(2, </span><span class="identifier">K</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">PM_IndefiniteVariable</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"I am unable to create the variable '%1', because its kind (%2) is too "</span>
<span class="string">"vague. I need to know exactly what kind of value goes into each "</span>
<span class="string">"variable: for instance, it's not enough to say 'L is a list of values "</span>
<span class="string">"that varies', because I don't know what the entries have to be - 'L "</span>
<span class="string">"is a list of numbers that varies' would be better."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</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="SP7_2"></a><b>&#167;7.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Take note if the notable variables turn up here</span> <span class="cwebmacronumber">7.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">notable</span><span class="plain">-</span><span class="identifier">variables</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">)) {</span>
<span class="reserved">switch</span><span class="plain"> (&lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt;) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">0</span><span class="plain">: </span><span class="identifier">i6_glob_VAR</span><span class="plain"> = </span><span class="identifier">nlv</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">1</span><span class="plain">: </span><span class="identifier">i6_nothing_VAR</span><span class="plain"> = </span><span class="identifier">nlv</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">command_prompt_VAR</span><span class="plain"> = </span><span class="identifier">nlv</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">parameter_object_VAR</span><span class="plain"> = </span><span class="identifier">nlv</span><span class="plain">; </span><span class="reserved">break</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="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7_3"></a><b>&#167;7.3. </b>Note that we only register the name of the variable as a meaning if it's
global, because it otherwise may mean different things in different places.
The knowledge about a variable is initially just that it is certainly a
variable; this means it inherits from the inference subject representing
all variables, and that in turn is good because it means it gets permission
to have the "initial value" property.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Actually create the nonlocal variable</span> <span class="cwebmacronumber">7.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">var_documentation_symbol</span><span class="plain"> = </span><span class="identifier">Index::DocReferences::position_of_symbol</span><span class="plain">(&amp;</span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">;</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_created_at</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_kind</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">;</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">rvalue_nve</span><span class="plain">.</span><span class="element">textual_form</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">(); </span><span class="comment">we won't decide their run-time storage until later</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">rvalue_nve</span><span class="plain">.</span><span class="element">iname_form</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">lvalue_nve</span><span class="plain">.</span><span class="element">textual_form</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">lvalue_nve</span><span class="plain">.</span><span class="element">iname_form</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">housed_in_variables_array</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_name_translated</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">alias_to_infs</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_write_schema</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">constant_at_run_time</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">var_is_initialisable_anyway</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">var_is_allowed_to_be_zero</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">scope</span><span class="plain"> = </span><span class="identifier">scope</span><span class="plain">;</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">substitution_marker</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) &amp;&amp; (</span><span class="identifier">scope</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="comment">that is, if it's a global</span>
<span class="identifier">Nouns::new_proper_noun</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">NEUTER_GENDER</span><span class="plain">,</span>
<span class="identifier">REGISTER_SINGULAR_NTOPT</span><span class="plain"> + </span><span class="identifier">PARSE_EXACTLY_NTOPT</span><span class="plain">,</span>
<span class="constant">VARIABLE_MC</span><span class="plain">, </span><span class="functiontext">Lvalues::new_actual_NONLOCAL_VARIABLE</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">));</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_knowledge</span><span class="plain"> =</span>
<span class="functiontext">InferenceSubjects::new</span><span class="plain">(</span><span class="identifier">nonlocal_variables</span><span class="plain">,</span>
<span class="constant">VARI_SUB</span><span class="plain">, </span><span class="identifier">STORE_POINTER_nonlocal_variable</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">), </span><span class="identifier">CERTAIN_CE</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. </b>So much for creation; and here's how we log them:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::log</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nlv</span><span class="plain">== </span><span class="identifier">NULL</span><span class="plain">) { </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"&lt;null variable&gt;"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"'%W'(%s)[$u]"</span><span class="plain">, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">,</span>
<span class="plain">(</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">constant_at_run_time</span><span class="plain">)?</span><span class="string">"const"</span><span class="plain">:</span><span class="string">"var"</span><span class="plain">,</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_kind</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NonlocalVariables::log is used in 1/cm (<a href="1-cm.html#SP5">&#167;5</a>, <a href="1-cm.html#SP6_6">&#167;6.6</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>It turns out to be convenient to have this routine around. Note that
parsing only picks up globals (see note on name registration above).
</p>
<pre class="display">
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="functiontext">NonlocalVariables::parse</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">W</span><span class="plain"> = </span><span class="identifier">Articles::remove_the</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">global</span><span class="plain">-</span><span class="identifier">variable</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">)) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::get_constant_nonlocal_variable</span><span class="plain">(</span><span class="identifier">val</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 NonlocalVariables::parse is used in <a href="#SP10">&#167;10</a>, 9/rpt (<a href="9-rpt.html#SP16">&#167;16</a>), 25/cii (<a href="25-cii.html#SP8">&#167;8</a>).</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>We need the flexibility to store the variable's value in a range of
different ways at run-time. One way this is used is to allow the source
text (generally the Standard Rules) to say that an already-existing I6
variable should hold it:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::translates</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">parse_node</span><span class="plain"> *</span><span class="identifier">p2</span><span class="plain">) {</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::parse</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">nlv</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">scope</span><span class="plain">)) {</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Tried %W\n"</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::sentence_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">PM_NonQuantityTranslated</span><span class="plain">),</span>
<span class="string">"this is not the name of a variable"</span><span class="plain">,</span>
<span class="string">"or at any rate not one global in scope."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_name_translated</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_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">PM_QuantityTranslatedAlready</span><span class="plain">),</span>
<span class="string">"this variable has already been translated"</span><span class="plain">,</span>
<span class="string">"so there must be some duplication somewhere."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_name_translated</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">, </span><span class="string">"%N"</span><span class="plain">, </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p2</span><span class="plain">)));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"nothing"</span><span class="plain">)) {</span>
<span class="functiontext">NonlocalVariables::set_I6_identifier</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="functiontext">NonlocalVariables::nve_from_nothing</span><span class="plain">());</span>
<span class="functiontext">NonlocalVariables::set_I6_identifier</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="functiontext">NonlocalVariables::nve_from_nothing</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">as_iname</span><span class="plain"> = </span><span class="identifier">Produce::find_by_name</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">name</span><span class="plain">);</span>
<span class="functiontext">NonlocalVariables::set_I6_identifier</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="functiontext">NonlocalVariables::nve_from_iname</span><span class="plain">(</span><span class="identifier">as_iname</span><span class="plain">));</span>
<span class="functiontext">NonlocalVariables::set_I6_identifier</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="functiontext">NonlocalVariables::nve_from_iname</span><span class="plain">(</span><span class="identifier">as_iname</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">VARIABLE_CREATIONS</span><span class="plain">,</span>
<span class="string">"Translated variable: $Z as %N\n"</span><span class="plain">, </span><span class="identifier">nlv</span><span class="plain">, </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">p2</span><span class="plain">)));</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NonlocalVariables::translates is used in 26/tti (<a href="26-tti.html#SP5_1">&#167;5.1</a>).</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>In general, the following allows us to set the R-value and L-value forms
of the variable's storage. An R-value is the form of the variable on the
right-hand side of an assignment, that is, when we're reading it; an L-value
is the form used when we're setting it. Often these will be the same, but
not always.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::set_I6_identifier</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">left</span><span class="plain">, </span><span class="reserved">nonlocal_variable_emission</span><span class="plain"> </span><span class="identifier">nve</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">nve</span><span class="plain">.</span><span class="element">textual_form</span><span class="plain">) &gt; </span><span class="constant">30</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"name too long"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nlv</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">"null nlv"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">left</span><span class="plain">) </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">lvalue_nve</span><span class="plain"> = </span><span class="identifier">nve</span><span class="plain">; </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">rvalue_nve</span><span class="plain"> = </span><span class="identifier">nve</span><span class="plain">;</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">housed_in_variables_array</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">nonlocal_variable_emission</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::new_nve</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">nonlocal_variable_emission</span><span class="plain"> </span><span class="identifier">nve</span><span class="plain">;</span>
<span class="identifier">nve</span><span class="plain">.</span><span class="element">iname_form</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">nve</span><span class="plain">.</span><span class="element">textual_form</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="identifier">nve</span><span class="plain">.</span><span class="element">stv_ID</span><span class="plain"> = -1;</span>
<span class="identifier">nve</span><span class="plain">.</span><span class="element">stv_index</span><span class="plain"> = -1;</span>
<span class="identifier">nve</span><span class="plain">.</span><span class="element">allow_outside</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">nve</span><span class="plain">.</span><span class="element">use_own_iname</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">nve</span><span class="plain">.</span><span class="element">nothing_form</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">nve</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">nonlocal_variable_emission</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::nve_from_nothing</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">nonlocal_variable_emission</span><span class="plain"> </span><span class="identifier">nve</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::new_nve</span><span class="plain">();</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">nve</span><span class="plain">.</span><span class="element">textual_form</span><span class="plain">, </span><span class="string">"nothing"</span><span class="plain">);</span>
<span class="identifier">nve</span><span class="plain">.</span><span class="element">nothing_form</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">nve</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">nonlocal_variable_emission</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::nve_from_iname</span><span class="plain">(</span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain">) {</span>
<span class="reserved">nonlocal_variable_emission</span><span class="plain"> </span><span class="identifier">nve</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::new_nve</span><span class="plain">();</span>
<span class="identifier">nve</span><span class="plain">.</span><span class="element">iname_form</span><span class="plain"> = </span><span class="identifier">iname</span><span class="plain">;</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">nve</span><span class="plain">.</span><span class="element">textual_form</span><span class="plain">, </span><span class="string">"%n"</span><span class="plain">, </span><span class="identifier">iname</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">nve</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">nonlocal_variable_emission</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::nve_from_mstack</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="reserved">int</span><span class="plain"> </span><span class="identifier">index</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">allow_outside</span><span class="plain">) {</span>
<span class="reserved">nonlocal_variable_emission</span><span class="plain"> </span><span class="identifier">nve</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::new_nve</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">allow_outside</span><span class="plain">)</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">nve</span><span class="plain">.</span><span class="element">textual_form</span><span class="plain">, </span><span class="string">"(MStack--&gt;MstVON(%d,%d))"</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">index</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">nve</span><span class="plain">.</span><span class="element">textual_form</span><span class="plain">, </span><span class="string">"(MStack--&gt;MstVO(%d,%d))"</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">index</span><span class="plain">);</span>
<span class="identifier">nve</span><span class="plain">.</span><span class="element">stv_ID</span><span class="plain"> = </span><span class="identifier">N</span><span class="plain">;</span>
<span class="identifier">nve</span><span class="plain">.</span><span class="element">stv_index</span><span class="plain"> = </span><span class="identifier">index</span><span class="plain">;</span>
<span class="identifier">nve</span><span class="plain">.</span><span class="element">allow_outside</span><span class="plain"> = </span><span class="identifier">allow_outside</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">nve</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">nonlocal_variable_emission</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::nve_from_pos</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">nonlocal_variable_emission</span><span class="plain"> </span><span class="identifier">nve</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::new_nve</span><span class="plain">();</span>
<span class="identifier">nve</span><span class="plain">.</span><span class="element">use_own_iname</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">nve</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NonlocalVariables::set_I6_identifier is used in <a href="#SP10">&#167;10</a>, <a href="#SP13">&#167;13</a>, <a href="#SP20">&#167;20</a>, 21/sv (<a href="21-sv.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function NonlocalVariables::new_nve appears nowhere else.</p>
<p class="endnote">The function NonlocalVariables::nve_from_nothing is used in <a href="#SP10">&#167;10</a>.</p>
<p class="endnote">The function NonlocalVariables::nve_from_iname is used in <a href="#SP10">&#167;10</a>, <a href="#SP20">&#167;20</a>, 21/sv (<a href="21-sv.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function NonlocalVariables::nve_from_mstack is used in 21/sv (<a href="21-sv.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function NonlocalVariables::nve_from_pos is used in <a href="#SP13">&#167;13</a>.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>Later, when we actually need to know where these are being stored, we assign
run-time locations to any variable without them:
</p>
<pre class="display">
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">NonlocalVariables::identifier</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">rvalue_nve</span><span class="plain">.</span><span class="element">textual_form</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) </span><span class="functiontext">NonlocalVariables::allocate_storage</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">rvalue_nve</span><span class="plain">.</span><span class="element">textual_form</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) </span>&lt;<span class="cwebmacro">Issue a missing meaning problem</span> <span class="cwebmacronumber">12.1</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">rvalue_nve</span><span class="plain">.</span><span class="element">textual_form</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::emit_lvalue</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">lvalue_nve</span><span class="plain">.</span><span class="element">iname_form</span><span class="plain">) {</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">lvalue_nve</span><span class="plain">.</span><span class="element">iname_form</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">nlv</span><span class="plain">-&gt;</span><span class="element">lvalue_nve</span><span class="plain">.</span><span class="element">stv_ID</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">LOOKUP_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">MSTACK_HL</span><span class="plain">));</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">ex</span><span class="plain"> = </span><span class="constant">MSTVO_HL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">lvalue_nve</span><span class="plain">.</span><span class="element">allow_outside</span><span class="plain">) </span><span class="identifier">ex</span><span class="plain"> = </span><span class="constant">MSTVON_HL</span><span class="plain">;</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="identifier">ex</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">lvalue_nve</span><span class="plain">.</span><span class="element">stv_ID</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">lvalue_nve</span><span class="plain">.</span><span class="element">stv_index</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</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">nlv</span><span class="plain">-&gt;</span><span class="element">lvalue_nve</span><span class="plain">.</span><span class="element">use_own_iname</span><span class="plain">) {</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">NonlocalVariables::iname</span><span class="plain">(</span><span class="identifier">nlv</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">nlv</span><span class="plain">-&gt;</span><span class="element">lvalue_nve</span><span class="plain">.</span><span class="element">nothing_form</span><span class="plain">) {</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Site::veneer_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">NOTHING_VSYMB</span><span class="plain">));</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"improperly formed nve"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NonlocalVariables::identifier is used in <a href="#SP16">&#167;16</a>.</p>
<p class="endnote">The function NonlocalVariables::emit_lvalue is used in 14/lv (<a href="14-lv.html#SP14_2">&#167;14.2</a>).</p>
<p class="inwebparagraph"><a id="SP12_1"></a><b>&#167;12.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a missing meaning problem</span> <span class="cwebmacronumber">12.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">name</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">BelievedImpossible</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The sentence %1 seems to need the value '%2', but that currently "</span>
<span class="string">"has no definition."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">I</span><span class="string">"self"</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP12">&#167;12</a>.</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>And the allocation is done here. Variables not stored anywhere else are
marked to be housed in an array, though it's really up to the code-generator
tp make that decision:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::allocate_storage</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">var</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">var</span><span class="plain">, </span><span class="reserved">nonlocal_variable</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (((</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">var</span><span class="plain">-&gt;</span><span class="element">lvalue_nve</span><span class="plain">.</span><span class="element">textual_form</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) || (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">var</span><span class="plain">-&gt;</span><span class="element">rvalue_nve</span><span class="plain">.</span><span class="element">textual_form</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">((</span><span class="identifier">var</span><span class="plain">-&gt;</span><span class="element">constant_at_run_time</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) || (</span><span class="identifier">var</span><span class="plain">-&gt;</span><span class="element">var_is_bibliographic</span><span class="plain">))) {</span>
<span class="functiontext">NonlocalVariables::set_I6_identifier</span><span class="plain">(</span><span class="identifier">var</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="functiontext">NonlocalVariables::nve_from_pos</span><span class="plain">());</span>
<span class="functiontext">NonlocalVariables::set_I6_identifier</span><span class="plain">(</span><span class="identifier">var</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="functiontext">NonlocalVariables::nve_from_pos</span><span class="plain">());</span>
<span class="identifier">var</span><span class="plain">-&gt;</span><span class="element">housed_in_variables_array</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NonlocalVariables::allocate_storage is used in <a href="#SP12">&#167;12</a>, <a href="#SP16">&#167;16</a>.</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. </b>In extreme cases, even that flexibility isn't enough. For example, the
"location" variable is rigged so that changing it causes code in the I6
template to be called, because the world model must be kept consistent when
the player character moves room. So it's even possible to set an explicit
I6 schema for how to change a variable:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::set_write_schema</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">sch</span><span class="plain">) {</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_write_schema</span><span class="plain"> = </span><span class="identifier">sch</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="functiontext">NonlocalVariables::get_write_schema</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="functiontext">NonlocalVariables::warn_about_change</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nlv</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">return</span><span class="plain"> </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_write_schema</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::warn_about_change</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</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">score_VAR</span><span class="plain">) &amp;&amp; (</span><span class="identifier">nlv</span><span class="plain"> == </span><span class="identifier">score_VAR</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">scoring_option_set</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) || (</span><span class="identifier">scoring_option_set</span><span class="plain"> == </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">)) {</span>
<span class="identifier">Problems::Issue::sentence_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">PM_CantChangeScore</span><span class="plain">),</span>
<span class="string">"this is a story with no scoring"</span><span class="plain">,</span>
<span class="string">"so it makes no sense to change the 'score' value. You can add "</span>
<span class="string">"scoring to the story by including the sentence 'Use scoring.', "</span>
<span class="string">"in which case this problem message will go away; or you can "</span>
<span class="string">"remove it with 'Use no scoring.' (Until 2011, the default was "</span>
<span class="string">"to have scoring, but now it's not to have scoring.)"</span><span class="plain">);</span>
<span class="plain">}</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 NonlocalVariables::set_write_schema appears nowhere else.</p>
<p class="endnote">The function NonlocalVariables::get_write_schema is used in 12/ter (<a href="12-ter.html#SP8_3">&#167;8.3</a>).</p>
<p class="endnote">The function NonlocalVariables::warn_about_change is used in 25/cii (<a href="25-cii.html#SP3_5_4_2">&#167;3.5.4.2</a>).</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. </b>Here are the standard routines allowing NLVs to be inference subjects:
there's very little to say.
</p>
<pre class="display">
<span class="identifier">wording</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::SUBJ_get_name_text</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">) {</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::as_nlv</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">general_pointer</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::SUBJ_new_permission_granted</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL_GENERAL_POINTER</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::SUBJ_make_adj_const_domain</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">,</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">nc</span><span class="plain">, </span><span class="reserved">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain">) {</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::SUBJ_complete_model</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">) {</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::SUBJ_check_model</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">) {</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::SUBJ_emit_element_of_condition</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">, </span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">t0_s</span><span class="plain">) {</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"NLV in runtime match condition"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::SUBJ_compile</span><span class="plain">(</span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">) {</span>
<span class="plain">}</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="functiontext">NonlocalVariables::get_knowledge</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_knowledge</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NonlocalVariables::SUBJ_get_name_text is used in 16/is (<a href="16-is.html#SP24">&#167;24</a>).</p>
<p class="endnote">The function NonlocalVariables::SUBJ_new_permission_granted is used in 16/is (<a href="16-is.html#SP25">&#167;25</a>).</p>
<p class="endnote">The function NonlocalVariables::SUBJ_make_adj_const_domain is used in 16/is (<a href="16-is.html#SP26">&#167;26</a>).</p>
<p class="endnote">The function NonlocalVariables::SUBJ_complete_model is used in 16/is (<a href="16-is.html#SP27">&#167;27</a>).</p>
<p class="endnote">The function NonlocalVariables::SUBJ_check_model is used in 16/is (<a href="16-is.html#SP28">&#167;28</a>).</p>
<p class="endnote">The function NonlocalVariables::SUBJ_emit_element_of_condition is used in 16/is (<a href="16-is.html#SP29">&#167;29</a>).</p>
<p class="endnote">The function NonlocalVariables::SUBJ_compile is used in 16/is (<a href="16-is.html#SP30">&#167;30</a>).</p>
<p class="endnote">The function NonlocalVariables::get_knowledge is used in <a href="#SP17">&#167;17</a>, <a href="#SP21">&#167;21</a>, 12/ter (<a href="12-ter.html#SP7">&#167;7</a>).</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. </b>The iname is created on demand:
</p>
<pre class="display">
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">NonlocalVariables::iname</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_iname</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="functiontext">Hierarchy::package</span><span class="plain">(</span><span class="functiontext">Modules::find</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_created_at</span><span class="plain">), </span><span class="constant">VARIABLES_HAP</span><span class="plain">);</span>
<span class="functiontext">Hierarchy::markup_wording</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">, </span><span class="constant">VARIABLE_NAME_HMD</span><span class="plain">, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">);</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_with_memo</span><span class="plain">(</span><span class="constant">VARIABLE_HL</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::SUBJ_compile_all</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="functiontext">NonlocalVariables::allocate_storage</span><span class="plain">(); </span><span class="comment">in case this hasn't happened already</span>
&lt;<span class="cwebmacro">Verify that externally-stored nonlocals haven't been initialised</span> <span class="cwebmacronumber">16.1</span>&gt;<span class="character">;</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">, </span><span class="reserved">nonlocal_variable</span><span class="plain">) {</span>
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::origin_of_initial_value</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">NonlocalVariables::has_initial_value_set</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">))</span>
<span class="functiontext">Assertions::PropertyKnowledge::verify_global_variable</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">, </span><span class="reserved">nonlocal_variable</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="identifier">constant_at_run_time</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">housed_in_variables_array</span><span class="plain">)) {</span>
<span class="constant">BEGIN_COMPILATION_MODE</span><span class="plain">;</span>
<span class="identifier">COMPILATION_MODE_EXIT</span><span class="plain">(</span><span class="constant">DEREFERENCE_POINTERS_CMODE</span><span class="plain">);</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::iname</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">);</span>
<span class="identifier">inter_t</span><span class="plain"> </span><span class="identifier">v1</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">v2</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="functiontext">NonlocalVariables::seek_initial_value</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">, &amp;</span><span class="identifier">v1</span><span class="plain">, &amp;</span><span class="identifier">v2</span><span class="plain">, </span><span class="identifier">nlv</span><span class="plain">);</span>
<span class="constant">END_COMPILATION_MODE</span><span class="plain">;</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">rvalue</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">nlv</span><span class="plain">-&gt;</span><span class="element">housed_in_variables_array</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">rvalue</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::identifier</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">);</span>
<span class="functiontext">Emit::variable</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_kind</span><span class="plain">, </span><span class="identifier">v1</span><span class="plain">, </span><span class="identifier">v2</span><span class="plain">, </span><span class="identifier">rvalue</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nlv</span><span class="plain"> == </span><span class="identifier">command_prompt_VAR</span><span class="plain">) {</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">cpt_iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">COMMANDPROMPTTEXT_HL</span><span class="plain">);</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="identifier">cpt_iname</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">RETURN_BIP</span><span class="plain">);</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_text</span><span class="plain">, </span><span class="identifier">iname</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="functiontext">Hierarchy::make_available</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">cpt_iname</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NonlocalVariables::iname is used in <a href="#SP12">&#167;12</a>, 25/cii (<a href="25-cii.html#SP8">&#167;8</a>), 26/rt (<a href="26-rt.html#SP4_1_2">&#167;4.1.2</a>, <a href="26-rt.html#SP4_1_4">&#167;4.1.4</a>), 27/hr (<a href="27-hr.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function NonlocalVariables::SUBJ_compile_all is used in 16/is (<a href="16-is.html#SP30">&#167;30</a>).</p>
<p class="inwebparagraph"><a id="SP16_1"></a><b>&#167;16.1. </b>If a variable is said to be the same as, say, <code class="display"><span class="extract">my_var</span></code> defined in some
I6 code somewhere out of our reach, then it makes no sense to allow the
source text to specify its initial value &mdash; the initial value is whatever
that faraway I6 code said it was.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Verify that externally-stored nonlocals haven't been initialised</span> <span class="cwebmacronumber">16.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">, </span><span class="reserved">nonlocal_variable</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="identifier">housed_in_variables_array</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">var_is_initialisable_anyway</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">alias_to_infs</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">NonlocalVariables::has_initial_value_set</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">)))</span>
&lt;<span class="cwebmacro">Issue a problem message for an impossible initialisation</span> <span class="cwebmacronumber">16.1.1</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP16">&#167;16</a>.</p>
<p class="inwebparagraph"><a id="SP16_1_1"></a><b>&#167;16.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem message for an impossible initialisation</span> <span class="cwebmacronumber">16.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::origin_of_initial_value</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">);</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">);</span>
<span class="identifier">Problems::quote_stream</span><span class="plain">(3, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">lvalue_nve</span><span class="plain">.</span><span class="element">textual_form</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">PM_InaccessibleVariable</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The sentence %1 tells me that '%2' has a specific initial value, "</span>
<span class="string">"but this is a variable which has been translated into an I6 'Global' "</span>
<span class="string">"called '%3' at the lowest level of Inform. Any initial value must be "</span>
<span class="string">"given in its I6 definition, not here."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP16_1">&#167;16.1</a>.</p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. </b>So, as we've seen, each variable is an inference subject. The initial knowledge
about it is that it's a variable, and as such, has permission to have the
"variable initial value" property. So:
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">NonlocalVariables::get_initial_value</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="reserved">inference</span><span class="plain"> *</span><span class="identifier">inf</span><span class="plain">;</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::get_knowledge</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">);</span>
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">, </span><span class="constant">PROPERTY_INF</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">World::Inferences::get_property</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">) == </span><span class="identifier">P_variable_initial_value</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">World::Inferences::get_property_value</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Specifications::new_UNKNOWN</span><span class="plain">(</span><span class="identifier">EMPTY_WORDING</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">NonlocalVariables::origin_of_initial_value</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="reserved">inference</span><span class="plain"> *</span><span class="identifier">inf</span><span class="plain">;</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::get_knowledge</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">);</span>
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">, </span><span class="constant">PROPERTY_INF</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">World::Inferences::get_property</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">) == </span><span class="identifier">P_variable_initial_value</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">World::Inferences::where_inferred</span><span class="plain">(</span><span class="identifier">inf</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">int</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::has_initial_value_set</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">nlv</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">NonlocalVariables::origin_of_initial_value</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">))) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::allow_to_be_zero</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">var_is_allowed_to_be_zero</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NonlocalVariables::get_initial_value is used in <a href="#SP23">&#167;23</a>, <a href="#SP24">&#167;24</a>, <a href="#SP25">&#167;25</a>, 9/pk (<a href="9-pk.html#SP1">&#167;1</a>), 16/is (<a href="16-is.html#SP12">&#167;12</a>), 16/in (<a href="16-in.html#SP19">&#167;19</a>).</p>
<p class="endnote">The function NonlocalVariables::origin_of_initial_value is used in <a href="#SP16">&#167;16</a>, <a href="#SP16_1_1">&#167;16.1.1</a>, <a href="#SP25">&#167;25</a>.</p>
<p class="endnote">The function NonlocalVariables::has_initial_value_set is used in <a href="#SP16">&#167;16</a>, <a href="#SP16_1">&#167;16.1</a>.</p>
<p class="endnote">The function NonlocalVariables::allow_to_be_zero appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. </b>Now for some basic properties:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::is_global</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">scope</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NonlocalVariables::is_global is used in <a href="#SP27">&#167;27</a>, 8/ef (<a href="8-ef.html#SP12_3">&#167;12.3</a>), 11/bas (<a href="11-bas.html#SP19">&#167;19</a>).</p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. </b>The kind can in fact be changed after creation, though this never happens
to variables declared in source text: it allows us to have a few globals which
are reused for different purposes and are typeless.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::set_kind</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</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="reserved">if</span><span class="plain"> (</span><span class="identifier">nlv</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">"set kind for null variable"</span><span class="plain">);</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_kind</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">NonlocalVariables::kind</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nlv</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">return</span><span class="plain"> </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_kind</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NonlocalVariables::set_kind is used in <a href="#SP20">&#167;20</a>, 9/ma (<a href="9-ma.html#SP3_3_39_1">&#167;3.3.39.1</a>), 25/ci (<a href="25-ci.html#SP3_2_3_3_1_1">&#167;3.2.3.3.1.1</a>).</p>
<p class="endnote">The function NonlocalVariables::kind is used in 9/ma (<a href="9-ma.html#SP3_3_39_1">&#167;3.3.39.1</a>), 9/pk (<a href="9-pk.html#SP2">&#167;2</a>), 14/lv (<a href="14-lv.html#SP12_2">&#167;12.2</a>), 21/sv (<a href="21-sv.html#SP3">&#167;3</a>, <a href="21-sv.html#SP3_1">&#167;3.1</a>, <a href="21-sv.html#SP3_2">&#167;3.2</a>).</p>
<p class="inwebparagraph"><a id="SP20"></a><b>&#167;20. </b>Here's an example of that kind-setting in action:
</p>
<pre class="display">
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="functiontext">NonlocalVariables::temporary_from_iname</span><span class="plain">(</span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">temp_iname</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="functiontext">NonlocalVariables::set_I6_identifier</span><span class="plain">(</span><span class="identifier">i6_glob_VAR</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="functiontext">NonlocalVariables::nve_from_iname</span><span class="plain">(</span><span class="identifier">temp_iname</span><span class="plain">));</span>
<span class="functiontext">NonlocalVariables::set_I6_identifier</span><span class="plain">(</span><span class="identifier">i6_glob_VAR</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="functiontext">NonlocalVariables::nve_from_iname</span><span class="plain">(</span><span class="identifier">temp_iname</span><span class="plain">));</span>
<span class="functiontext">NonlocalVariables::set_kind</span><span class="plain">(</span><span class="identifier">i6_glob_VAR</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">i6_glob_VAR</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="functiontext">NonlocalVariables::temporary_from_nve</span><span class="plain">(</span><span class="reserved">nonlocal_variable_emission</span><span class="plain"> </span><span class="identifier">nve</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="functiontext">NonlocalVariables::set_I6_identifier</span><span class="plain">(</span><span class="identifier">i6_glob_VAR</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">nve</span><span class="plain">);</span>
<span class="functiontext">NonlocalVariables::set_I6_identifier</span><span class="plain">(</span><span class="identifier">i6_glob_VAR</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">nve</span><span class="plain">);</span>
<span class="functiontext">NonlocalVariables::set_kind</span><span class="plain">(</span><span class="identifier">i6_glob_VAR</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">i6_glob_VAR</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">formal_par_vars_made</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">formal_par_VAR</span><span class="plain">[8];</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="functiontext">NonlocalVariables::temporary_formal</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">if</span><span class="plain"> (</span><span class="identifier">formal_par_vars_made</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;8; </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">formal_par_VAR</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="functiontext">NonlocalVariables::new</span><span class="plain">(</span><span class="identifier">EMPTY_WORDING</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::formal_par</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">);</span>
<span class="identifier">formal_par_VAR</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]-&gt;</span><span class="element">nlv_iname</span><span class="plain"> = </span><span class="identifier">iname</span><span class="plain">;</span>
<span class="functiontext">NonlocalVariables::set_I6_identifier</span><span class="plain">(</span><span class="identifier">formal_par_VAR</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">], </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="functiontext">NonlocalVariables::nve_from_iname</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">));</span>
<span class="functiontext">NonlocalVariables::set_I6_identifier</span><span class="plain">(</span><span class="identifier">formal_par_VAR</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="functiontext">NonlocalVariables::nve_from_iname</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="identifier">formal_par_vars_made</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain"> = </span><span class="identifier">formal_par_VAR</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">];</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">nlv</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">NonlocalVariables::formal_par</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="reserved">switch</span><span class="plain"> (</span><span class="identifier">n</span><span class="plain">) {</span>
<span class="reserved">case</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="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">formal_par0_HL</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">1</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">formal_par1_HL</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="reserved">return</span><span class="plain"> </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">formal_par2_HL</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="reserved">return</span><span class="plain"> </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">formal_par3_HL</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">4</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">formal_par4_HL</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">5</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">formal_par5_HL</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">6</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">formal_par6_HL</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">7</span><span class="plain">: </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">formal_par7_HL</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"bad formal par number"</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 NonlocalVariables::temporary_from_iname appears nowhere else.</p>
<p class="endnote">The function NonlocalVariables::temporary_from_nve appears nowhere else.</p>
<p class="endnote">The function NonlocalVariables::temporary_formal is used in 25/ci (<a href="25-ci.html#SP3_2_3_1_1">&#167;3.2.3.1.1</a>, <a href="25-ci.html#SP3_2_3_3_1_1">&#167;3.2.3.3.1.1</a>, <a href="25-ci.html#SP3_2_3_4_1_1">&#167;3.2.3.4.1.1</a>, <a href="25-ci.html#SP3_2_3_3_1_2_1">&#167;3.2.3.3.1.2.1</a>), 26/rt (<a href="26-rt.html#SP4_1_2">&#167;4.1.2</a>, <a href="26-rt.html#SP4_1_4">&#167;4.1.4</a>).</p>
<p class="endnote">The function NonlocalVariables::formal_par is used in 25/ci (<a href="25-ci.html#SP3_2_3_1_1">&#167;3.2.3.1.1</a>).</p>
<p class="inwebparagraph"><a id="SP21"></a><b>&#167;21. </b>This is a curiosity, used to force the textual contents of a bibliographic
data variable (such as "story title") to be treated as text.
</p>
<pre class="display">
<span class="identifier">wording</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::treat_as_plain_text_word</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="reserved">inference</span><span class="plain"> *</span><span class="identifier">inf</span><span class="plain">;</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::get_knowledge</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">);</span>
<span class="identifier">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">infs</span><span class="plain">, </span><span class="constant">PROPERTY_INF</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">World::Inferences::get_property</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">) == </span><span class="identifier">P_variable_initial_value</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span>
<span class="functiontext">World::Inferences::set_property_value_kind</span><span class="plain">(</span><span class="identifier">inf</span><span class="plain">, </span><span class="identifier">K_text</span><span class="plain">));</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NonlocalVariables::treat_as_plain_text_word appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP22"></a><b>&#167;22. </b>"Constant" means that no change is permitted at run-time; "initialisable"
means that a value can be set by an assertion in the source text.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::make_constant</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">bib</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nlv</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">"no such var"</span><span class="plain">);</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">constant_at_run_time</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">var_is_initialisable_anyway</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">var_is_bibliographic</span><span class="plain"> = </span><span class="identifier">bib</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::make_initalisable</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">var_is_initialisable_anyway</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::is_constant</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nlv</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">"no such var"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">constant_at_run_time</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::must_be_constant</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">constant_at_run_time</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::sentence_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">PM_CantChangeConstants</span><span class="plain">),</span>
<span class="string">"this is a name for a value which never changes during the story"</span><span class="plain">,</span>
<span class="string">"so it can't be altered with 'now'."</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 NonlocalVariables::make_constant is used in 12/ap (<a href="12-ap.html#SP9_5_2">&#167;9.5.2</a>).</p>
<p class="endnote">The function NonlocalVariables::make_initalisable appears nowhere else.</p>
<p class="endnote">The function NonlocalVariables::is_constant is used in 10/cad (<a href="10-cad.html#SP3">&#167;3</a>, <a href="10-cad.html#SP4">&#167;4</a>), 12/ter (<a href="12-ter.html#SP7">&#167;7</a>), 14/lv (<a href="14-lv.html#SP8">&#167;8</a>), 25/cii (<a href="25-cii.html#SP3_1_1_2">&#167;3.1.1.2</a>).</p>
<p class="endnote">The function NonlocalVariables::must_be_constant is used in 12/ter (<a href="12-ter.html#SP8_3">&#167;8.3</a>), 25/cii (<a href="25-cii.html#SP3_5_4_2">&#167;3.5.4.2</a>).</p>
<p class="inwebparagraph"><a id="SP23"></a><b>&#167;23. </b>Substitution is the process of replacing a constant variable with its value,
and leaving everything else alone.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">substitution_session_id</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">NonlocalVariables::substitute_constants</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="reserved">int</span><span class="plain"> </span><span class="identifier">depth</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">substitution_session_id</span><span class="plain">++;</span>
<span class="reserved">while</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">depth</span><span class="plain">++ &gt; </span><span class="constant">20</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"ill-founded constants"</span><span class="plain">);</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain"> = </span><span class="functiontext">Lvalues::get_nonlocal_variable_if_any</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">nlv</span><span class="plain">) &amp;&amp; (</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">constant_at_run_time</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">substitution_marker</span><span class="plain"> == </span><span class="identifier">substitution_session_id</span><span class="plain">) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(3, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_kind</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">PM_MeaningRecursive</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The sentence %1 tells me that '%2', which should be %3 "</span>
<span class="string">"that varies, is to have an initial value which can't "</span>
<span class="string">"be worked out without going round in circles."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">substitution_marker</span><span class="plain"> = </span><span class="identifier">substitution_session_id</span><span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">sspec</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::get_initial_value</span><span class="plain">(</span><span class="identifier">nlv</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">sspec</span><span class="plain">, </span><span class="constant">UNKNOWN_NT</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) { </span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">sspec</span><span class="plain">; </span><span class="reserved">continue</span><span class="plain">; }</span>
<span class="plain">}</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NonlocalVariables::substitute_constants is used in <a href="#SP25">&#167;25</a>, 9/ma (<a href="9-ma.html#SP3_3_41_3">&#167;3.3.41.3</a>), 9/pk (<a href="9-pk.html#SP4">&#167;4</a>), 9/rk (<a href="9-rk.html#SP2">&#167;2</a>), 14/cfs (<a href="14-cfs.html#SP6">&#167;6</a>), 18/lc (<a href="18-lc.html#SP8">&#167;8</a>), 19/tb (<a href="19-tb.html#SP26_2">&#167;26.2</a>), 25/cp (<a href="25-cp.html#SP5_3_5">&#167;5.3.5</a>).</p>
<p class="inwebparagraph"><a id="SP24"></a><b>&#167;24. </b>From the point of view of computer science, aliasing is a terrible thing.
This is the ability to tie the name of a variable to that of something
else, and is motivated by the existence of nouns in English which are
neither quite proper nor common; "the player" in Inform is an example.
</p>
<pre class="display">
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="functiontext">NonlocalVariables::get_alias</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::get_initial_value</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">);</span>
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">vals</span><span class="plain"> = </span><span class="functiontext">InferenceSubjects::from_specification</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">vals</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">vals</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">alias_to_infs</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>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::set_alias</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">, </span><span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain">) {</span>
<span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">alias_to_infs</span><span class="plain"> = </span><span class="identifier">infs</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NonlocalVariables::get_alias is used in 9/rpt (<a href="9-rpt.html#SP16">&#167;16</a>), 12/ap (<a href="12-ap.html#SP12">&#167;12</a>), 19/tb (<a href="19-tb.html#SP24_5">&#167;24.5</a>).</p>
<p class="endnote">The function NonlocalVariables::set_alias appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP25"></a><b>&#167;25. </b>The following routine compiles the correct initial value for the given
variable. If it has no known initial value, it is given the initial
value for its kind where possible: note that this may not be possible
if the source text says something like
</p>
<blockquote>
<p>Thickness is a kind of value. The carpet nap is a thickness that varies.</p>
</blockquote>
<p class="inwebparagraph">without specifying any thicknesses: the set of legal thickness values
is empty, so the carpet nap variable cannot be created in a way
which makes its kind safe. Hence the error messages.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::emit_initial_value</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="identifier">value_holster</span><span class="plain"> </span><span class="identifier">VH</span><span class="plain"> = </span><span class="identifier">Holsters::new</span><span class="plain">(</span><span class="identifier">INTER_DATA_VHMODE</span><span class="plain">);</span>
<span class="functiontext">NonlocalVariables::compile_initial_value_vh</span><span class="plain">(&amp;</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">nlv</span><span class="plain">);</span>
<span class="identifier">inter_t</span><span class="plain"> </span><span class="identifier">v1</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">v2</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">Holsters::unholster_pair</span><span class="plain">(&amp;</span><span class="identifier">VH</span><span class="plain">, &amp;</span><span class="identifier">v1</span><span class="plain">, &amp;</span><span class="identifier">v2</span><span class="plain">);</span>
<span class="functiontext">Emit::array_generic_entry</span><span class="plain">(</span><span class="identifier">v1</span><span class="plain">, </span><span class="identifier">v2</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::emit_initial_value_as_val</span><span class="plain">(</span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="identifier">value_holster</span><span class="plain"> </span><span class="identifier">VH</span><span class="plain"> = </span><span class="identifier">Holsters::new</span><span class="plain">(</span><span class="identifier">INTER_VAL_VHMODE</span><span class="plain">);</span>
<span class="functiontext">NonlocalVariables::compile_initial_value_vh</span><span class="plain">(&amp;</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">nlv</span><span class="plain">);</span>
<span class="identifier">Holsters::to_val_mode</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), &amp;</span><span class="identifier">VH</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::seek_initial_value</span><span class="plain">(</span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain">, </span><span class="identifier">inter_t</span><span class="plain"> *</span><span class="identifier">v1</span><span class="plain">, </span><span class="identifier">inter_t</span><span class="plain"> *</span><span class="identifier">v2</span><span class="plain">, </span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="reserved">ival_emission</span><span class="plain"> </span><span class="identifier">IE</span><span class="plain"> = </span><span class="functiontext">Emit::begin_ival_emission</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">);</span>
<span class="functiontext">NonlocalVariables::compile_initial_value_vh</span><span class="plain">(</span><span class="functiontext">Emit::ival_holster</span><span class="plain">(&amp;</span><span class="identifier">IE</span><span class="plain">), </span><span class="identifier">nlv</span><span class="plain">);</span>
<span class="functiontext">Emit::end_ival_emission</span><span class="plain">(&amp;</span><span class="identifier">IE</span><span class="plain">, </span><span class="identifier">v1</span><span class="plain">, </span><span class="identifier">v2</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::compile_initial_value_vh</span><span class="plain">(</span><span class="identifier">value_holster</span><span class="plain"> *</span><span class="identifier">VH</span><span class="plain">, </span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain"> =</span>
<span class="functiontext">NonlocalVariables::substitute_constants</span><span class="plain">(</span>
<span class="functiontext">NonlocalVariables::get_initial_value</span><span class="plain">(</span>
<span class="identifier">nlv</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">val</span><span class="plain">, </span><span class="constant">UNKNOWN_NT</span><span class="plain">)) {</span>
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_created_at</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Initialise with the default value of its kind</span> <span class="cwebmacronumber">25.1</span>&gt;
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::origin_of_initial_value</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Lvalues::get_storage_form</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">) == </span><span class="constant">NONLOCAL_VARIABLE_NT</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Issue a problem for one variable set equal to another</span> <span class="cwebmacronumber">25.2</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Specifications::Compiler::compile_constant_to_kind_vh</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">val</span><span class="plain">, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_kind</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NonlocalVariables::emit_initial_value appears nowhere else.</p>
<p class="endnote">The function NonlocalVariables::emit_initial_value_as_val is used in 21/sv (<a href="21-sv.html#SP3_1">&#167;3.1</a>).</p>
<p class="endnote">The function NonlocalVariables::seek_initial_value is used in <a href="#SP16">&#167;16</a>.</p>
<p class="endnote">The function NonlocalVariables::compile_initial_value_vh appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP25_1"></a><b>&#167;25.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Initialise with the default value of its kind</span> <span class="cwebmacronumber">25.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::RunTime::compile_default_value_vh</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_kind</span><span class="plain">, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">, </span><span class="string">"variable"</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">nlv</span><span class="plain">-&gt;</span><span class="element">var_is_allowed_to_be_zero</span><span class="plain">) {</span>
<span class="identifier">Holsters::holster_pair</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</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">Kinds::Behaviour::get_name</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_kind</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(1, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">W</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">PM_EmptyDataType</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"I am unable to put any value into the variable '%1', because "</span>
<span class="string">"%2 is a kind of value with no actual values."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</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="#SP25">&#167;25</a>.</p>
<p class="inwebparagraph"><a id="SP25_2"></a><b>&#167;25.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem for one variable set equal to another</span> <span class="cwebmacronumber">25.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">the_other</span><span class="plain"> = </span><span class="identifier">ParseTree::get_constant_nonlocal_variable</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">the_other</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">"Tried to compile initial value of variable as null variable"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">the_other</span><span class="plain"> == </span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(3, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_kind</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">PM_InitialiseQ2</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The sentence %1 tells me that '%2', which should be %3 "</span>
<span class="string">"that varies, is to have an initial value equal to itself - "</span>
<span class="string">"this is such an odd thing to say that I think I must have "</span>
<span class="string">"misunderstood."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(3, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_kind</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(4, </span><span class="identifier">the_other</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(5, </span><span class="identifier">the_other</span><span class="plain">-&gt;</span><span class="element">nlv_kind</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">PM_InitialiseQ1</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The sentence %1 tells me that '%2', which should be %3 "</span>
<span class="string">"that varies, is to have an initial value equal to '%4', "</span>
<span class="string">"which in turn is %5 that varies. At the start of play, "</span>
<span class="string">"variable values have to be set equal to definite constants, "</span>
<span class="string">"so this is not allowed."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP25">&#167;25</a>.</p>
<p class="inwebparagraph"><a id="SP26"></a><b>&#167;26. </b>The index of all the global variables doesn't actually include all of them,
because there are "K understood" variables for every kind which can be
understood, and a list of those would be tediously repetitive &mdash; it would
duplicate most of the list of base kinds. So the index shows just one such
variable. Inform recognises these variables by parsing their names against
the following:
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">value</span><span class="plain">-</span><span class="identifier">understood</span><span class="plain">-</span><span class="identifier">variable</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">k</span><span class="plain">-</span><span class="identifier">kind</span><span class="plain">&gt; </span><span class="identifier">understood</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP27"></a><b>&#167;27. </b>And here is the indexing code:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::index_all</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">) {</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">;</span>
<span class="identifier">heading</span><span class="plain"> *</span><span class="identifier">definition_area</span><span class="plain">, *</span><span class="identifier">current_area</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="identifier">Index::anchor</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"NAMES"</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">understood_note_given</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">, </span><span class="reserved">nonlocal_variable</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">) &gt;= </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">NonlocalVariables::is_global</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">))) {</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">value</span><span class="plain">-</span><span class="identifier">understood</span><span class="plain">-</span><span class="identifier">variable</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt;(</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Index a K understood variable</span> <span class="cwebmacronumber">27.1</span>&gt;
<span class="reserved">else</span>
&lt;<span class="cwebmacro">Index a regular variable</span> <span class="cwebmacronumber">27.2</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NonlocalVariables::index_all appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP27_1"></a><b>&#167;27.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Index a K understood variable</span> <span class="cwebmacronumber">27.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">understood_note_given</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">understood_note_given</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&lt;i&gt;kind&lt;/i&gt; understood - &lt;i&gt;value&lt;/i&gt;"</span><span class="plain">);</span>
<span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"br"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP27">&#167;27</a>.</p>
<p class="inwebparagraph"><a id="SP27_2"></a><b>&#167;27.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Index a regular variable</span> <span class="cwebmacronumber">27.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">definition_area</span><span class="plain"> = </span><span class="identifier">Headings::of_wording</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Headings::indexed</span><span class="plain">(</span><span class="identifier">definition_area</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">definition_area</span><span class="plain"> != </span><span class="identifier">current_area</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">Headings::get_text</span><span class="plain">(</span><span class="identifier">definition_area</span><span class="plain">);</span>
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="functiontext">Phrases::Index::index_definition_area</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">current_area</span><span class="plain"> = </span><span class="identifier">definition_area</span><span class="plain">;</span>
<span class="functiontext">NonlocalVariables::index_single</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">nlv</span><span class="plain">);</span>
<span class="identifier">HTML_TAG</span><span class="plain">(</span><span class="string">"br"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP27">&#167;27</a>.</p>
<p class="inwebparagraph"><a id="SP28"></a><b>&#167;28. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">NonlocalVariables::index_single</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">);</span>
<span class="identifier">Index::link</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">var_documentation_symbol</span><span class="plain">)) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">ixt</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">ixt</span><span class="plain">, </span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">Wordings::one_word</span><span class="plain">(</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">var_documentation_symbol</span><span class="plain">)));</span>
<span class="identifier">Index::DocReferences::link</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">ixt</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">ixt</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" - &lt;i&gt;"</span><span class="plain">);</span>
<span class="identifier">Kinds::Textual::write</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">nlv_kind</span><span class="plain">);</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&lt;/i&gt;"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function NonlocalVariables::index_single is used in <a href="#SP27_2">&#167;27.2</a>, 21/sv (<a href="21-sv.html#SP3">&#167;3</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="5-ins.html">Back to 'Instances'</a></li><li><a href="5-ipw.html">Continue with 'Index Physical World'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>