mirror of
https://github.com/ganelson/inform.git
synced 2024-07-08 18:14:21 +03:00
489 lines
55 KiB
HTML
489 lines
55 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>24/pb</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/sf' 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>Stack Frames</b></li></ul><p class="purpose">When Inform compiles phrase invocations, or implied forms of these such as text substitutions, it does so in the context of a "stack frame". This provides for local "let" values, manages loop blocks, and in general looks after any information shared between a whole sequence of invocations.</p>
|
|
|
|
<ul class="toc"><li><a href="#SP1">§1. Definitions</a></li><li><a href="#SP5">§5. Creation</a></li><li><a href="#SP8">§8. The current stack frame</a></li><li><a href="#SP9">§9. Kinds</a></li><li><a href="#SP11">§11. Stacked variables</a></li><li><a href="#SP12">§12. Past tense</a></li><li><a href="#SP13">§13. Logging</a></li><li><a href="#SP14">§14. Formal parameter allocation</a></li><li><a href="#SP15">§15. Pointer value allocation</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>As we've seen, each phrase has its own stack frame, which is a structure
|
|
inside the <code class="display"><span class="extract">phrase</span></code> structure. But they can also exist independently, for
|
|
other occasions when compilation occurs. They keep track of which variables
|
|
are visible, and also of the current values of the kind variables A to Z,
|
|
if any, and the consequent return kind.
|
|
</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">ph_stack_frame</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="identifier">local_value_variables</span><span class="plain">; </span> <span class="comment">those in scope here</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">stacked_variable_owner_list</span><span class="plain"> *</span><span class="identifier">local_stvol</span><span class="plain">; </span> <span class="comment">those in scope here</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">pointer_allocation</span><span class="plain"> *</span><span class="identifier">allocated_pointers</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_formal_parameters_needed</span><span class="plain">; </span> <span class="comment">usually 0, unless there are ambiguities</span>
|
|
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">kind_returned</span><span class="plain">; </span> <span class="comment">or <code class="display"><span class="extract">NULL</span></code> for no return value</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">kind</span><span class="plain"> **</span><span class="identifier">local_kind_variables</span><span class="plain">; </span> <span class="comment">points to an array indexed 1 to 26</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">determines_past_conditions</span><span class="plain">; </span> <span class="comment">or rather, in the present, but for future use</span>
|
|
<span class="plain">} </span><span class="reserved">ph_stack_frame</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure ph_stack_frame is accessed in 24/lv, 26/rt and here.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b>Stack frames are often made fleetingly and then thrown away, but sometimes
|
|
we need to make one and keep it around. For this, we have the ability to box
|
|
up a stack frame: by allocating an instance of the following structure, we
|
|
can have a permanently valid pointer to a unique new PHSF.
|
|
</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">ph_stack_frame_box</span><span class="plain"> {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">ph_stack_frame</span><span class="plain"> </span><span class="identifier">boxed_phsf</span><span class="plain">;</span>
|
|
<span class="identifier">MEMORY_MANAGEMENT</span>
|
|
<span class="plain">} </span><span class="reserved">ph_stack_frame_box</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure ph_stack_frame_box is private to this section.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. </b>Within each stack frame is a linked list of notes about pointer values
|
|
for which memory allocation and deallocation will be needed:
|
|
</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">pointer_allocation</span><span class="plain"> {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">heap_allocation</span><span class="plain"> </span><span class="identifier">allocation</span><span class="plain">; </span> <span class="comment">needed to compile a function call returning a pointer to a new value</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">local_reference_code</span><span class="plain">; </span> <span class="comment">an I6 lvalue for the storage holding the pointer</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">escaped_local_reference_code</span><span class="plain">; </span> <span class="comment">the same, but suitable for schema use</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">schema_for_promotion</span><span class="plain">; </span> <span class="comment">an I6 schema for promoting this value</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">offset_index</span><span class="plain">; </span> <span class="comment">start of small block wrt current stack frame</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">offset_past</span><span class="plain">; </span> <span class="comment">just past the end of the small block</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">pointer_allocation</span><span class="plain"> *</span><span class="identifier">next_in_frame</span><span class="plain">; </span> <span class="comment">within the linked list</span>
|
|
<span class="identifier">MEMORY_MANAGEMENT</span>
|
|
<span class="plain">} </span><span class="reserved">pointer_allocation</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure pointer_allocation is accessed in 26/rt and here.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§5. Creation. </b>A completely black stack frame...
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> </span><span class="functiontext">Frames::new</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="identifier">phsf</span><span class="element">.local_value_variables</span><span class="plain"> = </span><span class="functiontext">LocalVariables::blank_slate</span><span class="plain">();</span>
|
|
<span class="identifier">phsf</span><span class="element">.local_kind_variables</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">phsf</span><span class="element">.local_stvol</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">phsf</span><span class="element">.determines_past_conditions</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">phsf</span><span class="element">.allocated_pointers</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">phsf</span><span class="element">.kind_returned</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">phsf</span><span class="element">.no_formal_parameters_needed</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">phsf</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Frames::new is used in <a href="#SP6">§6</a>, 17/ts (<a href="17-ts.html#SP5">§5</a>), 22/ph (<a href="22-ph.html#SP6_5">§6.5</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§6. </b>...can be useful all by itself. The following is used to make a temporary
|
|
stack frame suitable for "nonphrasal" compilation, that is, for when Inform
|
|
wants to compile an I6 routine for some purpose other than to define a phrase.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">nonphrasal_stack_frame_is_current</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> </span><span class="identifier">nonphrasal_stack_frame</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="functiontext">Frames::new_nonphrasal</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">nonphrasal_stack_frame_is_current</span><span class="plain">)</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"can't nest nonphrasal stack frames"</span><span class="plain">);</span>
|
|
<span class="identifier">nonphrasal_stack_frame</span><span class="plain"> = </span><span class="functiontext">Frames::new</span><span class="plain">();</span>
|
|
<span class="identifier">nonphrasal_stack_frame_is_current</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="functiontext">Frames::make_current</span><span class="plain">(&</span><span class="identifier">nonphrasal_stack_frame</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> &</span><span class="identifier">nonphrasal_stack_frame</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Frames::remove_nonphrase_stack_frame</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="identifier">nonphrasal_stack_frame</span><span class="plain"> = </span><span class="functiontext">Frames::new</span><span class="plain">(); </span> <span class="comment">to prevent accidental lucky misuse</span>
|
|
<span class="identifier">nonphrasal_stack_frame_is_current</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="functiontext">Frames::remove_current</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Frames::new_nonphrasal is used in 26/rt (<a href="26-rt.html#SP3_1">§3.1</a>).</p>
|
|
|
|
<p class="endnote">The function Frames::remove_nonphrase_stack_frame is used in 22/pu (<a href="22-pu.html#SP20_1_1">§20.1.1</a>), 26/rt (<a href="26-rt.html#SP4">§4</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§7. </b>Another way to get hold of a PHSF is to request a boxed one, as noted above:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="functiontext">Frames::boxed_frame</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="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">ph_stack_frame_box</span><span class="plain"> *</span><span class="identifier">phsfb</span><span class="plain">;</span>
|
|
<span class="identifier">phsfb</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">ph_stack_frame_box</span><span class="plain">);</span>
|
|
<span class="identifier">phsfb</span><span class="plain">-</span><span class="element">>boxed_phsf</span><span class="plain"> = *</span><span class="identifier">phsf</span><span class="plain">;</span>
|
|
<span class="functiontext">LocalVariables::deep_copy_locals_slate</span><span class="plain">(&(</span><span class="identifier">phsfb</span><span class="plain">-</span><span class="element">>boxed_phsf.local_value_variables</span><span class="plain">),</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">return</span><span class="plain"> &(</span><span class="identifier">phsfb</span><span class="plain">-</span><span class="element">>boxed_phsf</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Frames::boxed_frame is used in 17/ts (<a href="17-ts.html#SP5">§5</a>, <a href="17-ts.html#SP8">§8</a>), 17/rs (<a href="17-rs.html#SP5">§5</a>, <a href="17-rs.html#SP12_1_1">§12.1.1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. The current stack frame. </b>At any given time, a single stack frame is valid for local variable names
|
|
and phrase option names used as conditions. It will be the nonphrasal one
|
|
if that's active, and otherwise must be set as needed.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">current_frame</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">current_frame</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Frames::make_current</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="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"can't select null stack frame"</span><span class="plain">);</span>
|
|
<span class="identifier">current_frame</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Frames::remove_current</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="identifier">current_frame</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 Frames::current_stack_frame is used in <a href="#SP9">§9</a>, <a href="#SP10">§10</a>, <a href="#SP11">§11</a>, <a href="#SP12">§12</a>, <a href="#SP14">§14</a>, <a href="#SP15">§15</a>, 4/am (<a href="4-am.html#SP34_2">§34.2</a>, <a href="4-am.html#SP34_2_1">§34.2.1</a>), 6/rlt (<a href="6-rlt.html#SP30">§30</a>), 10/cad (<a href="10-cad.html#SP19_2">§19.2</a>), 10/teav (<a href="10-teav.html#SP15">§15</a>, <a href="10-teav.html#SP16">§16</a>), 15/ma (<a href="15-ma.html#SP13">§13</a>), 17/ts (<a href="17-ts.html#SP5">§5</a>, <a href="17-ts.html#SP8">§8</a>, <a href="17-ts.html#SP9">§9</a>, <a href="17-ts.html#SP11">§11</a>), 17/rs (<a href="17-rs.html#SP12_1_1">§12.1.1</a>), 20/eq (<a href="20-eq.html#SP47_3">§47.3</a>), 22/pu (<a href="22-pu.html#SP20_1_1">§20.1.1</a>), 24/lv (<a href="24-lv.html#SP10">§10</a>, <a href="24-lv.html#SP11">§11</a>, <a href="24-lv.html#SP20">§20</a>, <a href="24-lv.html#SP21">§21</a>, <a href="24-lv.html#SP22">§22</a>, <a href="24-lv.html#SP23">§23</a>, <a href="24-lv.html#SP26">§26</a>, <a href="24-lv.html#SP27">§27</a>, <a href="24-lv.html#SP30">§30</a>, <a href="24-lv.html#SP31">§31</a>, <a href="24-lv.html#SP33">§33</a>, <a href="24-lv.html#SP33_3">§33.3</a>, <a href="24-lv.html#SP41">§41</a>, <a href="24-lv.html#SP42">§42</a>), 24/pb (<a href="24-pb.html#SP8">§8</a>, <a href="24-pb.html#SP18">§18</a>, <a href="24-pb.html#SP19">§19</a>).</p>
|
|
|
|
<p class="endnote">The function Frames::make_current is used in <a href="#SP6">§6</a>, 22/cs (<a href="22-cs.html#SP7">§7</a>), 22/prcd (<a href="22-prcd.html#SP9">§9</a>), 25/cp (<a href="25-cp.html#SP3_2">§3.2</a>), 26/rt (<a href="26-rt.html#SP3_1">§3.1</a>).</p>
|
|
|
|
<p class="endnote">The function Frames::remove_current is used in <a href="#SP6">§6</a>, 22/cs (<a href="22-cs.html#SP7">§7</a>), 26/rt (<a href="26-rt.html#SP4">§4</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9"></a><b>§9. Kinds. </b>The kind of value we expect to return from within this stack frame, if any.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Frames::set_kind_returned</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">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">>kind_returned</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">Frames::get_kind_returned</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="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 Frames::set_kind_returned is used in 22/ptd (<a href="22-ptd.html#SP20">§20</a>).</p>
|
|
|
|
<p class="endnote">The function Frames::get_kind_returned is used in 25/cii (<a href="25-cii.html#SP3_1_1_4_7_1">§3.1.1.4.7.1</a>, <a href="25-cii.html#SP7">§7</a>), 25/cp (<a href="25-cp.html#SP3_3_1">§3.3.1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10"></a><b>§10. </b>And the values of the kind variables A to Z:
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">KIND_VARIABLE_FROM_CONTEXT</span><span class="plain"> </span><span class="functiontext">Frames::get_kind_variable</span>
|
|
</pre>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Frames::set_kind_variables</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">kind</span><span class="plain"> **</span><span class="identifier">vars</span><span class="plain">) {</span>
|
|
<span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_kind_variables</span><span class="plain"> = </span><span class="identifier">vars</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">Frames::get_kind_variable</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain">) {</span>
|
|
<span class="reserved">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">phsf</span><span class="plain">-</span><span class="element">>local_kind_variables</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_kind_variables</span><span class="plain">[</span><span class="identifier">N</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">kind</span><span class="plain"> **</span><span class="functiontext">Frames::temporarily_set_kvs</span><span class="plain">(</span><span class="identifier">kind</span><span class="plain"> **</span><span class="identifier">vars</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">kind</span><span class="plain"> **</span><span class="identifier">prev</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_kind_variables</span><span class="plain">;</span>
|
|
<span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_kind_variables</span><span class="plain"> = </span><span class="identifier">vars</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">prev</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Frames::set_kind_variables is used in 25/cp (<a href="25-cp.html#SP3_2">§3.2</a>).</p>
|
|
|
|
<p class="endnote">The function Frames::get_kind_variable is used in 25/cii (<a href="25-cii.html#SP3_1_1_1">§3.1.1.1</a>).</p>
|
|
|
|
<p class="endnote">The function Frames::temporarily_set_kvs is used in 25/cii (<a href="25-cii.html#SP3_1_1">§3.1.1</a>, <a href="25-cii.html#SP7">§7</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11"></a><b>§11. Stacked variables. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Frames::set_stvol</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">stacked_variable_owner_list</span><span class="plain"> *</span><span class="identifier">stvol</span><span class="plain">) {</span>
|
|
<span class="identifier">phsf</span><span class="plain">-</span><span class="element">>local_stvol</span><span class="plain"> = </span><span class="identifier">stvol</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">stacked_variable_owner_list</span><span class="plain"> *</span><span class="functiontext">Frames::get_stvol</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_stvol</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 Frames::set_stvol is used in 22/pu (<a href="22-pu.html#SP20_1_1">§20.1.1</a>), 22/prcd (<a href="22-prcd.html#SP9">§9</a>), 25/cp (<a href="25-cp.html#SP3_2">§3.2</a>).</p>
|
|
|
|
<p class="endnote">The function Frames::get_stvol is used in 10/teav (<a href="10-teav.html#SP16">§16</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12"></a><b>§12. Past tense. </b>All we do here is to make a note if anything compiled in this context makes
|
|
reference to the past.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Frames::determines_the_past</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">"tried to determine past where no stack frame exists"</span><span class="plain">);</span>
|
|
<span class="identifier">phsf</span><span class="plain">-</span><span class="element">>determines_past_conditions</span><span class="plain"> = </span><span class="identifier">TRUE</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 determines past\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Frames::used_for_past_tense</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="identifier">phsf</span><span class="plain">-</span><span class="element">>determines_past_conditions</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 Frames::determines_the_past is used in 24/ch (<a href="24-ch.html#SP7">§7</a>).</p>
|
|
|
|
<p class="endnote">The function Frames::used_for_past_tense is used in 12/ca (<a href="12-ca.html#SP5_1_2">§5.1.2</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP13"></a><b>§13. Logging. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Frames::log</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="identifier">NULL</span><span class="plain">) { </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"<null stack frame>\</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="identifier">LOG</span><span class="plain">(</span><span class="string">"Stack frame at %08x: it:%s, dpc:%s\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
|
|
<span class="identifier">phsf</span><span class="plain">,</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="string">"yes"</span><span class="plain">:</span><span class="string">"no"</span><span class="plain">,</span>
|
|
<span class="plain">(</span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>determines_past_conditions</span><span class="plain">)?</span><span class="string">"yes"</span><span class="plain">:</span><span class="string">"no"</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">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">LET_VALUE_LV</span><span class="plain">: </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Let/loop value: "</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">TOKEN_CALL_PARAMETER_LV</span><span class="plain">: </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Call value: "</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">LOG</span><span class="plain">(</span><span class="string">"Internal use: "</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">LOG</span><span class="plain">(</span><span class="string">"Other: "</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">LOG</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="functiontext">LocalVariables::log</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">); </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Frames::log is used in 17/ts (<a href="17-ts.html#SP9">§9</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14"></a><b>§14. Formal parameter allocation. </b>Some stack frames need access to additional variables to handle run-time
|
|
invocation ambiguities, and this is how they're requested:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Frames::need_at_least_this_many_formals</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain">) {</span>
|
|
<span class="reserved">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">"requested formal parameters outside all stack frames"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> > </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>no_formal_parameters_needed</span><span class="plain">)</span>
|
|
<span class="identifier">phsf</span><span class="plain">-</span><span class="element">>no_formal_parameters_needed</span><span class="plain"> = </span><span class="identifier">N</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Frames::need_at_least_this_many_formals is used in 25/ci (<a href="25-ci.html#SP3_2">§3.2</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15"></a><b>§15. Pointer value allocation. </b>Values such as lists, which have to stored in whole blocks rather than single
|
|
words of memory, are sometimes called pointer values because all we can
|
|
immediately handle is a pointer to the block. When these arise in the
|
|
compilation of a routine, we have to make a note of this, because special
|
|
code will be needed to allocate and deallocate the memory storing the block.
|
|
The following is the routine called to make this note.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">pointer_allocation</span><span class="plain"> *</span><span class="functiontext">Frames::add_allocation</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">char</span><span class="plain"> *</span><span class="identifier">proto</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">LOG</span><span class="plain">(</span><span class="string">"Tried to allocate: $u\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to allocate block kind outside all stack frames"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">pointer_allocation</span><span class="plain"> *</span><span class="identifier">pall</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">pointer_allocation</span><span class="plain">);</span>
|
|
<span class="identifier">pall</span><span class="plain">-</span><span class="element">>next_in_frame</span><span class="plain"> = </span><span class="identifier">phsf</span><span class="plain">-</span><span class="element">>allocated_pointers</span><span class="plain">;</span>
|
|
<span class="identifier">phsf</span><span class="plain">-</span><span class="element">>allocated_pointers</span><span class="plain"> = </span><span class="identifier">pall</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>next_in_frame</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>offset_index</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>offset_index</span><span class="plain"> = </span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>next_in_frame</span><span class="plain">-</span><span class="element">>offset_past</span><span class="plain">;</span>
|
|
<span class="identifier">pall</span><span class="plain">-</span><span class="element">>offset_past</span><span class="plain"> = </span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>offset_index</span><span class="plain"> + </span><span class="identifier">Kinds::Behaviour::get_small_block_size</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
|
|
|
|
<<span class="cwebmacro">Work out heap allocation code for this pointer value</span> <span class="cwebmacronumber">15.1</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Work out local reference code for this pointer value</span> <span class="cwebmacronumber">15.2</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Work out promotion schema for this pointer value</span> <span class="cwebmacronumber">15.3</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pall</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Frames::compile_allocation</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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">pointer_allocation</span><span class="plain"> *</span><span class="identifier">pall</span><span class="plain"> = </span><span class="functiontext">Frames::add_allocation</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S"</span><span class="plain">, </span><span class="functiontext">Frames::pall_get_local_reference</span><span class="plain">(</span><span class="identifier">pall</span><span class="plain">));</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Frames::emit_allocation</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">pointer_allocation</span><span class="plain"> *</span><span class="identifier">pall</span><span class="plain"> = </span><span class="functiontext">Frames::add_allocation</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="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">all_sch</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>escaped_local_reference_code</span><span class="plain">);</span>
|
|
<span class="functiontext">Calculus::Schemas::emit_expand_from_terms</span><span class="plain">(</span><span class="identifier">all_sch</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</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 Frames::add_allocation is used in 13/rsfk (<a href="13-rsfk.html#SP6">§6</a>).</p>
|
|
|
|
<p class="endnote">The function Frames::compile_allocation is used in 13/rsfk (<a href="13-rsfk.html#SP7">§7</a>).</p>
|
|
|
|
<p class="endnote">The function Frames::emit_allocation is used in 12/dtd (<a href="12-dtd.html#SP16">§16</a>, <a href="12-dtd.html#SP17">§17</a>), 13/rsfk (<a href="13-rsfk.html#SP7">§7</a>), 14/cfs (<a href="14-cfs.html#SP7">§7</a>), 17/ts (<a href="17-ts.html#SP8">§8</a>), 25/ciac (<a href="25-ciac.html#SP2_1">§2.1</a>), 25/cii (<a href="25-cii.html#SP1_2_1">§1.2.1</a>, <a href="25-cii.html#SP3_2_1">§3.2.1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15_1"></a><b>§15.1. </b>The following works out a call to <code class="display"><span class="extract">BlkValueCreate</span></code> which will return a
|
|
default value of the given kind.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Work out heap allocation code for this pointer value</span> <span class="cwebmacronumber">15.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">pall</span><span class="plain">-</span><span class="element">>allocation</span><span class="plain"> = </span><span class="functiontext">Kinds::RunTime::make_heap_allocation</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, 0, </span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>offset_index</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP15">§15</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15_2"></a><b>§15.2. </b>This is the storage used to hold the pointer. For each frame, we have
|
|
a subarray of short blocks, indexed by the offset.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Work out local reference code for this pointer value</span> <span class="cwebmacronumber">15.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">pall</span><span class="plain">-</span><span class="element">>local_reference_code</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
|
|
<span class="identifier">pall</span><span class="plain">-</span><span class="element">>escaped_local_reference_code</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>offset_index</span><span class="plain"> == 0) {</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>local_reference_code</span><span class="plain">, </span><span class="string">"I7SFRAME"</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>escaped_local_reference_code</span><span class="plain">, </span><span class="string">"I7SFRAME"</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>offset_index</span><span class="plain"> == 1) {</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>local_reference_code</span><span class="plain">, </span><span class="string">"(I7SFRAME+WORDSIZE)"</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>escaped_local_reference_code</span><span class="plain">, </span><span class="string">"(I7SFRAME+WORDSIZE)"</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>local_reference_code</span><span class="plain">, </span><span class="string">"(I7SFRAME+WORDSIZE*%d)"</span><span class="plain">, </span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>offset_index</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>escaped_local_reference_code</span><span class="plain">, </span><span class="string">"(I7SFRAME+WORDSIZE**%d)"</span><span class="plain">, </span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>offset_index</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP15">§15</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15_3"></a><b>§15.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Work out promotion schema for this pointer value</span> <span class="cwebmacronumber">15.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">pall</span><span class="plain">-</span><span class="element">>schema_for_promotion</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">proto</span><span class="plain">) {</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">proto</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]; </span><span class="identifier">i</span><span class="plain">++) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">proto</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] == </span><span class="character">'*'</span><span class="plain">) && (</span><span class="identifier">proto</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">+1] == </span><span class="character">'#'</span><span class="plain">) && (</span><span class="identifier">proto</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">+2] == </span><span class="character">'#'</span><span class="plain">)) {</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>schema_for_promotion</span><span class="plain">, </span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>escaped_local_reference_code</span><span class="plain">);</span>
|
|
<span class="identifier">i</span><span class="plain">+=2;</span>
|
|
<span class="reserved">continue</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>schema_for_promotion</span><span class="plain">, </span><span class="identifier">proto</span><span class="plain">[</span><span class="identifier">i</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="#SP15">§15</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP16"></a><b>§16. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">Frames::pall_get_local_reference</span><span class="plain">(</span><span class="reserved">pointer_allocation</span><span class="plain"> *</span><span class="identifier">pall</span><span class="plain">) {</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>local_reference_code</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">Frames::pall_get_expanded_schema</span><span class="plain">(</span><span class="reserved">pointer_allocation</span><span class="plain"> *</span><span class="identifier">pall</span><span class="plain">) {</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pall</span><span class="plain">-</span><span class="element">>schema_for_promotion</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Frames::pall_get_local_reference is used in <a href="#SP15">§15</a>.</p>
|
|
|
|
<p class="endnote">The function Frames::pall_get_expanded_schema is used in 13/rsfk (<a href="13-rsfk.html#SP6">§6</a>).</p>
|
|
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><a href="24-pb.html">Back to 'Phrase Blocks'</a></li><li><a href="24-ch.html">Continue with 'Chronology'</a></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</body>
|
|
</html>
|
|
|