1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 00:24:22 +03:00
inform7/docs/imperative-module/3-lv.html
2023-06-05 11:12:24 +01:00

664 lines
120 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Local Variables</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script src="http://code.jquery.com/jquery-1.12.4.min.js"
integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
<script src="../docs-assets/Bigfoot.js"></script>
<link href="../docs-assets/Bigfoot.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Preform-Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Inform.png" height=72">
</a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../indocn.html">indoc</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
<li><a href="../inrtpsn.html">inrtps</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=18> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="../../../inweb/index.html">inweb</a></li>
<li><a href="../../../intest/index.html">intest</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Local Variables' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inform7n.html">Inform7</a></li><li><a href="index.html">imperative</a></li><li><a href="index.html#3">Chapter 3: Functions</a></li><li><b>Local Variables</b></li></ul></div>
<p class="purpose">Local variables are used for call parameters, temporary values, and other ephemeral workspace.</p>
<ul class="toc"><li><a href="3-lv.html#SP1">&#167;1. Declaration</a></li><li><a href="3-lv.html#SP2">&#167;2. Call parameters</a></li><li><a href="3-lv.html#SP4">&#167;4. Other call parameters</a></li><li><a href="3-lv.html#SP7">&#167;7. Let values</a></li><li><a href="3-lv.html#SP9">&#167;9. Internal locals</a></li><li><a href="3-lv.html#SP13">&#167;13. Searching by identifier</a></li><li><a href="3-lv.html#SP15">&#167;15. Searching by index</a></li><li><a href="3-lv.html#SP17">&#167;17. Searching by I7 source name</a></li><li><a href="3-lv.html#SP19">&#167;19. Monitoring parsing</a></li><li><a href="3-lv.html#SP20">&#167;20. Callings</a></li><li><a href="3-lv.html#SP23">&#167;23. Permissible names</a></li><li><a href="3-lv.html#SP24">&#167;24. Kind</a></li><li><a href="3-lv.html#SP26">&#167;26. Logging</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Declaration. </b>When some other part of the <a href="../runtime-module/index.html" class="internal">runtime</a> or <a href="index.html" class="internal">imperative</a> modules wants to
compile an Inter function, it will need to ensure that any local it creates
is declared as part of that function. This is how, and it returns the Inter
symbol referring to the variable.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::declare</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::declare</span></span>:<br/><a href="3-lv.html#SP4">&#167;4</a>, <a href="3-lv.html#SP7">&#167;7</a>, <a href="3-lv.html#SP9">&#167;9</a><br/>Compile Lvalues - <a href="2-cl.html#SP1_1">&#167;1.1</a>, <a href="2-cl.html#SP2">&#167;2</a><br/>Compile Conditions - <a href="2-cc.html#SP1_3">&#167;1.3</a>, <a href="2-cc.html#SP5_1">&#167;5.1</a><br/>Matching Action Patterns - <a href="2-map.html#SP3_5_1_1_1_20">&#167;3.5.1.1.1.20</a>, <a href="2-map.html#SP5">&#167;5</a>, <a href="2-map.html#SP5_2_1">&#167;5.2.1</a><br/>Local Variable Slates - <a href="3-lvs.html#SP17">&#167;17</a>, <a href="3-lvs.html#SP19">&#167;19</a><br/>Local Parking - <a href="3-lp.html#SP2">&#167;2</a>, <a href="3-lp.html#SP3">&#167;3</a><br/>Compile Schemas - <a href="4-cs.html#SP5_1">&#167;5.1</a>, <a href="4-cs.html#SP5_2">&#167;5.2</a><br/>Compile Loops - <a href="4-cl.html#SP1_1">&#167;1.1</a>, <a href="4-cl.html#SP2">&#167;2</a>, <a href="4-cl.html#SP4">&#167;4</a><br/>Deciding to Defer - <a href="4-dtd.html#SP8_1">&#167;8.1</a><br/>Compile Deferred Propositions - <a href="4-cdp.html#SP3_5_1">&#167;3.5.1</a><br/>Compile Blocks and Lines - <a href="5-cbal.html#SP4_4_5_2">&#167;4.4.5.2</a><br/>Compile Invocations Inline - <a href="5-cii.html#SP3_2">&#167;3.2</a>, <a href="5-cii.html#SP6_6_1">&#167;6.6.1</a>, <a href="5-cii.html#SP6_6_3">&#167;6.6.3</a><br/>Compile Solutions to Equations - <a href="5-cste.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-lvs.html#SP18" class="function-link"><span class="function-syntax">LocalVariableSlates::declare_one</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. Call parameters. </b>These are the ones with names in Inform 7 source text, and generally come
from prototypes of phrases.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::new_call_parameter</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::new_call_parameter</span></span>:<br/>Stack Frames - <a href="3-sf.html#SP13">&#167;13</a><br/>Compile Imperative Definitions - <a href="3-cid.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">stack_frame</span><span class="plain-syntax"> *</span><span class="identifier-syntax">frame</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax"> = </span><a href="3-lvs.html#SP11" class="function-link"><span class="function-syntax">LocalVariableSlates::allocate_I7_local</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">frame</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">local_variables</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="constant-syntax">TOKEN_CALL_PARAMETER_LV</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, -1);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOCAL_VARIABLES</span><span class="plain-syntax">, </span><span class="string-syntax">"Call parameter $k added\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>These are numbered 0, 1, 2, ..., as created, and the following returns that
index number:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">LocalVariables::get_parameter_number</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::get_parameter_number</span></span>:<br/>Compile Invocations Inline - <a href="5-cii.html#SP6_1">&#167;6.1</a>, <a href="5-cii.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lvar</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">lv_purpose</span><span class="plain-syntax"> != </span><span class="constant-syntax">TOKEN_CALL_PARAMETER_LV</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"not a call parameter"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">index_with_this_purpose</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. Other call parameters. </b>However, our Inter function may also (or instead) be called with other arguments,
and those are "other call parameters": they have no I7 source text name, and
instead referred to by their Inter identifiers alone.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::new_other_parameter</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::new_other_parameter</span></span>:<br/>Closures - <a href="3-cls.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">stack_frame</span><span class="plain-syntax"> *</span><span class="identifier-syntax">frame</span><span class="plain-syntax"> = </span><a href="3-sf.html#SP2" class="function-link"><span class="function-syntax">Frames::current_stack_frame</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">frame</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-lvs.html#SP12" class="function-link"><span class="function-syntax">LocalVariableSlates::ensure_Inter_identifier</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">frame</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">local_variables</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">, </span><span class="constant-syntax">OTHER_CALL_PARAMETER_LV</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::new_other_as_symbol</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::new_other_as_symbol</span></span>:<br/>Cinders and Deferrals - <a href="4-cad.html#SP5">&#167;5</a><br/>Compile Deferred Propositions - <a href="4-cdp.html#SP3_5">&#167;3.5</a>, <a href="4-cdp.html#SP3_5_4">&#167;3.5.4</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">v</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP4" class="function-link"><span class="function-syntax">LocalVariables::new_other_parameter</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-lv.html#SP1" class="function-link"><span class="function-syntax">LocalVariables::declare</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">v</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>Finally, when phrase options are used in invoking a phrase, a bitmap is
passed to its Inter routine, and this occupies a pseudo-call-parameter:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LocalVariables::options_parameter_is_needed</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::options_parameter_is_needed</span></span>:<br/>Compile Imperative Definitions - <a href="3-cid.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">stack_frame</span><span class="plain-syntax"> *</span><span class="identifier-syntax">frame</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="3-lvs.html#SP12" class="function-link"><span class="function-syntax">LocalVariableSlates::ensure_Inter_identifier</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">frame</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">local_variables</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="string-syntax">"phrase_options"</span><span class="plain-syntax">, </span><span class="constant-syntax">OTHER_CALL_PARAMETER_LV</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::options_parameter</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::options_parameter</span></span>:<br/>Compile Conditions - <a href="2-cc.html#SP1_3">&#167;1.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">stack_frame</span><span class="plain-syntax"> *</span><span class="identifier-syntax">frame</span><span class="plain-syntax"> = </span><a href="3-sf.html#SP2" class="function-link"><span class="function-syntax">Frames::current_stack_frame</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">frame</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-lvs.html#SP12" class="function-link"><span class="function-syntax">LocalVariableSlates::find_Inter_identifier</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">frame</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">local_variables</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="string-syntax">"phrase_options"</span><span class="plain-syntax">, </span><span class="constant-syntax">OTHER_CALL_PARAMETER_LV</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>Both sorts of parameter count:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">LocalVariables::is_parameter</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::is_parameter</span></span>:<br/>Stack Frames - <a href="3-sf.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> ((</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lv_purpose</span><span class="plain-syntax"> == </span><span class="constant-syntax">TOKEN_CALL_PARAMETER_LV</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lv_purpose</span><span class="plain-syntax"> == </span><span class="constant-syntax">OTHER_CALL_PARAMETER_LV</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. Let values. </b>These can only be created in the current frame, and they are immediately
declared.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::new_let_value</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::new_let_value</span></span>:<br/><a href="3-lv.html#SP21">&#167;21</a><br/>Compile Loops - <a href="4-cl.html#SP1">&#167;1</a>, <a href="4-cl.html#SP4">&#167;4</a><br/>Compile Invocations Inline - <a href="5-cii.html#SP3_2">&#167;3.2</a>, <a href="5-cii.html#SP6_6_1_1">&#167;6.6.1.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">stack_frame</span><span class="plain-syntax"> *</span><span class="identifier-syntax">frame</span><span class="plain-syntax"> = </span><a href="3-sf.html#SP2" class="function-link"><span class="function-syntax">Frames::current_stack_frame</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">frame</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to add let value without stack frame"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax"> = </span><a href="3-lvs.html#SP11" class="function-link"><span class="function-syntax">LocalVariableSlates::allocate_I7_local</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">frame</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">local_variables</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="constant-syntax">LET_VALUE_LV</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, -1);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Produce::function_body_is_open</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">()))</span>
<span class="plain-syntax"> </span><a href="3-lv.html#SP1" class="function-link"><span class="function-syntax">LocalVariables::declare</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOCAL_VARIABLES</span><span class="plain-syntax">, </span><span class="string-syntax">"Let value $k allocated\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b>Some <span class="extract"><span class="extract-syntax">LET_VALUE_LV</span></span> variables are protected from being changed by "let" or "now" &mdash;
that sounds contradictory, but for example loop counters in "repeat" constructs are
also <span class="extract"><span class="extract-syntax">LET_VALUE_LV</span></span> locals, and we want to stop the source text from altering
those. Protection is opt-out for let values: we have to call <a href="3-lv.html#SP8" class="internal">LocalVariables::unprotect</a>
if we want a let value to be modifiable from source text.
</p>
<p class="commentary">Note that <span class="extract"><span class="extract-syntax">TOKEN_CALL_PARAMETER_LV</span></span> locals are unprotected, which means that it's
legal in Inform to modify one of the call parameters to a phrase.<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> Protection
would be meaningless for the other two sorts of local, since they aren't accessible
from I7 source text anyway.
</p>
<ul class="footnotetexts"><li class="footnote" id="fn:1"><p class="inwebfootnote"><sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> We considered banning this in March 2012, when there were only two instances
in the entire set of documentation Examples making use of this "feature". But
in the end, it didn't seem harmful enough to matter.
<a href="#fnref:1" title="return to text"> &#x21A9;</a></p></li></ul>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LocalVariables::unprotect</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::unprotect</span></span>:<br/>Compile Invocations Inline - <a href="5-cii.html#SP6_6_2">&#167;6.6.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">current_usage</span><span class="plain-syntax">.</span><span class="element-syntax">protected</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">LocalVariables::protected</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::protected</span></span>:<br/>Compile Invocations Inline - <a href="5-cii.html#SP6_6_4_2">&#167;6.6.4.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lv_purpose</span><span class="plain-syntax"> == </span><span class="constant-syntax">LET_VALUE_LV</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_usage</span><span class="plain-syntax">.</span><span class="element-syntax">protected</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_usage</span><span class="plain-syntax">.</span><span class="element-syntax">varname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_ProtectedFromLet</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"In %1, it looks as if you want to use 'let' to change the value of "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"the temporary variable '%2'. Ordinarily that would be fine, but it's "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"not allowed when the variable is used as the counter in a 'repeat' "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"loop, or has some other do-not-disturb purpose - this could cause "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"chaotic effects. The rule is: you can only change an existing value "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"with 'let' if it was created by 'let' in the first place."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. Internal locals. </b>"Internals" are Inter locals which do not correspond to anything at the I7
level, and which are used to implement some low-level feature. They can only
be created in the current frame.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::new_internal</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::new_internal</span></span>:<br/>Compile Deferred Propositions - <a href="4-cdp.html#SP3_5_1">&#167;3.5.1</a><br/>Compile Invocations Inline - <a href="5-cii.html#SP6_6_1_2">&#167;6.6.1.2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">stack_frame</span><span class="plain-syntax"> *</span><span class="identifier-syntax">frame</span><span class="plain-syntax"> = </span><a href="3-sf.html#SP2" class="function-link"><span class="function-syntax">Frames::current_stack_frame</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">frame</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-lvs.html#SP12" class="function-link"><span class="function-syntax">LocalVariableSlates::ensure_Inter_identifier</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">frame</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">local_variables</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">, </span><span class="constant-syntax">INTERNAL_USE_LV</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::new_internal_as_symbol</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::new_internal_as_symbol</span></span>:<br/>Compile Deferred Propositions - <a href="4-cdp.html#SP3_5_1">&#167;3.5.1</a>, <a href="4-cdp.html#SP3_5_2">&#167;3.5.2</a>, <a href="4-cdp.html#SP3_5_3">&#167;3.5.3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">v</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-lv.html#SP1" class="function-link"><span class="function-syntax">LocalVariables::declare</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">v</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::new_internal_commented</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::new_internal_commented</span></span>:<br/><a href="3-lv.html#SP10">&#167;10</a>, <a href="3-lv.html#SP11">&#167;11</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">comment</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">) </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">comment_on_use</span><span class="plain-syntax"> = </span><span class="identifier-syntax">comment</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">inter_symbol</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::new_internal_commented_as_symbol</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">comment</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">v</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_commented</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">, </span><span class="identifier-syntax">comment</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-lv.html#SP1" class="function-link"><span class="function-syntax">LocalVariables::declare</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">v</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. </b>For example, <span class="extract"><span class="extract-syntax">ct_0</span></span> and <span class="extract"><span class="extract-syntax">ct_1</span></span> contain the current table and row selection,
in phrases for which that's relevant.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LocalVariables::add_table_lookup</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::add_table_lookup</span></span>:<br/>Compile Lvalues - <a href="2-cl.html#SP2">&#167;2</a><br/>Matching Action Patterns - <a href="2-map.html#SP5_2_1">&#167;5.2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_commented</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"ct_0"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"currently selected table"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_commented</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"ct_1"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"currently selected row"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOCAL_VARIABLES</span><span class="plain-syntax">, </span><span class="string-syntax">"Stack frame acquires CT locals\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">LocalVariables::are_we_using_table_lookup</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::are_we_using_table_lookup</span></span>:<br/>Compile Deferred Propositions - <a href="4-cdp.html#SP3_3">&#167;3.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">stack_frame</span><span class="plain-syntax"> *</span><span class="identifier-syntax">frame</span><span class="plain-syntax"> = </span><a href="3-sf.html#SP2" class="function-link"><span class="function-syntax">Frames::current_stack_frame</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">frame</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-lvs.html#SP12" class="function-link"><span class="function-syntax">LocalVariableSlates::find_Inter_identifier</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">frame</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">local_variables</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="string-syntax">"ct_0"</span><span class="plain-syntax">, </span><span class="constant-syntax">INTERNAL_USE_LV</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>Similarly <span class="extract"><span class="extract-syntax">sw_v</span></span> holds a temporary switch value, in some cases.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::add_switch_value</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::add_switch_value</span></span>:<br/>Compile Blocks and Lines - <a href="5-cbal.html#SP4_4_5_2">&#167;4.4.5.2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOCAL_VARIABLES</span><span class="plain-syntax">, </span><span class="string-syntax">"Stack frame acquires switch value\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-lv.html#SP9" class="function-link"><span class="function-syntax">LocalVariables::new_internal_commented</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"sw_v"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"switch value"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. </b>And this retrieves the local on the current stack frame with the given
identifier, if it exists.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::find_internal</span><button class="popup" onclick="togglePopup('usagePopup18')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup18">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::find_internal</span></span>:<br/>Compile Lvalues - <a href="2-cl.html#SP2">&#167;2</a><br/>Matching Action Patterns - <a href="2-map.html#SP5_2_1">&#167;5.2.1</a><br/>Compile Invocations Inline - <a href="5-cii.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">stack_frame</span><span class="plain-syntax"> *</span><span class="identifier-syntax">frame</span><span class="plain-syntax"> = </span><a href="3-sf.html#SP2" class="function-link"><span class="function-syntax">Frames::current_stack_frame</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">frame</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-lvs.html#SP12" class="function-link"><span class="function-syntax">LocalVariableSlates::find_Inter_identifier</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">frame</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">local_variables</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">, </span><span class="constant-syntax">INTERNAL_USE_LV</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. Searching by identifier. </b>One way is to search the slate for a scratch variable by its Inter name:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::by_identifier</span><button class="popup" onclick="togglePopup('usagePopup19')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup19">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::by_identifier</span></span>:<br/>Cinders and Deferrals - <a href="4-cad.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">stack_frame</span><span class="plain-syntax"> *</span><span class="identifier-syntax">frame</span><span class="plain-syntax"> = </span><a href="3-sf.html#SP2" class="function-link"><span class="function-syntax">Frames::current_stack_frame</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">frame</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-lvs.html#SP12" class="function-link"><span class="function-syntax">LocalVariableSlates::find_any_Inter_identifier</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">frame</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">local_variables</span><span class="plain-syntax">), </span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. </b>Locals used in predicate calculus have the names <span class="extract"><span class="extract-syntax">x</span></span>, <span class="extract"><span class="extract-syntax">y</span></span>, <span class="extract"><span class="extract-syntax">z</span></span>, <span class="extract"><span class="extract-syntax">a</span></span>, <span class="extract"><span class="extract-syntax">b</span></span>, ...;
the following looks for this identifier, where <span class="extract"><span class="extract-syntax">v</span></span> counts from 0 to 25 through
this reordered alphabet.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::find_pcalc_var</span><button class="popup" onclick="togglePopup('usagePopup20')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup20">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::find_pcalc_var</span></span>:<br/>Compile Schemas - <a href="4-cs.html#SP5_1">&#167;5.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">v</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">stack_frame</span><span class="plain-syntax"> *</span><span class="identifier-syntax">frame</span><span class="plain-syntax"> = </span><a href="3-sf.html#SP2" class="function-link"><span class="function-syntax">Frames::current_stack_frame</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">frame</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LOCALS_IN_FRAME</span><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">, </span><span class="identifier-syntax">frame</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">identifier</span><span class="plain-syntax">) == </span><span class="constant-syntax">1</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">identifier</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">) == </span><span class="identifier-syntax">pcalc_vars</span><span class="plain-syntax">[</span><span class="identifier-syntax">v</span><span class="plain-syntax">])</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. Searching by index. </b>Another way to search is by index. The following, for instance, returns
the ith call parameter on the current slate (counting from 0), or <span class="extract"><span class="extract-syntax">NULL</span></span> if
there isn't one.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::get_ith_parameter</span><button class="popup" onclick="togglePopup('usagePopup21')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup21">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::get_ith_parameter</span></span>:<br/><a href="3-lv.html#SP16">&#167;16</a><br/>Compile Imperative Definitions - <a href="3-cid.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">stack_frame</span><span class="plain-syntax"> *</span><span class="identifier-syntax">frame</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LOCALS_IN_FRAME</span><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">, </span><span class="identifier-syntax">frame</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lv_purpose</span><span class="plain-syntax"> == </span><span class="constant-syntax">TOKEN_CALL_PARAMETER_LV</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax">++ == </span><span class="identifier-syntax">i</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. </b>"It", when it's allowed, refers always to the first call parameter. This is
used, for instance, in defining adjectives by phrases, where the value which
is to be judged goes in to the first call parameter.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::it_variable</span><button class="popup" onclick="togglePopup('usagePopup22')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup22">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::it_variable</span></span>:<br/><a href="3-lv.html#SP17_1">&#167;17.1</a>, <a href="3-lv.html#SP17_3">&#167;17.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">stack_frame</span><span class="plain-syntax"> *</span><span class="identifier-syntax">frame</span><span class="plain-syntax"> = </span><a href="3-sf.html#SP2" class="function-link"><span class="function-syntax">Frames::current_stack_frame</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">frame</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">frame</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">local_variables</span><span class="plain-syntax">.</span><span class="element-syntax">it_variable_exists</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-lv.html#SP15" class="function-link"><span class="function-syntax">LocalVariables::get_ith_parameter</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">frame</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. Searching by I7 source name. </b>Because local variables come and go on the breeze, we parse them by hand rather
than with the excerpt parser's symbols table.<sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup> All the same we make use of the
excerpt hashing function, to reuse as much earlier work as possible, and the
following is very fast.
</p>
<ul class="footnotetexts"><li class="footnote" id="fn:2"><p class="inwebfootnote"><sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup> Experiment shows that this is better, and that there's a reward for not allowing
the hash table of excerpts to grow, contrary to the general experience with C-like
compiler symbols tables.
<a href="#fnref:2" title="return to text"> &#x21A9;</a></p></li></ul>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::parse</span><button class="popup" onclick="togglePopup('usagePopup23')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup23">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::parse</span></span>:<br/><a href="3-lv.html#SP18">&#167;18</a><br/>Compile Invocations Inline - <a href="5-cii.html#SP7_1">&#167;7.1</a>, <a href="5-cii.html#SP8">&#167;8</a><br/>Compile Solutions to Equations - <a href="5-cste.html#SP3_3">&#167;3.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">stack_frame</span><span class="plain-syntax"> *</span><span class="identifier-syntax">frame</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">frame</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP17" class="function-link"><span class="function-syntax">LocalVariables::parse_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">frame</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">) </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_usage</span><span class="plain-syntax">.</span><span class="element-syntax">parsed_recently</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::parse_inner</span><span class="plain-syntax">(</span><span class="reserved-syntax">stack_frame</span><span class="plain-syntax"> *</span><span class="identifier-syntax">frame</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lv.html#SP17_1" class="named-paragraph-link"><span class="named-paragraph">Recognise the pronoun it as parameter 0</span><span class="named-paragraph-number">17.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lv.html#SP17_2" class="named-paragraph-link"><span class="named-paragraph">Remove the definite article</span><span class="named-paragraph-number">17.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lv.html#SP17_3" class="named-paragraph-link"><span class="named-paragraph">Recognise the it-pseudonym as parameter 0</span><span class="named-paragraph-number">17.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lv.html#SP17_4" class="named-paragraph-link"><span class="named-paragraph">Parse the locals directly</span><span class="named-paragraph-number">17.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17_1" class="paragraph-anchor"></a><b>&#167;17.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Recognise the pronoun it as parameter 0</span><span class="named-paragraph-number">17.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">frame</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">local_variables</span><span class="plain-syntax">.</span><span class="element-syntax">it_variable_exists</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;agent-pronoun&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pronoun_usage</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pu</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;rp&gt;&gt;</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Stock::usage_might_be_third_person</span><span class="plain-syntax">(</span><span class="identifier-syntax">pu</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">usage</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-lv.html#SP16" class="function-link"><span class="function-syntax">LocalVariables::it_variable</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lv.html#SP17">&#167;17</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP17_2" class="paragraph-anchor"></a><b>&#167;17.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Remove the definite article</span><span class="named-paragraph-number">17.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;definite-article&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Articles::remove_the</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lv.html#SP17">&#167;17</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP17_3" class="paragraph-anchor"></a><b>&#167;17.3. </b>Only a few stack frames allow "it" and only some of those also have a pseudonym
for it, so it doesn't seem worth hashing this:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Recognise the it-pseudonym as parameter 0</span><span class="named-paragraph-number">17.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">frame</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">local_variables</span><span class="plain-syntax">.</span><span class="element-syntax">it_pseudonym</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::match</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">frame</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">local_variables</span><span class="plain-syntax">.</span><span class="element-syntax">it_pseudonym</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-lv.html#SP16" class="function-link"><span class="function-syntax">LocalVariables::it_variable</span></a><span class="plain-syntax">();</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lv.html#SP17">&#167;17</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP17_4" class="paragraph-anchor"></a><b>&#167;17.4. </b>Earlier builds of Inform went to some trouble to parse these in reverse
creation order, so that if the same name existed both as a loop variable
and outside it, the inner one would always be parsed &mdash; compare C, where
this is legal (if doubtful in style). But since the Inform language no
longer permits local names to be overloaded like this, there's no longer
any need.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse the locals directly</span><span class="named-paragraph-number">17.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Lexicon::wording_hash</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LOCALS_IN_FRAME</span><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">, </span><span class="identifier-syntax">frame</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_usage</span><span class="plain-syntax">.</span><span class="element-syntax">varname</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax"> == </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_usage</span><span class="plain-syntax">.</span><span class="element-syntax">name_hash</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">allocated</span><span class="plain-syntax"> == </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::match</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_usage</span><span class="plain-syntax">.</span><span class="element-syntax">varname</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lv.html#SP17">&#167;17</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. </b>And this is much the same function in a Preform wrapper:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="function-syntax">&lt;existing-local-name&gt;</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax"> = </span><a href="3-lv.html#SP17" class="function-link"><span class="function-syntax">LocalVariables::parse</span></a><span class="plain-syntax">(</span><a href="3-sf.html#SP2" class="function-link"><span class="function-syntax">Frames::current_stack_frame</span></a><span class="plain-syntax">(), </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> ==&gt; { -, </span><span class="identifier-syntax">lvar</span><span class="plain-syntax"> };</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> ==&gt; { </span><span class="identifier-syntax">fail</span><span class="plain-syntax"> </span><span class="identifier-syntax">nonterminal</span><span class="plain-syntax"> };</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. Monitoring parsing. </b>It turns out to be useful to check whether local variables are ever accessed
by something we're compiling. To do this, call <a href="3-lv.html#SP19" class="internal">LocalVariables::monitor_local_parsing</a>,
compile some code, and then call <a href="3-lv.html#SP19" class="internal">LocalVariables::local_parsed_recently</a> to
see whether that code ever accessed the locals (or the two ct table-selection
variables).
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">stack_selection_used_recently</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LocalVariables::monitor_local_parsing</span><span class="plain-syntax">(</span><span class="reserved-syntax">stack_frame</span><span class="plain-syntax"> *</span><span class="identifier-syntax">frame</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">frame</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LOCALS_IN_FRAME</span><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">, </span><span class="identifier-syntax">frame</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_usage</span><span class="plain-syntax">.</span><span class="element-syntax">parsed_recently</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">stack_selection_used_recently</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LocalVariables::used_ct_locals</span><button class="popup" onclick="togglePopup('usagePopup24')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup24">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::used_ct_locals</span></span>:<br/>Compile Lvalues - <a href="2-cl.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">stack_selection_used_recently</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">LocalVariables::local_parsed_recently</span><span class="plain-syntax">(</span><span class="reserved-syntax">stack_frame</span><span class="plain-syntax"> *</span><span class="identifier-syntax">frame</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">frame</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LOCALS_IN_FRAME</span><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">, </span><span class="identifier-syntax">frame</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_usage</span><span class="plain-syntax">.</span><span class="element-syntax">parsed_recently</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">stack_selection_used_recently</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. Callings. </b>A "calling" is a declaration of the sort found in text like "a body which is part
of a person (called the owner)". This will need to create a local variable with
the name "the owner". Here <span class="extract"><span class="extract-syntax">W</span></span> would be that name, and <span class="extract"><span class="extract-syntax">K</span></span> would be <span class="extract"><span class="extract-syntax">K_body</span></span>:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">PM_CalledWithDash_wording</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING_INIT</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::ensure_calling</span><button class="popup" onclick="togglePopup('usagePopup25')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup25">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::ensure_calling</span></span>:<br/><a href="3-lv.html#SP22">&#167;22</a><br/>Matching Action Patterns - <a href="2-map.html#SP3_5_1_1_1_20">&#167;3.5.1.1.1.20</a>, <a href="2-map.html#SP5">&#167;5</a><br/>Deciding to Defer - <a href="4-dtd.html#SP8_1">&#167;8.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-sf.html#SP2" class="function-link"><span class="function-syntax">Frames::current_stack_frame</span></a><span class="plain-syntax">()) &amp;&amp; (</span><span class="function-syntax">&lt;new-calling&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;rp&gt;&gt;</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">K</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">)) </span><a href="3-lv.html#SP25" class="function-link"><span class="function-syntax">LocalVariables::set_kind</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>&#167;21. </b>The work is done by this Preform grammar:
</p>
<pre class="Preform-displayed-code all-displayed-code code-font">
<span class="Preform-function-syntax">&lt;new-calling&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;definite-article&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;new-calling-unarticled&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> { pass 2 }</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;new-calling-unarticled&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> { pass 1 }</span>
<span class="Preform-function-syntax">&lt;new-calling-unarticled&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">::=</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">***</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">-</span><span class="Preform-plain-syntax"> </span><span class="Preform-constant-syntax">***</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lv.html#SP21_1" class="named-paragraph-link"><span class="named-paragraph">Issue PM_CalledWithDash problem</span><span class="named-paragraph-number">21.1</span></a></span>
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;existing-local-name&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> { pass 1 }</span>
<span class="Preform-plain-syntax"> </span><span class="Preform-function-syntax">&lt;s-type-expression-or-value&gt;</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">|</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-lv.html#SP21_2" class="named-paragraph-link"><span class="named-paragraph">Vet to see if this name can be overloaded</span><span class="named-paragraph-number">21.2</span></a></span>
<span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">...</span><span class="Preform-plain-syntax"> </span><span class="Preform-reserved-syntax">==&gt;</span><span class="Preform-plain-syntax"> { 0, LocalVariables::new_let_value(W, K_object) }</span>
</pre>
<ul class="endnotetexts"><li>This is <a href="../words-module/4-ap.html" class="internal">Preform grammar</a>, not regular C code.</li></ul>
<p class="commentary firstcommentary"><a id="SP21_1" class="paragraph-anchor"></a><b>&#167;21.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Issue PM_CalledWithDash problem</span><span class="named-paragraph-number">21.1</span></span><span class="Preform-comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!(</span><span class="identifier-syntax">Wordings::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_CalledWithDash_wording</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PM_CalledWithDash_wording</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::sentence_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_CalledWithDash</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="string-syntax">"a '(called ...)' name is not allowed to include a hyphen"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"since this would look misleadingly like a declaration of kind of value it has."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> ==&gt; { </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lv.html#SP21">&#167;21</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP21_2" class="paragraph-anchor"></a><b>&#167;21.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Vet to see if this name can be overloaded</span><span class="named-paragraph-number">21.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">already</span><span class="plain-syntax"> = </span><span class="function-syntax">&lt;&lt;rp&gt;&gt;</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-lv.html#SP23" class="function-link"><span class="function-syntax">LocalVariables::permit_as_new_local</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">already</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Meaning already existing: $T\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">already</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Specifications::is_kind_like</span><span class="plain-syntax">(</span><span class="identifier-syntax">already</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_text</span><span class="plain-syntax">(3, </span><span class="string-syntax">"a kind"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::quote_kind_of</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">already</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_CalledOverloaded</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><span class="string-syntax">"In %1, it looks as if '%2' is going to be a temporary name which something "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"will be called. But I can't allow that, because it already has a meaning "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"as %3."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> ==&gt; { </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-lv.html#SP21">&#167;21</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP22" class="paragraph-anchor"></a><b>&#167;22. </b>The following rather inelegantly picks up any apparent callings in some text,
making all of them objects.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">last_mnc_wording</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING_INIT</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LocalVariables::make_necessary_callings</span><span class="plain-syntax">(</span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::within</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">last_mnc_wording</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_mnc_wording</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="function-syntax">&lt;text-including-a-calling&gt;</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;text-including-a-calling&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GET_RW</span><span class="plain-syntax">(</span><span class="function-syntax">&lt;text-including-a-calling&gt;</span><span class="plain-syntax">, </span><span class="constant-syntax">3</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-lv.html#SP20" class="function-link"><span class="function-syntax">LocalVariables::ensure_calling</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">V</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_object</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>&#167;23. Permissible names. </b>This is an interesting issue of policy. Suppose the source text says:
</p>
<blockquote>
<p>let the slate be 1;</p>
</blockquote>
<p class="commentary">and, far away, an object called "the slate" is sitting on a schoolroom desk.
Do we allow this, thus temporarily changing the meaning of "slate", or do
we throw it out with a problem message? If we allow it, we enable source text
to become less clear, since meaning now depends on context. If we forbid it,
we cause all sorts of things to go wrong with extensions (including not least
the Standard Rules): because suppose they contain a local called "slate"
somewhere, and then the unsuspecting user writes
</p>
<blockquote>
<p>The slate is on the desk.</p>
</blockquote>
<p class="commentary">Now there's a conflict, and the user will be baffled, never having read the
extension he's using. So we do allow this, and certain other overloadings
of meanings, too, but it would be too much to say that every phrase has its
own namespace.
</p>
<p class="commentary">Callings get one extra benefit, because they typically exist more fleetingly &mdash;
often only for the sentence where they're defined &mdash; and because the syntax
is more explicit. So you can write:
</p>
<blockquote>
<p>if an infected person can see a healthy person (called random bystander), ...</p>
</blockquote>
<p class="commentary">even if "random bystander" might otherwise be a request to randomly generate
an instance of the kind "bystander".
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">LocalVariables::permit_as_new_local</span><button class="popup" onclick="togglePopup('usagePopup26')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup26">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::permit_as_new_local</span></span>:<br/><a href="3-lv.html#SP21_2">&#167;21.2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">found</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">as_calling</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">found</span><span class="plain-syntax">, </span><span class="identifier-syntax">AMBIGUITY_NT</span><span class="plain-syntax">)) </span><span class="identifier-syntax">found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">found</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">down</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Specifications::is_kind_like</span><span class="plain-syntax">(</span><span class="identifier-syntax">found</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Kinds::Behaviour::is_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">Specifications::to_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">found</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">found</span><span class="plain-syntax">, </span><span class="identifier-syntax">UNKNOWN_NT</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Node::is</span><span class="plain-syntax">(</span><span class="identifier-syntax">found</span><span class="plain-syntax">, </span><span class="identifier-syntax">NONLOCAL_VARIABLE_NT</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Specifications::is_description</span><span class="plain-syntax">(</span><span class="identifier-syntax">found</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Rvalues::is_object</span><span class="plain-syntax">(</span><span class="identifier-syntax">found</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Rvalues::to_instance</span><span class="plain-syntax">(</span><span class="identifier-syntax">found</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Rvalues::is_CONSTANT_construction</span><span class="plain-syntax">(</span><span class="identifier-syntax">found</span><span class="plain-syntax">, </span><span class="identifier-syntax">CON_table_column</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">Rvalues::is_CONSTANT_construction</span><span class="plain-syntax">(</span><span class="identifier-syntax">found</span><span class="plain-syntax">, </span><span class="identifier-syntax">CON_property</span><span class="plain-syntax">))) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">as_calling</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Specifications::is_phrasal</span><span class="plain-syntax">(</span><span class="identifier-syntax">found</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP24" class="paragraph-anchor"></a><b>&#167;24. Kind. </b>Of a single variable:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="function-syntax">LocalVariables::kind</span><button class="popup" onclick="togglePopup('usagePopup27')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup27">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::kind</span></span>:<br/>Compile Conditions - <a href="2-cc.html#SP5_1">&#167;5.1</a><br/>Compile Solutions to Equations - <a href="5-cste.html#SP3_3_2">&#167;3.3.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_usage</span><span class="plain-syntax">.</span><span class="element-syntax">kind_as_declared</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP25" class="paragraph-anchor"></a><b>&#167;25. </b>Locals are sometimes created before their kinds are known, so this call
exists to fix that:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LocalVariables::set_kind</span><button class="popup" onclick="togglePopup('usagePopup28')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup28">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::set_kind</span></span>:<br/><a href="3-lv.html#SP20">&#167;20</a><br/>Compile Imperative Definitions - <a href="3-cid.html#SP10">&#167;10</a><br/>Compile Loops - <a href="4-cl.html#SP4">&#167;4</a><br/>Compile Blocks and Lines - <a href="5-cbal.html#SP4_4_5_1_1">&#167;4.4.5.1.1</a><br/>Compile Invocations Inline - <a href="5-cii.html#SP6_6_1_1_1">&#167;6.6.1.1.1</a><br/>Compile Solutions to Equations - <a href="5-cste.html#SP3_3_2">&#167;3.3.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">, </span><span class="identifier-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lvar</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Tried to set kind of nonexistent local variable"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">LOCAL_VARIABLES</span><span class="plain-syntax">, </span><span class="string-syntax">"Kind of local $k set to %u\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">, </span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">current_usage</span><span class="plain-syntax">.</span><span class="element-syntax">kind_as_declared</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP26" class="paragraph-anchor"></a><b>&#167;26. Logging. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LocalVariables::log</span><button class="popup" onclick="togglePopup('usagePopup29')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup29">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::log</span></span>:<br/>Imperative Module - <a href="1-im.html#SP2">&#167;2</a><br/>Stack Frames - <a href="3-sf.html#SP22">&#167;22</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="3-lv.html#SP26" class="function-link"><span class="function-syntax">LocalVariables::write</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">DL</span><span class="plain-syntax">, </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LocalVariables::writer</span><button class="popup" onclick="togglePopup('usagePopup30')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup30">Usage of <span class="code-font"><span class="function-syntax">LocalVariables::writer</span></span>:<br/>Imperative Module - <a href="1-im.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">format_string</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">vL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">vL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lvar</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no such variable"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">format_string</span><span class="plain-syntax">[0]) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'L'</span><span class="plain-syntax">: </span><span class="comment-syntax"> bare </span><span class="extract"><span class="extract-syntax">%L</span></span><span class="comment-syntax"> means the same as </span><span class="extract"><span class="extract-syntax">%+L</span></span><span class="comment-syntax">, so fall through to...</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'+'</span><span class="plain-syntax">: </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%+W"</span><span class="plain-syntax">, </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_usage</span><span class="plain-syntax">.</span><span class="element-syntax">varname</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'-'</span><span class="plain-syntax">: </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%-W"</span><span class="plain-syntax">, </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_usage</span><span class="plain-syntax">.</span><span class="element-syntax">varname</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'~'</span><span class="plain-syntax">: </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">identifier</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"bad %L modifier"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">LocalVariables::write</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">local_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">allocated</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) { </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"LV&lt;unallocated&gt;"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">current_usage</span><span class="plain-syntax">.</span><span class="element-syntax">varname</span><span class="plain-syntax">)) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"LV\"%W\""</span><span class="plain-syntax">, </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_usage</span><span class="plain-syntax">.</span><span class="element-syntax">varname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"LV&lt;nameless&gt;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"-"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::Textual::write</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">lvar</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">current_usage</span><span class="plain-syntax">.</span><span class="element-syntax">kind_as_declared</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="3-lvs.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-im.html">1</a></li><li class="progresschapter"><a href="2-cv.html">2</a></li><li class="progresscurrentchapter">3</li><li class="progresssection"><a href="3-sf.html">sf</a></li><li class="progresssection"><a href="3-lvs.html">lvs</a></li><li class="progresscurrent">lv</li><li class="progresssection"><a href="3-tv.html">tv</a></li><li class="progresssection"><a href="3-lp.html">lp</a></li><li class="progresssection"><a href="3-cb.html">cb</a></li><li class="progresssection"><a href="3-fnc.html">fnc</a></li><li class="progresssection"><a href="3-jl.html">jl</a></li><li class="progresssection"><a href="3-pr.html">pr</a></li><li class="progresssection"><a href="3-cls.html">cls</a></li><li class="progresssection"><a href="3-cid.html">cid</a></li><li class="progresschapter"><a href="4-cs.html">4</a></li><li class="progresschapter"><a href="5-cbal.html">5</a></li><li class="progressnext"><a href="3-tv.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>