mirror of
https://github.com/ganelson/inform.git
synced 2024-07-08 18:14:21 +03:00
1697 lines
217 KiB
HTML
1697 lines
217 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>23/abc</title>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
</head>
|
|
<body>
|
|
|
|
<!--Weave of '24/lv' generated by 7-->
|
|
<ul class="crumbs"><li><a href="../webs.html">★</a></li><li><a href="index.html">core</a></li><li><a href="index.html#24">Chapter 24: Compilation Context</a></li><li><b>Local Variables</b></li></ul><p class="purpose">Local variables are used for call parameters, temporary values, and other ephemeral workspace.</p>
|
|
|
|
<ul class="toc"><li><a href="#SP1">§1. Definitions</a></li><li><a href="#SP6">§6. Boxing</a></li><li><a href="#SP7">§7. Adding</a></li><li><a href="#SP15">§15. Deallocating</a></li><li><a href="#SP17">§17. Extent</a></li><li><a href="#SP18">§18. Copying</a></li><li><a href="#SP19">§19. Searching</a></li><li><a href="#SP26">§26. It</a></li><li><a href="#SP28">§28. Local Parking</a></li><li><a href="#SP30">§30. Equation terms</a></li><li><a href="#SP31">§31. Callings</a></li><li><a href="#SP34">§34. Permissible names</a></li><li><a href="#SP35">§35. Logging</a></li><li><a href="#SP37">§37. Kind</a></li><li><a href="#SP39">§39. Protection</a></li><li><a href="#SP40">§40. Block scope</a></li><li><a href="#SP43">§43. Callings</a></li><li><a href="#SP44">§44. Writer</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. Definitions. </b></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP2"></a><b>§2. </b>Each phrase has its own "slate" of local variables. For example, in
|
|
the definition "..." of:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>To attract (ferrous item - a thing) with (magnet - a thing), uninsulated: ...</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">two locals are "ferrous item" and "magnet", of type <code class="display"><span class="extract">TOKEN_CALL_PARAMETER_LV</span></code>.
|
|
The presence of ", uninsulated" means that another local is "phrase options",
|
|
of type <code class="display"><span class="extract">OTHER_CALL_PARAMETER_LV</span></code>, because the bitmap of options chosen is
|
|
passed as an additional call parameter when the phrase is invoked.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Within the definition, we might have:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>let Q be the electrical charge;</p>
|
|
|
|
</blockquote>
|
|
|
|
<blockquote>
|
|
<p>repeat with the item running through things: say "The needle flickers over [the item]."</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">Here "Q" and "item" are both <code class="display"><span class="extract">LET_VALUE_LV</span></code> variables, but whereas "Q" exists
|
|
all through the phrase, "item" exists only inside its own repeat loop: this
|
|
is called its block scope. When Inform compiles on past the end of the loop,
|
|
it doesn't actually delete the local variable structure for "item": it simply
|
|
marks it as deallocated.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">A slate of locals is stored like so:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">locals_slate</span><span class="plain"> {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">local_variable_allocation</span><span class="plain">; </span> <span class="comment">linked list of valid locals</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">it_variable_exists</span><span class="plain">; </span> <span class="comment">it, he, she, or they, used for adjective definitions</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">its_form_allowed</span><span class="plain">; </span> <span class="comment">its, his, her or their, ditto</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">it_pseudonym</span><span class="plain">; </span> <span class="comment">a further variation on the same variable</span>
|
|
<span class="plain">} </span><span class="reserved">locals_slate</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure locals_slate is accessed in 24/sf and here.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b>Which contains a linked list of variables of the following types:
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">TOKEN_CALL_PARAMETER_LV</span><span class="plain"> 1 </span> <span class="comment">values for the tokens of the phrase being invoked</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">OTHER_CALL_PARAMETER_LV</span><span class="plain"> 2 </span> <span class="comment">other implied parameters passed during invocation: I6-level only</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">LET_VALUE_LV</span><span class="plain"> 3 </span> <span class="comment">variables created by "let", "while" or "repeat"</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">INTERNAL_USE_LV</span><span class="plain"> 4 </span> <span class="comment">workspace needed by our compiled code: I6-level only</span>
|
|
</pre>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">local_variable</span><span class="plain"> {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">lv_purpose</span><span class="plain">; </span> <span class="comment">one of the <code class="display"><span class="extract">*_LV</span></code> values above</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">lv_lvalue</span><span class="plain">; </span> <span class="comment">an Inform lvalue for the variable's run-time storage</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">index_with_this_purpose</span><span class="plain">; </span> <span class="comment">what index count it has, within locals of its type</span>
|
|
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">comment_on_use</span><span class="plain">; </span> <span class="comment">purely to make the output more legible</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">allocated</span><span class="plain">; </span> <span class="comment">in existence at this point in the routine?</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">duplicated</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">varname</span><span class="plain">; </span> <span class="comment">name of local variable</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">name_hash</span><span class="plain">; </span> <span class="comment">hash code for this name</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">block_scope</span><span class="plain">; </span> <span class="comment">scope of a local - block depth</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">free_at_end_of_scope</span><span class="plain">; </span> <span class="comment">whether it holds temporary data on heap</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">kind_as_declared</span><span class="plain">; </span> <span class="comment">data type for the contents</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">protected</span><span class="plain">; </span> <span class="comment">from alteration using "let"?</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">parsed_recently</span><span class="plain">; </span> <span class="comment">name recognised since this was last wiped?</span>
|
|
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">next</span><span class="plain">; </span> <span class="comment">on the same slate</span>
|
|
<span class="identifier">MEMORY_MANAGEMENT</span>
|
|
<span class="plain">} </span><span class="reserved">local_variable</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure local_variable is accessed in 3/pd, 5/lp, 5/ut, 5/un, 5/ins, 6/rlt, 6/nv, 7/ss, 7/hdn, 7/ns, 7/oaf, 7/rs, 8/ie, 8/ec, 8/ed, 9/tfa, 9/tbath, 9/rpt, 9/tc, 9/ma, 9/rk, 9/ass, 9/imp, 9/pd, 10/teav, 10/cap, 11/ap, 11/pr, 11/bas, 11/tc, 11/sm, 12/dtd, 12/cdp, 14/rv, 14/lv, 14/cn, 14/ds, 14/ds2, 15/cp, 16/is, 16/in, 19/tb, 19/rsft, 19/tod, 20/eq, 21/rl, 21/rl2, 21/fao, 21/rps, 21/sv, 21/ac, 22/ph, 22/tp, 22/tp2, 23/ad, 24/sf, 25/in, 25/pi, 25/cii, 25/cp, 26/uo, 26/tti, 26/pc, 26/ts, 27/cm and here.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. </b>A local variable needs to be stored somewhere at run-time. The obvious
|
|
correspondence is to put these into I6 local variables, which are, in effect,
|
|
CPU registers. We won't need to do much in the way of register-allocation,
|
|
though; we simply take the opportunity to reuse I6 locals if it presents
|
|
itself. The resulting I6 function tends to look like this example:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><code class="display"><span class="extract">[ R_314 t_0 t_1 phrase_options tmp_0 tmp_1 tmp_2 ct_0 ct_1;</span></code>
|
|
</p>
|
|
|
|
<p class="inwebparagraph">where there are two tokens passed to the routine (<code class="display"><span class="extract">t_0</span></code> and <code class="display"><span class="extract">t_1</span></code>), and
|
|
there are phrase options (whose bitmap is in <code class="display"><span class="extract">phrase_options</span></code>), and at
|
|
the busiest point in the routine three temporary values are needed at
|
|
once (<code class="display"><span class="extract">tmp_0</span></code> and so on), and finally table-row selection will be
|
|
going on, so that we need to record a choice of table (<code class="display"><span class="extract">ct_0</span></code>) and
|
|
row number within that table (<code class="display"><span class="extract">ct_1</span></code>). A typical invocation of this
|
|
example phrase would compile to I6 like so:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><code class="display"><span class="extract">R_314(20, O31_black_marble_slab, 16);</span></code>
|
|
</p>
|
|
|
|
<p class="inwebparagraph">It is perhaps worth stopping to ask ourselves why it is helpful for
|
|
values to be in local variables. Unlike traditional register allocation,
|
|
this is not done for any speed gain — in the Z-machine, there is no
|
|
particular advantage to a local vs a global variable. The actual reason
|
|
is to place a value in the stack frame for the current routine. For
|
|
instance, each phrase must have its own "currently selected table row":
|
|
it would not do for one phrase which uses another one to find that the
|
|
table row had been deselected as a side-effect. So <code class="display"><span class="extract">ct_0</span></code> and <code class="display"><span class="extract">ct_1</span></code>
|
|
are most conveniently stored as locals, not globals.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§5. </b>Tabula rasa:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">locals_slate</span><span class="plain"> </span><span class="functiontext">LocalVariables::blank_slate</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">locals_slate</span><span class="plain"> </span><span class="identifier">slate</span><span class="plain">;</span>
|
|
<span class="identifier">slate</span><span class="element">.local_variable_allocation</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">slate</span><span class="element">.it_pseudonym</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
|
|
<span class="identifier">slate</span><span class="element">.it_variable_exists</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span><span class="identifier">slate</span><span class="element">.its_form_allowed</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">slate</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::blank_slate is used in 24/sf (<a href="24-sf.html#SP5">§5</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§6. Boxing. </b>It's sometimes necessary to "box" a stack frame — to store the entire current
|
|
context of compilation for later use. That includes locals, so:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::deep_copy_locals_slate</span><span class="plain">(</span><span class="reserved">locals_slate</span><span class="plain"> *</span><span class="identifier">slate_to</span><span class="plain">, </span><span class="reserved">locals_slate</span><span class="plain"> *</span><span class="identifier">slate_from</span><span class="plain">) {</span>
|
|
<span class="plain">*</span><span class="identifier">slate_to</span><span class="plain"> = *</span><span class="identifier">slate_from</span><span class="plain">;</span>
|
|
<span class="identifier">slate_to</span><span class="plain">-</span><span class="element">>local_variable_allocation</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">, *</span><span class="identifier">tail</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">slate_from</span><span class="plain">-</span><span class="element">>local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">=</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">dup</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">local_variable</span><span class="plain">); *</span><span class="identifier">dup</span><span class="plain"> = *</span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="identifier">dup</span><span class="plain">-</span><span class="element">>duplicated</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="identifier">dup</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tail</span><span class="plain">) </span><span class="identifier">tail</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> = </span><span class="identifier">dup</span><span class="plain">; </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">slate_to</span><span class="plain">-</span><span class="element">>local_variable_allocation</span><span class="plain"> = </span><span class="identifier">dup</span><span class="plain">;</span>
|
|
<span class="identifier">tail</span><span class="plain"> = </span><span class="identifier">dup</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::deep_copy_locals_slate is used in 24/sf (<a href="24-sf.html#SP7">§7</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§7. Adding. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::add_to_locals_slate</span><span class="plain">(</span><span class="reserved">locals_slate</span><span class="plain"> *</span><span class="identifier">slate</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">purpose</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">,</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">override_lvalue</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">override_index</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">ix</span><span class="plain"> = 0; </span> <span class="comment">the new one will be the 0th, 1st, 2nd, ... with the same purpose</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">slate</span><span class="plain">) </span><<span class="cwebmacro">Make use of an unallocated var if possible, but otherwise add a new one</span> <span class="cwebmacronumber">7.1</span>>
|
|
<span class="reserved">else</span><span class="plain"> </span><<span class="cwebmacro">Make a new local variable structure</span> <span class="cwebmacronumber">7.2</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">override_index</span><span class="plain"> >= 0) </span><span class="identifier">ix</span><span class="plain"> = </span><span class="identifier">override_index</span><span class="plain">;</span>
|
|
<<span class="cwebmacro">Fill in the local variable structure, whether it's new or recycled</span> <span class="cwebmacronumber">7.3</span>><span class="character">;</span>
|
|
|
|
<span class="functiontext">ExParser::warn_expression_cache</span><span class="plain">(); </span> <span class="comment">the range of parsing possibilities has changed</span>
|
|
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::add_to_locals_slate is used in <a href="#SP8">§8</a>, <a href="#SP10">§10</a>, <a href="#SP11">§11</a>, <a href="#SP18">§18</a>, <a href="#SP26">§26</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7_1"></a><b>§7.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Make use of an unallocated var if possible, but otherwise add a new one</span> <span class="cwebmacronumber">7.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">find</span><span class="plain"> = </span><span class="identifier">slate</span><span class="plain">-</span><span class="element">>local_variable_allocation</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">find</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<<span class="cwebmacro">Make a new local variable structure</span> <span class="cwebmacronumber">7.2</span>><span class="plain">;</span>
|
|
<span class="identifier">slate</span><span class="plain">-</span><span class="element">>local_variable_allocation</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">find</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">find</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> == </span><span class="identifier">purpose</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">find</span><span class="plain">-</span><span class="element">>allocated</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) { </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">find</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">; }</span>
|
|
<span class="identifier">ix</span><span class="plain">++;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">find</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<<span class="cwebmacro">Make a new local variable structure</span> <span class="cwebmacronumber">7.2</span>><span class="plain">;</span>
|
|
<span class="identifier">find</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">find</span><span class="plain"> = </span><span class="identifier">find</span><span class="plain">-</span><span class="element">>next</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7_2"></a><b>§7.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Make a new local variable structure</span> <span class="cwebmacronumber">7.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">local_variable</span><span class="plain">);</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>duplicated</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP7">§7</a>, <a href="#SP7_1">§7.1</a> (twice).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7_3"></a><b>§7.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Fill in the local variable structure, whether it's new or recycled</span> <span class="cwebmacronumber">7.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> = </span><span class="identifier">purpose</span><span class="plain">;</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>allocated</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">override_lvalue</span><span class="plain">) </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_lvalue</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">override_lvalue</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_lvalue</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
|
|
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">prefix</span><span class="plain"> = </span><span class="string">"unknown"</span><span class="plain">;</span>
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">purpose</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">TOKEN_CALL_PARAMETER_LV</span><span class="plain">: </span><span class="identifier">prefix</span><span class="plain"> = </span><span class="string">"t"</span><span class="plain">;</span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">OTHER_CALL_PARAMETER_LV</span><span class="plain">: </span><span class="identifier">prefix</span><span class="plain"> = </span><span class="string">"ti"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">LET_VALUE_LV</span><span class="plain">: </span><span class="identifier">prefix</span><span class="plain"> = </span><span class="string">"tmp"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">INTERNAL_USE_LV</span><span class="plain">: </span><span class="identifier">prefix</span><span class="plain"> = </span><span class="string">"misc"</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">default</span><span class="plain">: </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"unknown local variable purpose"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_lvalue</span><span class="plain">, </span><span class="string">"%s_%d"</span><span class="plain">, </span><span class="identifier">prefix</span><span class="plain">, </span><span class="identifier">ix</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>index_with_this_purpose</span><span class="plain"> = </span><span class="identifier">ix</span><span class="plain">;</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>block_scope</span><span class="plain"> = 0; </span> <span class="comment">by default: universal scope throughout routine</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>free_at_end_of_scope</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>kind_as_declared</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">;</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>protected</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>parsed_recently</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>comment_on_use</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (<</span><span class="identifier">unsuitable</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">-</span><span class="reserved">for</span><span class="plain">-</span><span class="identifier">locals</span><span class="plain">>(</span><span class="identifier">W</span><span class="plain">)) </span><<span class="cwebmacro">Throw a problem for an unsuitable name</span> <span class="cwebmacronumber">7.3.1</span>><span class="plain">;</span>
|
|
<span class="identifier">W</span><span class="plain"> = </span><span class="identifier">Articles::remove_the</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>varname</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">;</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>name_hash</span><span class="plain"> = </span><span class="identifier">ExcerptMeanings::hash_code</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7_3_1"></a><b>§7.3.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Throw a problem for an unsuitable name</span> <span class="cwebmacronumber">7.3.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">W</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CalledThe</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"In %1, you seem to be giving a temporary value a pretty "</span>
|
|
<span class="string">"odd name - '%2', which I won't allow because it would lead to too "</span>
|
|
<span class="string">"many ambiguities."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP7_3">§7.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. </b>For example, here are the call parameters. If there are three of these,
|
|
they compile to the I6 names <code class="display"><span class="extract">t_0</span></code>, <code class="display"><span class="extract">t_1</span></code> and <code class="display"><span class="extract">t_2</span></code>.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::add_call_parameter</span><span class="plain">(</span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">,</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_to_locals_slate</span><span class="plain">(&(</span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables</span><span class="plain">),</span>
|
|
<span class="constant">TOKEN_CALL_PARAMETER_LV</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, -1);</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">LOCAL_VARIABLES</span><span class="plain">, </span><span class="string">"Call parameter $k added\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="functiontext">LocalVariables::add_call_parameter_as_symbol</span><span class="plain">(</span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">,</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">v</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_call_parameter</span><span class="plain">(</span><span class="identifier">phsf</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">v</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::add_call_parameter is used in <a href="#SP27">§27</a>, 15/ma (<a href="15-ma.html#SP13">§13</a>), 22/ptd (<a href="22-ptd.html#SP20">§20</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::add_call_parameter_as_symbol is used in 6/bp (<a href="6-bp.html#SP25">§25</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9"></a><b>§9. </b>Inversely:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">LocalVariables::get_parameter_number</span><span class="plain">(</span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">lvar</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> != </span><span class="constant">TOKEN_CALL_PARAMETER_LV</span><span class="plain">))</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"not a call parameter"</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>index_with_this_purpose</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::get_parameter_number is used in 25/cii (<a href="25-cii.html#SP3_1">§3.1</a>, <a href="25-cii.html#SP6">§6</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10"></a><b>§10. </b>And here are the "let" values, which can only be added to the routine
|
|
currently being compiled:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::new</span><span class="plain">(</span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to add let value without stack frame"</span><span class="plain">);</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_to_locals_slate</span><span class="plain">(&(</span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables</span><span class="plain">),</span>
|
|
<span class="constant">LET_VALUE_LV</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, -1);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Produce::emitting_routine</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">()))</span>
|
|
<span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 6);</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">LOCAL_VARIABLES</span><span class="plain">, </span><span class="string">"Let value $k allocated\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::new is used in <a href="#SP33_3">§33.3</a>, 12/dtd (<a href="12-dtd.html#SP23">§23</a>, <a href="12-dtd.html#SP27">§27</a>), 25/cii (<a href="25-cii.html#SP1_2_1">§1.2.1</a>, <a href="25-cii.html#SP3_5_1_1">§3.5.1.1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11"></a><b>§11. </b>Calling this guarantees the presence, at run-time, of an I6 local variable
|
|
with a given name. It won't be connected with any I7 values; it will just be
|
|
scratch work-space which can be used in the compiled code.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::add_internal</span><span class="plain">(</span><span class="reserved">locals_slate</span><span class="plain"> *</span><span class="identifier">slate</span><span class="plain">,</span>
|
|
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">purpose</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="functiontext">LocalVariables::find_i6_var</span><span class="plain">(</span><span class="identifier">slate</span><span class="plain">, </span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">purpose</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_to_locals_slate</span><span class="plain">(</span><span class="identifier">slate</span><span class="plain">, </span><span class="identifier">purpose</span><span class="plain">, </span><span class="identifier">EMPTY_WORDING</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">name</span><span class="plain">, -1);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::add_internal_local</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">) {</span>
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain">)</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::add_internal</span><span class="plain">(&(</span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables</span><span class="plain">), </span><span class="identifier">name</span><span class="plain">,</span>
|
|
<span class="constant">INTERNAL_USE_LV</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="functiontext">LocalVariables::add_internal_local_as_symbol</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">v</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_internal_local</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">v</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="functiontext">LocalVariables::add_internal_local_as_symbol_noting</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">, </span><span class="reserved">local_variable</span><span class="plain"> **</span><span class="identifier">lv</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">v</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_internal_local</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lv</span><span class="plain">) *</span><span class="identifier">lv</span><span class="plain"> = </span><span class="identifier">v</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">v</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::add_named_call</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">) {</span>
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain">)</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::add_internal</span><span class="plain">(&(</span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables</span><span class="plain">), </span><span class="identifier">name</span><span class="plain">,</span>
|
|
<span class="constant">OTHER_CALL_PARAMETER_LV</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="functiontext">LocalVariables::add_named_call_as_symbol</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">v</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_named_call</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">v</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="functiontext">LocalVariables::add_named_call_as_symbol_noting</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">, </span><span class="reserved">local_variable</span><span class="plain"> **</span><span class="identifier">lv</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">v</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_named_call</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lv</span><span class="plain">) *</span><span class="identifier">lv</span><span class="plain"> = </span><span class="identifier">v</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">v</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::add_internal_local_c</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">comment</span><span class="plain">) {</span>
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> =</span>
|
|
<span class="functiontext">LocalVariables::add_internal</span><span class="plain">(&(</span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables</span><span class="plain">),</span>
|
|
<span class="identifier">name</span><span class="plain">, </span><span class="constant">INTERNAL_USE_LV</span><span class="plain">);</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>comment_on_use</span><span class="plain"> = </span><span class="identifier">comment</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="functiontext">LocalVariables::add_internal_local_c_as_symbol</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">comment</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">v</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_internal_local_c</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">comment</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">v</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="functiontext">LocalVariables::add_internal_local_c_as_symbol_noting</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">comment</span><span class="plain">, </span><span class="reserved">local_variable</span><span class="plain"> **</span><span class="identifier">lv</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">v</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_internal_local_c</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">comment</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lv</span><span class="plain">) *</span><span class="identifier">lv</span><span class="plain"> = </span><span class="identifier">v</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">v</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::add_internal is used in <a href="#SP14">§14</a>.</p>
|
|
|
|
<p class="endnote">The function LocalVariables::add_internal_local is used in 25/cii (<a href="25-cii.html#SP3_5_1_2">§3.5.1.2</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::add_internal_local_as_symbol is used in 4/am (<a href="4-am.html#SP43">§43</a>), 5/lp (<a href="5-lp.html#SP27">§27</a>), 12/cdp (<a href="12-cdp.html#SP2_1_5">§2.1.5</a>, <a href="12-cdp.html#SP2_1_5_1">§2.1.5.1</a>), 17/rs (<a href="17-rs.html#SP6_2">§6.2</a>), 24/ch (<a href="24-ch.html#SP7">§7</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::add_internal_local_as_symbol_noting is used in 12/cdp (<a href="12-cdp.html#SP2_1_5">§2.1.5</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::add_named_call is used in <a href="#SP47">§47</a>, 13/rsfk (<a href="13-rsfk.html#SP24_6_3">§24.6.3</a>), 21/rb (<a href="21-rb.html#SP23">§23</a>), 22/pav (<a href="22-pav.html#SP9_2">§9.2</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::add_named_call_as_symbol is used in 4/am (<a href="4-am.html#SP43">§43</a>), 5/lp (<a href="5-lp.html#SP27">§27</a>), 6/rlt (<a href="6-rlt.html#SP15_2">§15.2</a>, <a href="6-rlt.html#SP17">§17</a>, <a href="6-rlt.html#SP29_1">§29.1</a>), 6/nv (<a href="6-nv.html#SP18_1">§18.1</a>, <a href="6-nv.html#SP18_2">§18.2</a>), 8/ef (<a href="8-ef.html#SP19">§19</a>), 12/cad (<a href="12-cad.html#SP5">§5</a>), 12/cdp (<a href="12-cdp.html#SP2_1_5">§2.1.5</a>, <a href="12-cdp.html#SP2_1_5_2">§2.1.5.2</a>), 13/rsfk (<a href="13-rsfk.html#SP16_3">§16.3</a>, <a href="13-rsfk.html#SP24_1">§24.1</a>, <a href="13-rsfk.html#SP24_2">§24.2</a>, <a href="13-rsfk.html#SP24_3">§24.3</a>, <a href="13-rsfk.html#SP24_5">§24.5</a>, <a href="13-rsfk.html#SP24_6_1">§24.6.1</a>, <a href="13-rsfk.html#SP24_6_2">§24.6.2</a>, <a href="13-rsfk.html#SP24_6_5">§24.6.5</a>, <a href="13-rsfk.html#SP24_6_6">§24.6.6</a>, <a href="13-rsfk.html#SP25">§25</a>), 17/rs (<a href="17-rs.html#SP6_2">§6.2</a>, <a href="17-rs.html#SP7_2">§7.2</a>), 19/tc (<a href="19-tc.html#SP8">§8</a>), 19/rsft (<a href="19-rsft.html#SP2">§2</a>), 21/rl (<a href="21-rl.html#SP20">§20</a>), 21/rb (<a href="21-rb.html#SP24_1_1">§24.1.1</a>), 21/rl2 (<a href="21-rl2.html#SP14_1">§14.1</a>), 21/fao (<a href="21-fao.html#SP10">§10</a>), 21/sv (<a href="21-sv.html#SP3">§3</a>), 24/ch (<a href="24-ch.html#SP7">§7</a>), 26/uo (<a href="26-uo.html#SP21_1">§21.1</a>, <a href="26-uo.html#SP21_2">§21.2</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::add_named_call_as_symbol_noting is used in 6/rlt (<a href="6-rlt.html#SP15_2">§15.2</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::add_internal_local_c is used in <a href="#SP12">§12</a>, <a href="#SP13">§13</a>, 13/rsfk (<a href="13-rsfk.html#SP24_6_2">§24.6.2</a>, <a href="13-rsfk.html#SP24_6_3">§24.6.3</a>, <a href="13-rsfk.html#SP24_6_4">§24.6.4</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::add_internal_local_c_as_symbol is used in 6/rlt (<a href="6-rlt.html#SP15">§15</a>), 21/rb (<a href="21-rb.html#SP24_1_1">§24.1.1</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::add_internal_local_c_as_symbol_noting is used in 6/rlt (<a href="6-rlt.html#SP15_2">§15.2</a>, <a href="6-rlt.html#SP29_2">§29.2</a>, <a href="6-rlt.html#SP29_3">§29.3</a>, <a href="6-rlt.html#SP29_4">§29.4</a>, <a href="6-rlt.html#SP29_5">§29.5</a>, <a href="6-rlt.html#SP29_6">§29.6</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12"></a><b>§12. </b>For example, <code class="display"><span class="extract">ct_0</span></code> and <code class="display"><span class="extract">ct_1</span></code> contain the current table and row selection,
|
|
in phrases for which that's relevant.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::add_table_lookup</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="functiontext">LocalVariables::add_internal_local_c</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"ct_0"</span><span class="plain">, </span><span class="string">"currently selected table"</span><span class="plain">);</span>
|
|
<span class="functiontext">LocalVariables::add_internal_local_c</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"ct_1"</span><span class="plain">, </span><span class="string">"currently selected row"</span><span class="plain">);</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">LOCAL_VARIABLES</span><span class="plain">, </span><span class="string">"Stack frame acquires CT locals\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::add_table_lookup is used in 11/sm (<a href="11-sm.html#SP4">§4</a>), 14/lv (<a href="14-lv.html#SP14_5">§14.5</a>), 19/lr (<a href="19-lr.html#SP7">§7</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP13"></a><b>§13. </b>Similarly <code class="display"><span class="extract">sw_v</span></code> holds a temporary switch value, in some cases.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::add_switch_value</span><span class="plain">(</span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">LOCAL_VARIABLES</span><span class="plain">, </span><span class="string">"Stack frame acquires switch value\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::add_internal_local_c</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"sw_v"</span><span class="plain">, </span><span class="string">"switch value"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::add_switch_value is used in 25/cp (<a href="25-cp.html#SP5_3_5">§5.3.5</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14"></a><b>§14. </b>Finally, when phrase options are used in invoking a phrase, a bitmap is
|
|
passed to its I6 routine, and this occupies a pseudo-call-parameter:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::options_parameter_is_needed</span><span class="plain">(</span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">) {</span>
|
|
<span class="functiontext">LocalVariables::add_internal</span><span class="plain">(&(</span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables</span><span class="plain">),</span>
|
|
<span class="identifier">I</span><span class="string">"phrase_options"</span><span class="plain">, </span><span class="constant">OTHER_CALL_PARAMETER_LV</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::options_parameter_is_needed is used in 22/ph (<a href="22-ph.html#SP6_5">§6.5</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15"></a><b>§15. Deallocating. </b>The following is used when a "let" variable falls out of scope: for instance,
|
|
a loop counter disappearing when its loop body is finished.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::deallocate</span><span class="plain">(</span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> != </span><span class="constant">LET_VALUE_LV</span><span class="plain">)</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"only let variables can be deallocated"</span><span class="plain">);</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>allocated</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>varname</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>name_hash</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>block_scope</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>free_at_end_of_scope</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::deallocate is used in <a href="#SP16">§16</a>, <a href="#SP41">§41</a>, 25/cii (<a href="25-cii.html#SP1_5">§1.5</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP16"></a><b>§16. </b>More extremely:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::deallocate_all</span><span class="plain">(</span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> == </span><span class="constant">LET_VALUE_LV</span><span class="plain">) && (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>allocated</span><span class="plain">))</span>
|
|
<span class="functiontext">LocalVariables::deallocate</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::deallocate_all is used in 25/cp (<a href="25-cp.html#SP3_2">§3.2</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP17"></a><b>§17. Extent. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">LocalVariables::count</span><span class="plain">(</span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">ct</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="identifier">ct</span><span class="plain">++;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ct</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::count is used in 17/ts (<a href="17-ts.html#SP5">§5</a>), 26/rt (<a href="26-rt.html#SP4">§4</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP18"></a><b>§18. Copying. </b>It turns out to be useful to be able to copy one slate's variables to
|
|
another, in order to remember the current variable names to make sense
|
|
of a text substitution later.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">We have to deep-copy the variables, not simply copy the head of the linked
|
|
list, because they may include variables which will be deallocated and then
|
|
given fresh names in between now and then.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::copy</span><span class="plain">(</span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf_to</span><span class="plain">, </span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf_from</span><span class="plain">) {</span>
|
|
<span class="reserved">locals_slate</span><span class="plain"> *</span><span class="identifier">slate_from</span><span class="plain"> = &(</span><span class="identifier">phsf_from</span><span class="plain">-</span><span class="element">>local_value_variables</span><span class="plain">);</span>
|
|
<span class="reserved">locals_slate</span><span class="plain"> *</span><span class="identifier">slate_to</span><span class="plain"> = &(</span><span class="identifier">phsf_to</span><span class="plain">-</span><span class="element">>local_value_variables</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">slate_from</span><span class="plain">-</span><span class="element">>local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">copied</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_to_locals_slate</span><span class="plain">(</span><span class="identifier">slate_to</span><span class="plain">,</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>varname</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>kind_as_declared</span><span class="plain">,</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_lvalue</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>index_with_this_purpose</span><span class="plain">);</span>
|
|
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">copied</span><span class="plain">-</span><span class="element">>lv_lvalue</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_lvalue</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">slate_to</span><span class="plain">-</span><span class="element">>it_variable_exists</span><span class="plain"> = </span><span class="identifier">slate_from</span><span class="plain">-</span><span class="element">>it_variable_exists</span><span class="plain">;</span>
|
|
<span class="identifier">slate_to</span><span class="plain">-</span><span class="element">>its_form_allowed</span><span class="plain"> = </span><span class="identifier">slate_from</span><span class="plain">-</span><span class="element">>its_form_allowed</span><span class="plain">;</span>
|
|
<span class="identifier">slate_to</span><span class="plain">-</span><span class="element">>it_pseudonym</span><span class="plain"> = </span><span class="identifier">slate_from</span><span class="plain">-</span><span class="element">>it_pseudonym</span><span class="plain">;</span>
|
|
|
|
<span class="identifier">phsf_to</span><span class="plain">-</span><span class="element">>local_stvol</span><span class="plain"> = </span><span class="identifier">phsf_from</span><span class="plain">-</span><span class="element">>local_stvol</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::copy is used in 17/ts (<a href="17-ts.html#SP5">§5</a>, <a href="17-ts.html#SP11">§11</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP19"></a><b>§19. Searching. </b>One way is to search the slate for a scratch variable by its I6 name:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::find_i6_var</span><span class="plain">(</span><span class="reserved">locals_slate</span><span class="plain"> *</span><span class="identifier">slate</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">purpose</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">slate</span><span class="plain">-</span><span class="element">>local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> == </span><span class="identifier">purpose</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_lvalue</span><span class="plain">, </span><span class="identifier">name</span><span class="plain">)))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::find_any</span><span class="plain">(</span><span class="reserved">locals_slate</span><span class="plain"> *</span><span class="identifier">slate</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">slate</span><span class="plain">-</span><span class="element">>local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_lvalue</span><span class="plain">, </span><span class="identifier">name</span><span class="plain">))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::find_i6_var is used in <a href="#SP11">§11</a>, <a href="#SP20">§20</a>, <a href="#SP22">§22</a>.</p>
|
|
|
|
<p class="endnote">The function LocalVariables::find_any is used in <a href="#SP20">§20</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20"></a><b>§20. </b>Thus:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::by_name</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">) {</span>
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::find_i6_var</span><span class="plain">(&(</span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables</span><span class="plain">), </span><span class="identifier">name</span><span class="plain">, </span><span class="constant">INTERNAL_USE_LV</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::by_name_any</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">) {</span>
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::find_any</span><span class="plain">(&(</span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables</span><span class="plain">), </span><span class="identifier">name</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::phrase_options</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::find_i6_var</span><span class="plain">(&(</span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables</span><span class="plain">), </span><span class="identifier">I</span><span class="string">"phrase_options"</span><span class="plain">, </span><span class="constant">OTHER_CALL_PARAMETER_LV</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::by_name is used in 14/lv (<a href="14-lv.html#SP14_5">§14.5</a>), 25/cii (<a href="25-cii.html#SP6">§6</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::by_name_any appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function LocalVariables::phrase_options is used in 14/cn (<a href="14-cn.html#SP16_3">§16.3</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP21"></a><b>§21. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::find_pcalc_var</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">v</span><span class="plain">) {</span>
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">locals_slate</span><span class="plain"> *</span><span class="identifier">slate</span><span class="plain"> = &(</span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables</span><span class="plain">);</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">slate</span><span class="plain">-</span><span class="element">>local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_lvalue</span><span class="plain">) == 1)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_lvalue</span><span class="plain">, 0) == </span><span class="identifier">pcalc_vars</span><span class="plain">[</span><span class="identifier">v</span><span class="plain">])</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::find_const_var</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">v</span><span class="plain">) {</span>
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="string">"const_%d"</span><span class="plain">, </span><span class="identifier">v</span><span class="plain">);</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">, *</span><span class="identifier">found</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">locals_slate</span><span class="plain"> *</span><span class="identifier">slate</span><span class="plain"> = &(</span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables</span><span class="plain">);</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">slate</span><span class="plain">-</span><span class="element">>local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_lvalue</span><span class="plain">, </span><span class="identifier">T</span><span class="plain">))</span>
|
|
<span class="identifier">found</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">found</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::find_pcalc_var is used in 11/tr (<a href="11-tr.html#SP10">§10</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::find_const_var is used in 12/cad (<a href="12-cad.html#SP7">§7</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP22"></a><b>§22. </b>And, a little cheekily,
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">LocalVariables::are_we_using_table_lookup</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">LocalVariables::find_i6_var</span><span class="plain">(&(</span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables</span><span class="plain">), </span><span class="identifier">I</span><span class="string">"ct_0"</span><span class="plain">, </span><span class="constant">INTERNAL_USE_LV</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::are_we_using_table_lookup is used in 10/teav (<a href="10-teav.html#SP21_1">§21.1</a>), 12/cdp (<a href="12-cdp.html#SP2_1_3">§2.1.3</a>), 24/ch (<a href="24-ch.html#SP6">§6</a>, <a href="24-ch.html#SP7_4">§7.4</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP23"></a><b>§23. </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 <code class="display"><span class="extract">NULL</span></code> if
|
|
there isn't one.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::get_ith_parameter</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">) {</span>
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no stack frame exists"</span><span class="plain">);</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> == </span><span class="constant">TOKEN_CALL_PARAMETER_LV</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain">++ == </span><span class="identifier">i</span><span class="plain">)</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::get_ith_parameter is used in <a href="#SP26">§26</a>, 22/ptd (<a href="22-ptd.html#SP20">§20</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24"></a><b>§24. </b>The main way to search the slate, though, is by source-text name: in other
|
|
words, by parsing.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Because local variables come and go on the breeze, we parse them by hand
|
|
rather than with the excerpt parser's symbols table. (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.) 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>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::parse</span><span class="plain">(</span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="functiontext">LocalVariables::parse_inner</span><span class="plain">(</span><span class="identifier">phsf</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain">) </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>parsed_recently</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::parse_inner</span><span class="plain">(</span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.it_variable_exists</span><span class="plain">) && (<</span><span class="identifier">pronoun</span><span class="plain">>(</span><span class="identifier">W</span><span class="plain">)))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::it_variable</span><span class="plain">();</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (<</span><span class="identifier">definite</span><span class="plain">-</span><span class="identifier">article</span><span class="plain">>(</span><span class="identifier">W</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">W</span><span class="plain"> = </span><span class="identifier">Articles::remove_the</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.it_pseudonym</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Wordings::match</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.it_pseudonym</span><span class="plain">)))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::it_variable</span><span class="plain">();</span>
|
|
|
|
<<span class="cwebmacro">Parse the locals directly</span> <span class="cwebmacronumber">24.1</span>><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::parse is used in <a href="#SP33">§33</a>, 10/teav (<a href="10-teav.html#SP15">§15</a>), 20/eq (<a href="20-eq.html#SP47_3">§47.3</a>), 25/cii (<a href="25-cii.html#SP5_1">§5.1</a>, <a href="25-cii.html#SP6">§6</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::parse_inner appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24_1"></a><b>§24.1. </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 — 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="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Parse the locals directly</span> <span class="cwebmacronumber">24.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">h</span><span class="plain"> = </span><span class="identifier">ExcerptMeanings::hash_code</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>varname</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="identifier">h</span><span class="plain"> == </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>name_hash</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>allocated</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Wordings::match</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>varname</span><span class="plain">)))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP24">§24</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP25"></a><b>§25. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">stack_selection_used_recently</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::monitor_local_parsing</span><span class="plain">(</span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>parsed_recently</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">stack_selection_used_recently</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::used_stack_selection</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="identifier">stack_selection_used_recently</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">LocalVariables::local_parsed_recently</span><span class="plain">(</span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>parsed_recently</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">stack_selection_used_recently</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::monitor_local_parsing is used in 17/ts (<a href="17-ts.html#SP11">§11</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::used_stack_selection is used in 14/lv (<a href="14-lv.html#SP14_5">§14.5</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::local_parsed_recently is used in 17/ts (<a href="17-ts.html#SP11">§11</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP26"></a><b>§26. It. </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. (The variable's name
|
|
is sometimes needed when the stack frame doesn't exist yet, so we occasionally
|
|
fake up a call parameter pro tem.)
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::it_variable</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::get_ith_parameter</span><span class="plain">(0);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::add_to_locals_slate</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">, </span><span class="constant">TOKEN_CALL_PARAMETER_LV</span><span class="plain">,</span>
|
|
<span class="identifier">EMPTY_WORDING</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, 0);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::it_variable is used in <a href="#SP24">§24</a>, 4/am (<a href="4-am.html#SP34_2">§34.2</a>, <a href="4-am.html#SP39_1">§39.1</a>), 10/teav (<a href="10-teav.html#SP10_1">§10.1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP27"></a><b>§27. </b>Sometimes "its", "his", "her" or "their" is allowed too:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">LocalVariables::is_possessive_form_of_it_enabled</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.its_form_allowed</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::enable_possessive_form_of_it</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no stack frame exists"</span><span class="plain">);</span>
|
|
<span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.its_form_allowed</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::add_pronoun</span><span class="plain">(</span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
|
|
<span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.it_variable_exists</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::add_call_parameter</span><span class="plain">(</span><span class="identifier">phsf</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="functiontext">LocalVariables::add_pronoun_as_symbol</span><span class="plain">(</span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
|
|
<span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.it_variable_exists</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">v</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_call_parameter</span><span class="plain">(</span><span class="identifier">phsf</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">v</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::alias_pronoun</span><span class="plain">(</span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
|
|
<span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.it_pseudonym</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::is_possessive_form_of_it_enabled is used in 10/teav (<a href="10-teav.html#SP8">§8</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::enable_possessive_form_of_it is used in 4/am (<a href="4-am.html#SP34_2_1">§34.2.1</a>), 6/rlt (<a href="6-rlt.html#SP30">§30</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::add_pronoun is used in 4/am (<a href="4-am.html#SP34_2_1">§34.2.1</a>), 22/ph (<a href="22-ph.html#SP6_7_1">§6.7.1</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::add_pronoun_as_symbol appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function LocalVariables::alias_pronoun is used in 23/abc (<a href="23-abc.html#SP1">§1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP28"></a><b>§28. Local Parking. </b>This is a tricksy little manoeuvre. Suppose we're about to call a function
|
|
in our compiled code, and it's a function with no arguments, but we want
|
|
our current locals to be still visible from inside it. What we do is to
|
|
park the values of the locals into a little scratch array before the call...
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::compile_storage</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">=0;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"(LocalParking-->%d=%~L),"</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">++, </span><span class="identifier">lvar</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">LocalVariables::emit_storage</span><span class="plain">(</span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">NC</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">inter_t</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">) {</span>
|
|
<span class="identifier">NC</span><span class="plain">++;</span>
|
|
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SEQUENTIAL_BIP</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">LOOKUPREF_BIP</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">LOCALPARKING_HL</span><span class="plain">));</span>
|
|
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">++);</span>
|
|
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">lvar_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
|
|
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">lvar_s</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NC</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::compile_storage appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function LocalVariables::emit_storage is used in 17/ts (<a href="17-ts.html#SP8">§8</a>), 17/rs (<a href="17-rs.html#SP12_1_1">§12.1.1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP29"></a><b>§29. </b>...and then fish them out again as the first thing happening inside the
|
|
function, i.e., immediately after the call.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::compile_retrieval</span><span class="plain">(</span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">) {</span>
|
|
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">LP</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">LOCALPARKING_HL</span><span class="plain">);</span>
|
|
<span class="identifier">inter_t</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">=0;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">) {</span>
|
|
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="identifier">Produce::ref_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 1));</span>
|
|
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">LOOKUP_BIP</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">LP</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">++);</span>
|
|
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::compile_retrieval is used in 17/ts (<a href="17-ts.html#SP11">§11</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP30"></a><b>§30. Equation terms. </b>Another use for local variables is as the terms in an equation.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::make_available_to_equation</span><span class="plain">(</span><span class="reserved">equation</span><span class="plain"> *</span><span class="identifier">eqn</span><span class="plain">) {</span>
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>allocated</span><span class="plain">)</span>
|
|
<span class="functiontext">Equations::declare_local</span><span class="plain">(</span><span class="identifier">eqn</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>varname</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>kind_as_declared</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::make_available_to_equation is used in 20/eq (<a href="20-eq.html#SP20">§20</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP31"></a><b>§31. Callings. </b>A "calling" is a declaration of the "(called X)" sort. The word range here is
|
|
the text "X":
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::ensure_called_local</span><span class="plain">(</span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">in case callings are made from parsing alone</span>
|
|
<span class="plain"><</span><span class="identifier">new</span><span class="plain">-</span><span class="identifier">called</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">>(</span><span class="identifier">W</span><span class="plain">);</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = <<</span><span class="identifier">rp</span><span class="plain">>>;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">lvar</span><span class="plain">) && (</span><span class="identifier">K</span><span class="plain">)) </span><span class="functiontext">LocalVariables::set_kind</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::ensure_called_local is used in <a href="#SP32">§32</a>, 10/cad (<a href="10-cad.html#SP19_2">§19.2</a>), 12/ca (<a href="12-ca.html#SP6_1">§6.1</a>), 12/dtd (<a href="12-dtd.html#SP9_2">§9.2</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP32"></a><b>§32. </b>The following rather inelegantly picks up any apparent callings in some text.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">last_mnc_wording</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING_INIT</span><span class="plain">;</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">PM_CalledWithDash_wording</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING_INIT</span><span class="plain">;</span>
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::make_necessary_callings</span><span class="plain">(</span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::within</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">last_mnc_wording</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="identifier">last_mnc_wording</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">;</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (<</span><span class="identifier">text</span><span class="plain">-</span><span class="identifier">including</span><span class="plain">-</span><span class="identifier">a</span><span class="plain">-</span><span class="identifier">calling</span><span class="plain">>(</span><span class="identifier">W</span><span class="plain">)) {</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">V</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(<</span><span class="identifier">text</span><span class="plain">-</span><span class="identifier">including</span><span class="plain">-</span><span class="identifier">a</span><span class="plain">-</span><span class="identifier">calling</span><span class="plain">>, 2);</span>
|
|
<span class="identifier">W</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(<</span><span class="identifier">text</span><span class="plain">-</span><span class="identifier">including</span><span class="plain">-</span><span class="identifier">a</span><span class="plain">-</span><span class="identifier">calling</span><span class="plain">>, 3);</span>
|
|
<span class="functiontext">LocalVariables::ensure_called_local</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::make_necessary_callings is used in 10/aots (<a href="10-aots.html#SP4">§4</a>, <a href="10-aots.html#SP5">§5</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP33"></a><b>§33. </b>When a calling is found in, for instance, a description like this:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>a body which is part of a person (called the owner)</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">the text after "called" is run through the following.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Note that production (b) of <new-called-name-unarticled> checks
|
|
to see if the name already has a meaning. However, a match against (b) is
|
|
disregarded if the meaning is one of those allowed to be overridden: at
|
|
present, a global variable, an object name, a table column name, a property
|
|
name or a description.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"><</span><span class="identifier">new</span><span class="plain">-</span><span class="identifier">called</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">> ::=</span>
|
|
<span class="plain"><</span><span class="identifier">definite</span><span class="plain">-</span><span class="identifier">article</span><span class="plain">> <</span><span class="identifier">new</span><span class="plain">-</span><span class="identifier">called</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">-</span><span class="identifier">unarticled</span><span class="plain">> | ==> *</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">R</span><span class="plain">[2]; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[2]</span>
|
|
<span class="plain"><</span><span class="identifier">new</span><span class="plain">-</span><span class="identifier">called</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">-</span><span class="identifier">unarticled</span><span class="plain">> ==> *</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">R</span><span class="plain">[1]; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[1]</span>
|
|
|
|
<span class="plain"><</span><span class="identifier">new</span><span class="plain">-</span><span class="identifier">called</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">-</span><span class="identifier">unarticled</span><span class="plain">> ::=</span>
|
|
<span class="plain">*** - *** | ==> </span><<span class="cwebmacro">Issue PM_CalledWithDash problem</span> <span class="cwebmacronumber">33.1</span>>
|
|
<span class="plain"><</span><span class="identifier">existing</span><span class="plain">-</span><span class="identifier">local</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">> | ==> *</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">R</span><span class="plain">[1]; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[1]</span>
|
|
<span class="plain"><</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">type</span><span class="plain">-</span><span class="identifier">expression</span><span class="plain">-</span><span class="identifier">or</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">> | ==> </span><<span class="cwebmacro">Vet to see if this name can be overloaded</span> <span class="cwebmacronumber">33.2</span>>
|
|
<span class="plain">... ==> </span><<span class="cwebmacro">Make a new local for this calling</span> <span class="cwebmacronumber">33.3</span>>
|
|
|
|
<span class="plain"><</span><span class="identifier">existing</span><span class="plain">-</span><span class="identifier">local</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">> </span><span class="identifier">internal</span><span class="plain"> {</span>
|
|
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="functiontext">LocalVariables::parse</span><span class="plain">(</span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">(), </span><span class="identifier">W</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (*</span><span class="identifier">XP</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP33_1"></a><b>§33.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Issue PM_CalledWithDash problem</span> <span class="cwebmacronumber">33.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = 0; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (!(</span><span class="identifier">Wordings::eq</span><span class="plain">(</span><span class="identifier">PM_CalledWithDash_wording</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">))) {</span>
|
|
<span class="identifier">PM_CalledWithDash_wording</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">;</span>
|
|
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CalledWithDash</span><span class="plain">),</span>
|
|
<span class="string">"a '(called ...)' name is not allowed to include a hyphen"</span><span class="plain">,</span>
|
|
<span class="string">"since this would look misleadingly like a declaration of kind of value it has."</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP33">§33</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP33_2"></a><b>§33.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Vet to see if this name can be overloaded</span> <span class="cwebmacronumber">33.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">already</span><span class="plain"> = <<</span><span class="identifier">rp</span><span class="plain">>>;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">LocalVariables::permit_as_new_local</span><span class="plain">(</span><span class="identifier">already</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Meaning already existing: $T\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">already</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">W</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Specifications::is_kind_like</span><span class="plain">(</span><span class="identifier">already</span><span class="plain">))</span>
|
|
<span class="identifier">Problems::quote_text</span><span class="plain">(3, </span><span class="string">"a kind"</span><span class="plain">);</span>
|
|
<span class="reserved">else</span>
|
|
<span class="functiontext">Problems::quote_kind_of</span><span class="plain">(3, </span><span class="identifier">already</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_CalledOverloaded</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"In %1, it looks as if '%2' is going to be a temporary name which something "</span>
|
|
<span class="string">"will be called. But I can't allow that, because it already has a meaning "</span>
|
|
<span class="string">"as %3."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = 0; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP33">§33</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP33_3"></a><b>§33.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Make a new local for this calling</span> <span class="cwebmacronumber">33.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = 0;</span>
|
|
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = (</span><span class="identifier">phsf</span><span class="plain">)?(</span><span class="functiontext">LocalVariables::new</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)):</span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP33">§33</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP34"></a><b>§34. 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="inwebparagraph">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="inwebparagraph">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="inwebparagraph">Callings get one extra benefit, because they typically exist more fleetingly —
|
|
often only for the sentence where they're defined — and because the syntax
|
|
is more explicit. So you can write:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>if an infected person can see a clean person (called random bystander), ...</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">even if "random bystander" might otherwise be a request to randomly generate
|
|
an instance of the kind "bystander".
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">LocalVariables::permit_as_new_local</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">found</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">as_calling</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">found</span><span class="plain">, </span><span class="identifier">AMBIGUITY_NT</span><span class="plain">)) </span><span class="identifier">found</span><span class="plain"> = </span><span class="identifier">found</span><span class="plain">-</span><span class="element">>down</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Specifications::is_kind_like</span><span class="plain">(</span><span class="identifier">found</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">found</span><span class="plain">), </span><span class="identifier">K_object</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">found</span><span class="plain">, </span><span class="constant">UNKNOWN_NT</span><span class="plain">)) ||</span>
|
|
<span class="plain">(</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">found</span><span class="plain">, </span><span class="constant">NONLOCAL_VARIABLE_NT</span><span class="plain">)) ||</span>
|
|
<span class="plain">(</span><span class="functiontext">Specifications::is_description</span><span class="plain">(</span><span class="identifier">found</span><span class="plain">)) ||</span>
|
|
<span class="plain">(</span><span class="functiontext">Rvalues::is_object</span><span class="plain">(</span><span class="identifier">found</span><span class="plain">)) ||</span>
|
|
<span class="plain">(</span><span class="functiontext">Rvalues::to_instance</span><span class="plain">(</span><span class="identifier">found</span><span class="plain">)) ||</span>
|
|
<span class="plain">(</span><span class="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">found</span><span class="plain">, </span><span class="identifier">CON_table_column</span><span class="plain">)) ||</span>
|
|
<span class="plain">(</span><span class="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">found</span><span class="plain">, </span><span class="identifier">CON_property</span><span class="plain">))) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">as_calling</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTreeUsage::is_phrasal</span><span class="plain">(</span><span class="identifier">found</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::permit_as_new_local is used in <a href="#SP33_2">§33.2</a>, 14/ds2 (<a href="14-ds2.html#SP11_8">§11.8</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP35"></a><b>§35. Logging. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::log</span><span class="plain">(</span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>allocated</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) { </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"LV<unallocated>"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>varname</span><span class="plain">)) </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"LV\</span><span class="plain">"</span><span class="string">%W\</span><span class="plain">"</span><span class="string">"</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>varname</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"LV<nameless>"</span><span class="plain">);</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"-$u"</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>kind_as_declared</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::log is used in 1/cm (<a href="1-cm.html#SP5">§5</a>, <a href="1-cm.html#SP6_6">§6.6</a>), 24/sf (<a href="24-sf.html#SP13">§13</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP36"></a><b>§36. </b>And for run-time debugging in a similar vein:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::describe_repetition_local</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">lvar</span><span class="plain">) && (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> == </span><span class="constant">LET_VALUE_LV</span><span class="plain">)) </span> <span class="comment">should always be true</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"[repetition with %+W set to \</span><span class="plain">"</span><span class="string">, (%n) %~L, \</span><span class="plain">"</span><span class="string">]^\</span><span class="plain">"</span><span class="string">;\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>varname</span><span class="plain">,</span>
|
|
<span class="identifier">Kinds::Behaviour::get_iname</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>kind_as_declared</span><span class="plain">),</span>
|
|
<span class="identifier">lvar</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::describe_repetition_local appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP37"></a><b>§37. Kind. </b>Of a single variable:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">LocalVariables::kind</span><span class="plain">(</span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Tried to find kind of nonexistent local variable"</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>kind_as_declared</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">LocalVariables::unproblematic_kind</span><span class="plain">(</span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::kind</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::kind is used in <a href="#SP43">§43</a>, 14/ds2 (<a href="14-ds2.html#SP19_6_1_1">§19.6.1.1</a>), 20/eq (<a href="20-eq.html#SP47_3_2">§47.3.2</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::unproblematic_kind is used in 14/lv (<a href="14-lv.html#SP11">§11</a>, <a href="14-lv.html#SP12_1">§12.1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP38"></a><b>§38. </b>Locals are sometimes created before their kinds are known, so this call
|
|
exists to fix that:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::set_kind</span><span class="plain">(</span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Tried to set kind of nonexistent local variable"</span><span class="plain">);</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">LOCAL_VARIABLES</span><span class="plain">, </span><span class="string">"Kind of local $k set to $u\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>kind_as_declared</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::set_kind is used in <a href="#SP31">§31</a>, <a href="#SP47">§47</a>, 12/dtd (<a href="12-dtd.html#SP27">§27</a>), 20/eq (<a href="20-eq.html#SP47_3_2">§47.3.2</a>), 22/ptd (<a href="22-ptd.html#SP20">§20</a>), 25/cii (<a href="25-cii.html#SP3_5_1_1_1">§3.5.1.1.1</a>), 25/cp (<a href="25-cp.html#SP5_3_5_3">§5.3.5.3</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP39"></a><b>§39. Protection. </b>From being changed by "let", that is. Loop counters are protected, but that's
|
|
about it; call parameters aren't, for instance, though it would be a simple
|
|
change to make them so. (In the Examples suite as of March 2012, there are
|
|
only two points where call parameters are altered. Still, it didn't seem
|
|
worth making the change, even though the disruption would be small.)
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::unprotect</span><span class="plain">(</span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> == </span><span class="constant">LET_VALUE_LV</span><span class="plain">)</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>protected</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">LocalVariables::protected</span><span class="plain">(</span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> == </span><span class="constant">LET_VALUE_LV</span><span class="plain">) && (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>protected</span><span class="plain">)) {</span>
|
|
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>varname</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_ProtectedFromLet</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"In %1, it looks as if you want to use 'let' to change the value of "</span>
|
|
<span class="string">"the temporary variable '%2'. Ordinarily that would be fine, but it's "</span>
|
|
<span class="string">"not allowed when the variable is used as the counter in a 'repeat' "</span>
|
|
<span class="string">"loop, or has some other do-not-disturb purpose - this could cause "</span>
|
|
<span class="string">"chaotic effects. The rule is: you can only change an existing value "</span>
|
|
<span class="string">"with 'let' if it was created by 'let' in the first place."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::unprotect is used in 25/cii (<a href="25-cii.html#SP3_5_2">§3.5.2</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::protected is used in 14/ds2 (<a href="14-ds2.html#SP11_9_1_1_5">§11.9.1.1.5</a>), 25/cii (<a href="25-cii.html#SP3_5_4_2">§3.5.4.2</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP40"></a><b>§40. Block scope. </b>At every position in a phrase definition we have a "scope level" number S.
|
|
This begins at 0; when a block begins, usually as a loop body, it increments,
|
|
and when the block ends it decrements.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::set_scope_to</span><span class="plain">(</span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">s</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">s</span><span class="plain"> > 0) && (</span><span class="identifier">lvar</span><span class="plain">) && (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> == </span><span class="constant">LET_VALUE_LV</span><span class="plain">)) {</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>block_scope</span><span class="plain"> = </span><span class="identifier">s</span><span class="plain">;</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">LOCAL_VARIABLES</span><span class="plain">, </span><span class="string">"Setting scope of $k to block level %d\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">s</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::set_scope_to is used in 24/pb (<a href="24-pb.html#SP18">§18</a>, <a href="24-pb.html#SP19">§19</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP41"></a><b>§41. </b>And here is the reckoning when scope level S ends:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::mark_to_free_at_end_of_scope</span><span class="plain">(</span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">) {</span>
|
|
<span class="identifier">lvar</span><span class="plain">-</span><span class="element">>free_at_end_of_scope</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::end_scope</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">s</span><span class="plain">) {</span>
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"relinquishing locals where no stack frame exists"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">s</span><span class="plain"> <= 0) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"the outermost scope cannot end"</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> == </span><span class="constant">LET_VALUE_LV</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>allocated</span><span class="plain">) && (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>block_scope</span><span class="plain"> >= </span><span class="identifier">s</span><span class="plain">)) {</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">LOCAL_VARIABLES</span><span class="plain">, </span><span class="string">"De-allocating $k at end of block\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>free_at_end_of_scope</span><span class="plain">) {</span>
|
|
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">BLKVALUEFREE_HL</span><span class="plain">);</span>
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">LN</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 2);</span>
|
|
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">iname</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">LN</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="plain">}</span>
|
|
<span class="functiontext">LocalVariables::deallocate</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="functiontext">ExParser::warn_expression_cache</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::mark_to_free_at_end_of_scope is used in 12/dtd (<a href="12-dtd.html#SP27">§27</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::end_scope is used in 24/pb (<a href="24-pb.html#SP13">§13</a>, <a href="24-pb.html#SP14">§14</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP42"></a><b>§42. </b>This rather fatuous routine is used only for describing repetitions in
|
|
testing output (see above): in other circumstances it wouldn't give the
|
|
right result, so don't use it for anything else.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="functiontext">LocalVariables::latest_repeat_variable</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">s</span><span class="plain"> = </span><span class="functiontext">Frames::Blocks::current_block_level</span><span class="plain">();</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> == </span><span class="constant">LET_VALUE_LV</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>allocated</span><span class="plain">) && (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>block_scope</span><span class="plain"> == </span><span class="identifier">s</span><span class="plain">))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::latest_repeat_variable appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP43"></a><b>§43. Callings. </b>We need to keep track of the callings made in any condition so that the
|
|
variables, which generally have a scope extending beyond that condition,
|
|
can't be left with kind-unsafe (or no) values. For example, if:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>if a device (called the mechanism) is switched on: ...</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">turns out false, then "mechanism" has to be safely defused to some kind-safe
|
|
value.
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">MAX_CALLINGS_IN_MATCH</span><span class="plain"> 128</span>
|
|
</pre>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">current_session_number</span><span class="plain"> = -1;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">callings_in_condition_sp</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">callings_session_number</span><span class="plain">[</span><span class="constant">MAX_CALLINGS_IN_MATCH</span><span class="plain">];</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">callings_in_condition</span><span class="plain">[</span><span class="constant">MAX_CALLINGS_IN_MATCH</span><span class="plain">];</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::add_calling_to_condition</span><span class="plain">(</span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_session_number</span><span class="plain"> < 0) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no PM session"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">callings_in_condition_sp</span><span class="plain"> + 1 == </span><span class="constant">MAX_CALLINGS_IN_MATCH</span><span class="plain">)</span>
|
|
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">BelievedImpossible</span><span class="plain">), </span> <span class="comment">or very hard, anyway</span>
|
|
<span class="string">"that makes too complicated a condition to test"</span><span class="plain">,</span>
|
|
<span class="string">"with all of those clauses involving 'called' values."</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">callings_session_number</span><span class="plain">[</span><span class="identifier">callings_in_condition_sp</span><span class="plain">] = </span><span class="identifier">current_session_number</span><span class="plain">;</span>
|
|
<span class="identifier">callings_in_condition</span><span class="plain">[</span><span class="identifier">callings_in_condition_sp</span><span class="plain">++] = </span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::begin_condition_emit</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="identifier">current_session_number</span><span class="plain">++;</span>
|
|
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">OR_BIP</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::end_condition_emit</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_session_number</span><span class="plain"> < 0) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"unstarted PM session"</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">NC</span><span class="plain"> = 0, </span><span class="identifier">x</span><span class="plain"> = </span><span class="identifier">callings_in_condition_sp</span><span class="plain">, </span><span class="identifier">downs</span><span class="plain"> = 1;</span>
|
|
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">x</span><span class="plain"> > 0) &&</span>
|
|
<span class="plain">(</span><span class="identifier">callings_session_number</span><span class="plain">[</span><span class="identifier">x</span><span class="plain">-1] == </span><span class="identifier">current_session_number</span><span class="plain">)) {</span>
|
|
<span class="identifier">NC</span><span class="plain">++;</span>
|
|
<span class="identifier">x</span><span class="plain">--;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">NC</span><span class="plain"> == 0) {</span>
|
|
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SEQUENTIAL_BIP</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">()); </span><span class="identifier">downs</span><span class="plain">++;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">NM</span><span class="plain"> = 0, </span><span class="identifier">inner_downs</span><span class="plain"> = 0;;</span>
|
|
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">callings_in_condition_sp</span><span class="plain"> > 0) &&</span>
|
|
<span class="plain">(</span><span class="identifier">callings_session_number</span><span class="plain">[</span><span class="identifier">callings_in_condition_sp</span><span class="plain">-1] == </span><span class="identifier">current_session_number</span><span class="plain">)) {</span>
|
|
<span class="identifier">NM</span><span class="plain">++;</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">callings_in_condition</span><span class="plain">[</span><span class="identifier">callings_in_condition_sp</span><span class="plain">-1];</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">NM</span><span class="plain"> < </span><span class="identifier">NC</span><span class="plain">) { </span><span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SEQUENTIAL_BIP</span><span class="plain">); </span><span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">()); </span><span class="identifier">inner_downs</span><span class="plain">++; }</span>
|
|
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_BIP</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">lvar_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 8);</span>
|
|
<span class="identifier">Produce::ref_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">lvar_s</span><span class="plain">);</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">LocalVariables::kind</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) ||</span>
|
|
<span class="plain">(</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) ||</span>
|
|
<span class="plain">(</span><span class="identifier">Kinds::Behaviour::definite</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) ||</span>
|
|
<span class="plain">(</span><span class="functiontext">Kinds::RunTime::emit_default_value_as_val</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">EMPTY_WORDING</span><span class="plain">, </span><span class="string">"'called' value"</span><span class="plain">) != </span><span class="identifier">TRUE</span><span class="plain">))</span>
|
|
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
|
|
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="identifier">callings_in_condition_sp</span><span class="plain">--;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">inner_downs</span><span class="plain"> > 0) { </span><span class="identifier">inner_downs</span><span class="plain">--; </span><span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">()); }</span>
|
|
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">current_session_number</span><span class="plain">--;</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">downs</span><span class="plain"> > 0) { </span><span class="identifier">downs</span><span class="plain">--; </span><span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">()); }</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::add_calling_to_condition is used in 12/dtd (<a href="12-dtd.html#SP9">§9</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::begin_condition_emit is used in 12/dtd (<a href="12-dtd.html#SP7_1">§7.1</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::end_condition_emit is used in 12/dtd (<a href="12-dtd.html#SP7_1">§7.1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP44"></a><b>§44. Writer. </b>Lastly we get to run-time compilation. Writing <code class="display"><span class="extract">%~L</span></code> gives code for an I6
|
|
lvalue which can be used to evaluate or assign to the variable:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::writer</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">format_string</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">vL</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = (</span><span class="reserved">local_variable</span><span class="plain"> *) </span><span class="identifier">vL</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no such variable"</span><span class="plain">);</span>
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">format_string</span><span class="plain">[0]) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="character">'L'</span><span class="plain">: </span> <span class="comment">bare <code class="display"><span class="extract">%L</span></code> means the same as <code class="display"><span class="extract">%+L</span></code>, so fall through to...</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="character">'+'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>varname</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="character">'-'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%-W"</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>varname</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="character">'~'</span><span class="plain">: </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_lvalue</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">default</span><span class="plain">: </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"bad %L modifier"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::writer is used in 1/cm (<a href="1-cm.html#SP6_3">§6.3</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP45"></a><b>§45. </b>And here is a comma-separated list (possibly empty) of just the call
|
|
parameters:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::compile_parameter_list</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_vars</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">purpose</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">purpose</span><span class="plain"> = </span><span class="constant">TOKEN_CALL_PARAMETER_LV</span><span class="plain">; </span><span class="identifier">purpose</span><span class="plain"> <= </span><span class="constant">OTHER_CALL_PARAMETER_LV</span><span class="plain">; </span><span class="identifier">purpose</span><span class="plain">++) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> == </span><span class="identifier">purpose</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">no_vars</span><span class="plain">++ > 0) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">", "</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%~L"</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::emit_parameter_list</span><span class="plain">(</span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">) {</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">purpose</span><span class="plain"> = </span><span class="constant">TOKEN_CALL_PARAMETER_LV</span><span class="plain">; </span><span class="identifier">purpose</span><span class="plain"> <= </span><span class="constant">OTHER_CALL_PARAMETER_LV</span><span class="plain">; </span><span class="identifier">purpose</span><span class="plain">++) {</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> == </span><span class="identifier">purpose</span><span class="plain">) {</span>
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">vs</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, 3);</span>
|
|
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">vs</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::compile_parameter_list appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function LocalVariables::emit_parameter_list is used in 26/rt (<a href="26-rt.html#SP4_1_3">§4.1.3</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP46"></a><b>§46. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">LocalVariables::deduced_function_kind</span><span class="plain">(</span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">pc</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> == </span><span class="constant">TOKEN_CALL_PARAMETER_LV</span><span class="plain">) || (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> == </span><span class="constant">OTHER_CALL_PARAMETER_LV</span><span class="plain">))</span>
|
|
<span class="identifier">pc</span><span class="plain">++;</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K_array</span><span class="plain">[128];</span>
|
|
<span class="identifier">pc</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> == </span><span class="constant">TOKEN_CALL_PARAMETER_LV</span><span class="plain">) || (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> == </span><span class="constant">OTHER_CALL_PARAMETER_LV</span><span class="plain">))</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pc</span><span class="plain"> < 128) {</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">OK</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>kind_as_declared</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">OK</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">OK</span><span class="plain"> == </span><span class="identifier">K_nil</span><span class="plain">)) </span><span class="identifier">OK</span><span class="plain"> = </span><span class="identifier">K_number</span><span class="plain">;</span>
|
|
<span class="identifier">K_array</span><span class="plain">[</span><span class="identifier">pc</span><span class="plain">++] = </span><span class="identifier">OK</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Kinds::function_kind</span><span class="plain">(</span><span class="identifier">pc</span><span class="plain">, </span><span class="identifier">K_array</span><span class="plain">, </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>kind_returned</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::deduced_function_kind is used in 26/rt (<a href="26-rt.html#SP4">§4</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP47"></a><b>§47. </b>Finally, I6 local variable declarations for the temporary values we will
|
|
need in the compilation of any given routine:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::declare</span><span class="plain">(</span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">shell_mode</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">purpose</span><span class="plain">, </span><span class="identifier">from</span><span class="plain"> = </span><span class="constant">TOKEN_CALL_PARAMETER_LV</span><span class="plain">, </span><span class="identifier">to</span><span class="plain"> = </span><span class="constant">INTERNAL_USE_LV</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">shell_mode</span><span class="plain">) </span><span class="identifier">to</span><span class="plain"> = </span><span class="constant">OTHER_CALL_PARAMETER_LV</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">phsf</span><span class="plain">)</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">purpose</span><span class="plain"> = </span><span class="identifier">from</span><span class="plain">; </span><span class="identifier">purpose</span><span class="plain"> <= </span><span class="identifier">to</span><span class="plain">; </span><span class="identifier">purpose</span><span class="plain">++) {</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_value_variables.local_variable_allocation</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain">; </span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain"> == </span><span class="identifier">purpose</span><span class="plain">) {</span>
|
|
<span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">shell_mode</span><span class="plain">, 4);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">shell_mode</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">reason</span><span class="plain">) {</span>
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain"> = </span><span class="identifier">Produce::local_exists</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_lvalue</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">S</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">S</span><span class="plain">;</span>
|
|
|
|
<span class="identifier">inter_t</span><span class="plain"> </span><span class="identifier">annot</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">TOKEN_CALL_PARAMETER_LV</span><span class="plain">: </span><span class="identifier">annot</span><span class="plain"> = </span><span class="identifier">CALL_PARAMETER_IANN</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">OTHER_CALL_PARAMETER_LV</span><span class="plain">: </span><span class="identifier">annot</span><span class="plain"> = </span><span class="identifier">IMPLIED_CALL_PARAMETER_IANN</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">comment</span><span class="plain">);</span>
|
|
<span class="functiontext">LocalVariables::comment_on</span><span class="plain">(</span><span class="identifier">comment</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_purpose</span><span class="plain">);</span>
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">symb</span><span class="plain"> = </span><span class="functiontext">Emit::local</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>kind_as_declared</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>lv_lvalue</span><span class="plain">, </span><span class="identifier">annot</span><span class="plain">, </span><span class="identifier">comment</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">comment</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">symb</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="functiontext">LocalVariables::create_and_declare</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
|
|
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_named_call</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">);</span>
|
|
<span class="functiontext">LocalVariables::set_kind</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, 5);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::declare is used in 26/rt (<a href="26-rt.html#SP3">§3</a>, <a href="26-rt.html#SP4">§4</a>, <a href="26-rt.html#SP4_1_1">§4.1.1</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::declare_this is used in <a href="#SP8">§8</a>, <a href="#SP10">§10</a>, <a href="#SP11">§11</a>, <a href="#SP27">§27</a>, <a href="#SP28">§28</a>, <a href="#SP29">§29</a>, <a href="#SP41">§41</a>, <a href="#SP43">§43</a>, <a href="#SP45">§45</a>, 4/am (<a href="4-am.html#SP34_2">§34.2</a>), 11/tr (<a href="11-tr.html#SP10">§10</a>), 12/dtd (<a href="12-dtd.html#SP9">§9</a>, <a href="12-dtd.html#SP23">§23</a>, <a href="12-dtd.html#SP25">§25</a>, <a href="12-dtd.html#SP26">§26</a>, <a href="12-dtd.html#SP27">§27</a>), 12/cad (<a href="12-cad.html#SP7">§7</a>), 13/rsfk (<a href="13-rsfk.html#SP24_6_2">§24.6.2</a>, <a href="13-rsfk.html#SP24_6_3">§24.6.3</a>, <a href="13-rsfk.html#SP24_6_4">§24.6.4</a>), 14/lv (<a href="14-lv.html#SP14_1">§14.1</a>, <a href="14-lv.html#SP14_5">§14.5</a>), 14/cn (<a href="14-cn.html#SP16_3">§16.3</a>), 20/eq (<a href="20-eq.html#SP48">§48</a>), 25/cii (<a href="25-cii.html#SP1_2_1">§1.2.1</a>, <a href="25-cii.html#SP3_5_1">§3.5.1</a>, <a href="25-cii.html#SP3_5_3">§3.5.3</a>), 25/cp (<a href="25-cp.html#SP5_3_5">§5.3.5</a>).</p>
|
|
|
|
<p class="endnote">The function LocalVariables::create_and_declare is used in 13/rsfk (<a href="13-rsfk.html#SP24_4_1">§24.4.1</a>, <a href="13-rsfk.html#SP24_4_2">§24.4.2</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP48"></a><b>§48. </b>Note that a deallocated "let" variable retains its most recent name.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">LocalVariables::comment_on</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">purpose</span><span class="plain">) {</span>
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">purpose</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">TOKEN_CALL_PARAMETER_LV</span><span class="plain">:</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>varname</span><span class="plain">))</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"'%+W': "</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>varname</span><span class="plain">);</span>
|
|
<span class="identifier">Kinds::Textual::write</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>kind_as_declared</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">OTHER_CALL_PARAMETER_LV</span><span class="plain">:</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">LET_VALUE_LV</span><span class="plain">:</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>varname</span><span class="plain">))</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"e.g., '%+W'"</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>varname</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>allocated</span><span class="plain">) {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">": "</span><span class="plain">);</span>
|
|
<span class="identifier">Kinds::Textual::write</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>kind_as_declared</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" (deallocated by end of phrase)"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">INTERNAL_USE_LV</span><span class="plain">:</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>comment_on_use</span><span class="plain">)</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%s"</span><span class="plain">, </span><span class="identifier">lvar</span><span class="plain">-</span><span class="element">>comment_on_use</span><span class="plain">);</span>
|
|
<span class="reserved">else</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"internal use only"</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function LocalVariables::comment_on is used in <a href="#SP47">§47</a>.</p>
|
|
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><i>(This section begins Chapter 24: Compilation Context.)</i></li><li><a href="24-pb.html">Continue with 'Phrase Blocks'</a></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</body>
|
|
</html>
|
|
|