mirror of
https://github.com/ganelson/inform.git
synced 2024-07-08 18:14:21 +03:00
478 lines
55 KiB
HTML
478 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>17/tl</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 '17/ts' 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#17">Chapter 17: Text Data</a></li><li><b>Text Substitutions</b></li></ul><p class="purpose">In this section we compile text with substitutions.</p>
|
|
|
|
<ul class="toc"><li><a href="#SP1">§1. Definitions</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>Text containing substitutions, such as "You pick up [the noun] thoughtfully.",
|
|
are compiled as routines rather than Z-machine strings. Each is stored in one
|
|
of the following structures. Unlike literal text, a text routine might lead
|
|
to problem messages when eventually compiled, so it is useful to record the
|
|
current sentence when a text routine is created: this means a problem can
|
|
be reported at the right place.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The easiest way to understand this section is to pretend that responses
|
|
don't exist, and ignore them until they come up later.
|
|
</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">text_substitution</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">unsubstituted_text</span><span class="plain">; </span> <span class="comment">including the substitutions in squares</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">dont_need_after_all</span><span class="plain">; </span> <span class="comment">in case replaced as a response</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">tr_done_already</span><span class="plain">; </span> <span class="comment">has been compiled</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">responding_to_rule</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">responding_to_marker</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">sentence_using_this</span><span class="plain">; </span> <span class="comment">where this occurs in source</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">local_names_existed_at_usage_time</span><span class="plain">; </span> <span class="comment">remember in case of problems</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">parked_stack_frame</span><span class="plain">; </span> <span class="comment">for cases where possible</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">ts_iname</span><span class="plain">; </span> <span class="comment">the I6 array for this</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">ts_routine_iname</span><span class="plain">; </span> <span class="comment">the routine to implement it</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">ts_sb_needed</span><span class="plain">; </span> <span class="comment">reference copy of small block needed as a constant?</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">compilation_module</span><span class="plain"> *</span><span class="identifier">belongs_to_module</span><span class="plain">;</span>
|
|
<span class="identifier">MEMORY_MANAGEMENT</span>
|
|
<span class="plain">} </span><span class="reserved">text_substitution</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure text_substitution is accessed in 17/rs and here.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b>We are only allowed to create new ones until the following is set:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_further_text_subs</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. </b>The following global variable records whether we are currently compiling
|
|
a text routine, rather than some other routine, or free-standing objects.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">compiling_text_routines_mode</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; </span> <span class="comment">used for better problem messages</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§5. </b>Like literal texts, text substitutions aren't printed out in full when
|
|
they first arise; we keep a note of them when we need them, and compile
|
|
suitable routines later.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">A problem with this is that a text substitution probably contains references
|
|
to variables which exist now, but may not exist later when a routine to do
|
|
the printing is being compiled. For example,
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>say "The dial reads [counter].";</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">may do quite different things at different points in the code, according to
|
|
what <code class="display"><span class="extract">counter</span></code> currently means. So we need to take note of the current
|
|
stack frame; and we mustn't optimise by compiling identical text substitutions
|
|
to the same routines to print them.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">text_substitution</span><span class="plain"> *</span><span class="functiontext">Strings::TextSubstitutions::new_text_substitution</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">ph_stack_frame</span><span class="plain"> *</span><span class="identifier">phsf</span><span class="plain">, </span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">marker</span><span class="plain">, </span><span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain">) {</span>
|
|
<span class="reserved">text_substitution</span><span class="plain"> *</span><span class="identifier">ts</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">text_substitution</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">no_further_text_subs</span><span class="plain">) </span><<span class="cwebmacro">Panic, because it is really too late</span> <span class="cwebmacronumber">5.1</span>><span class="plain">;</span>
|
|
<span class="identifier">ts</span><span class="plain">-</span><span class="element">>unsubstituted_text</span><span class="plain"> = </span><span class="identifier">Wordings::first_word</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
|
|
<span class="identifier">ts</span><span class="plain">-</span><span class="element">>sentence_using_this</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
|
|
<span class="identifier">ts</span><span class="plain">-</span><span class="element">>local_names_existed_at_usage_time</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">R</span><span class="plain">) {</span>
|
|
<span class="identifier">ts</span><span class="plain">-</span><span class="element">>parked_stack_frame</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">ph_stack_frame</span><span class="plain"> </span><span class="identifier">new_frame</span><span class="plain"> = </span><span class="functiontext">Frames::new</span><span class="plain">();</span>
|
|
<span class="identifier">ts</span><span class="plain">-</span><span class="element">>parked_stack_frame</span><span class="plain"> = </span><span class="functiontext">Frames::boxed_frame</span><span class="plain">(&</span><span class="identifier">new_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="functiontext">LocalVariables::copy</span><span class="plain">(</span><span class="identifier">ts</span><span class="plain">-</span><span class="element">>parked_stack_frame</span><span class="plain">, </span><span class="identifier">phsf</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">ts</span><span class="plain">-</span><span class="element">>responding_to_rule</span><span class="plain"> = </span><span class="identifier">R</span><span class="plain">;</span>
|
|
<span class="identifier">ts</span><span class="plain">-</span><span class="element">>responding_to_marker</span><span class="plain"> = </span><span class="identifier">marker</span><span class="plain">;</span>
|
|
<span class="identifier">ts</span><span class="plain">-</span><span class="element">>dont_need_after_all</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">ts</span><span class="plain">-</span><span class="element">>tr_done_already</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">ts</span><span class="plain">-</span><span class="element">>ts_sb_needed</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">phrase_being_compiled</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">LocalVariables::count</span><span class="plain">(</span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">()) > 0))</span>
|
|
<span class="identifier">ts</span><span class="plain">-</span><span class="element">>local_names_existed_at_usage_time</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">PR</span><span class="plain"> = </span><span class="functiontext">Hierarchy::package_within</span><span class="plain">(</span><span class="constant">LITERALS_HAP</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">);</span>
|
|
<span class="identifier">ts</span><span class="plain">-</span><span class="element">>ts_iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">TEXT_SUBSTITUTION_HL</span><span class="plain">, </span><span class="identifier">PR</span><span class="plain">);</span>
|
|
<span class="identifier">ts</span><span class="plain">-</span><span class="element">>ts_routine_iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">TEXT_SUBSTITUTION_FN_HL</span><span class="plain">, </span><span class="identifier">PR</span><span class="plain">);</span>
|
|
<span class="identifier">ts</span><span class="plain">-</span><span class="element">>belongs_to_module</span><span class="plain"> = </span><span class="functiontext">Modules::current</span><span class="plain">();</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TEXT_SUBSTITUTIONS</span><span class="plain">, </span><span class="string">"Requesting text routine %d %08x %W %08x\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
|
|
<span class="identifier">ts</span><span class="plain">-></span><span class="identifier">allocation_id</span><span class="plain">, (</span><span class="reserved">int</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">R</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ts</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Strings::TextSubstitutions::new_text_substitution is used in <a href="#SP8">§8</a>, <a href="#SP8_1">§8.1</a>, 17/rs (<a href="17-rs.html#SP5">§5</a>, <a href="17-rs.html#SP7_1">§7.1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5_1"></a><b>§5.1. </b>Timing is going to turn out to be a real problem in all of this code.
|
|
If Inform finds that it needs a text substitution very late in its run —
|
|
after it has compiled them and can't compile any more — there's nothing
|
|
to do but panic.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Panic, because it is really too late</span> <span class="cwebmacronumber">5.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Too late for further text substitutions"</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP5">§5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§6. </b>The template layer calls the following when that midnight hour chimes:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Strings::TextSubstitutions::allow_no_further_text_subs</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="identifier">no_further_text_subs</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Strings::TextSubstitutions::allow_no_further_text_subs is used in 1/mr (<a href="1-mr.html#SP4_14">§4.14</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§7. </b>For some years these were compiled to routines verbosely called
|
|
<code class="display"><span class="extract">text_routine_1</span></code> and so on, but no longer:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Strings::TextSubstitutions::text_substitution_iname</span><span class="plain">(</span><span class="reserved">text_substitution</span><span class="plain"> *</span><span class="identifier">ts</span><span class="plain">) {</span>
|
|
<span class="identifier">ts</span><span class="plain">-</span><span class="element">>ts_sb_needed</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">ts</span><span class="plain">-</span><span class="element">>ts_iname</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Strings::TextSubstitutions::text_substitution_iname is used in <a href="#SP8">§8</a>, <a href="#SP8_1">§8.1</a>, 17/rs (<a href="17-rs.html#SP7_1">§7.1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. </b>The following is called when we want to compile a usage of a text
|
|
substitution; for instance, when compiling
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>say "The time is [time of day]. Hurry!";</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">we'll compile a call to a routine like <code class="display"><span class="extract">TS_1()</span></code>, and make a note to compile
|
|
that routine later. This appearance of the routine name is called the "cue".
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Strings::TextSubstitutions::text_substitution_cue</span><span class="plain">(</span><span class="identifier">value_holster</span><span class="plain"> *</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">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">adopted_rule_for_compilation</span><span class="plain">) {</span>
|
|
<span class="functiontext">Rules::log</span><span class="plain">(</span><span class="identifier">adopted_rule_for_compilation</span><span class="plain">);</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">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">adopted_rule_for_compilation</span><span class="plain">) {</span>
|
|
<<span class="cwebmacro">Write the actual cue</span> <span class="cwebmacronumber">8.1</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">Holsters::data_acceptable</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">)) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">downs</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">PERMIT_LOCALS_IN_TEXT_CMODE</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">phsf</span><span class="plain"> = </span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">();</span>
|
|
<span class="identifier">downs</span><span class="plain"> = </span><span class="functiontext">LocalVariables::emit_storage</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="functiontext">Frames::boxed_frame</span><span class="plain">(</span><span class="identifier">phsf</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">TEXT_TY_EXPANDIFPERISHABLE_HL</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="functiontext">Frames::emit_allocation</span><span class="plain">(</span><span class="identifier">K_text</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">text_substitution</span><span class="plain"> *</span><span class="identifier">ts</span><span class="plain"> = </span><span class="functiontext">Strings::TextSubstitutions::new_text_substitution</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="identifier">adopted_rule_for_compilation</span><span class="plain">, </span><span class="identifier">adopted_marker_for_compilation</span><span class="plain">, </span><span class="functiontext">Emit::current_enclosure</span><span class="plain">());</span>
|
|
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">tin</span><span class="plain"> = </span><span class="functiontext">Strings::TextSubstitutions::text_substitution_iname</span><span class="plain">(</span><span class="identifier">ts</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VH</span><span class="plain">-></span><span class="identifier">vhmode_wanted</span><span class="plain"> == </span><span class="identifier">INTER_DATA_VHMODE</span><span class="plain">)</span>
|
|
<span class="functiontext">Emit::holster</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">tin</span><span class="plain">);</span>
|
|
<span class="reserved">else</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">tin</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">PERMIT_LOCALS_IN_TEXT_CMODE</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="reserved">while</span><span class="plain"> (</span><span class="identifier">downs</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">downs</span><span class="plain">--; }</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 Strings::TextSubstitutions::text_substitution_cue is used in 17/rs (<a href="17-rs.html#SP12_1_2">§12.1.2</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8_1"></a><b>§8.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Write the actual cue</span> <span class="cwebmacronumber">8.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">text_substitution</span><span class="plain"> *</span><span class="identifier">ts</span><span class="plain"> = </span><span class="functiontext">Strings::TextSubstitutions::new_text_substitution</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="identifier">adopted_rule_for_compilation</span><span class="plain">, </span><span class="identifier">adopted_marker_for_compilation</span><span class="plain">, </span><span class="functiontext">Emit::current_enclosure</span><span class="plain">());</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">CONSTANT_CMODE</span><span class="plain">)) {</span>
|
|
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">PR</span><span class="plain"> = </span><span class="functiontext">Hierarchy::package_in_enclosure</span><span class="plain">(</span><span class="constant">BLOCK_CONSTANTS_HAP</span><span class="plain">);</span>
|
|
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">BLOCK_CONSTANT_HL</span><span class="plain">, </span><span class="identifier">PR</span><span class="plain">);</span>
|
|
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Emit::named_late_array_begin</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">);</span>
|
|
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">CONSTANT_PACKED_TEXT_STORAGE_HL</span><span class="plain">));</span>
|
|
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">ts</span><span class="plain">-</span><span class="element">>ts_routine_iname</span><span class="plain">);</span>
|
|
<span class="functiontext">Emit::array_end</span><span class="plain">(</span><span class="identifier">save</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="functiontext">Emit::holster</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">tin</span><span class="plain"> = </span><span class="functiontext">Strings::TextSubstitutions::text_substitution_iname</span><span class="plain">(</span><span class="identifier">ts</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Holsters::data_acceptable</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">)) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tin</span><span class="plain">) </span><span class="functiontext">Emit::holster</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">tin</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="#SP8">§8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9"></a><b>§9. </b>And the following clarifies problem messages arising from this point,
|
|
since it often confuses newcomers:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">text_substitution</span><span class="plain"> *</span><span class="identifier">current_ts_being_compiled</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Strings::TextSubstitutions::append_text_substitution_proviso</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">it_is_not_worth_adding</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">current_ts_being_compiled</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">current_ts_being_compiled</span><span class="plain">-</span><span class="element">>local_names_existed_at_usage_time</span><span class="plain">)) {</span>
|
|
<span class="functiontext">Frames::log</span><span class="plain">(</span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">());</span>
|
|
<span class="identifier">Problems::quote_wording</span><span class="plain">(9, </span><span class="identifier">current_ts_being_compiled</span><span class="plain">-</span><span class="element">>unsubstituted_text</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">" %PIt may be worth adding that this problem arose in text "</span>
|
|
<span class="string">"which both contains substitutions and is also being used as "</span>
|
|
<span class="string">"a value - being put into a variable, or used as one of the "</span>
|
|
<span class="string">"ingredients in a phrase other than 'say'. Because that means "</span>
|
|
<span class="string">"it needs to be used in places outside its immediate context, "</span>
|
|
<span class="string">"it is not allowed to refer to any 'let' values or phrase "</span>
|
|
<span class="string">"options - those are temporary things, long gone by the time it "</span>
|
|
<span class="string">"would need to be printed."</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Strings::TextSubstitutions::append_text_substitution_proviso appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10"></a><b>§10. </b>So much for the cues. As with text literals in the previous section, it's
|
|
now time to redeem our promises and compile the <code class="display"><span class="extract">TS_X</span></code> routines. These routines
|
|
can't be produced all at once, and are sometimes not needed at all: the
|
|
responses mechanism makes this quite fiddly, and so do the existence of
|
|
other constructs in Inform which, when compiled, may make new text
|
|
substitutions. So compilation is handled by a coroutine. (I'm a
|
|
little old-fashioned in calling this a coroutine: it achieves its task in
|
|
instalments, effectively sharing time with other routines which in turn
|
|
add to its task, until everybody is done.)
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Basically, we compile as many text substitutions as we can out of those not
|
|
yet done, returning the number we compile.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">text_substitution</span><span class="plain"> *</span><span class="identifier">latest_ts_compiled</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Strings::TextSubstitutions::compilation_coroutine</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">in_response_mode</span><span class="plain">) {</span>
|
|
<span class="functiontext">Strings::compile_response_launchers</span><span class="plain">();</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">compiling_text_routines_mode</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">TRUE</span><span class="plain">) {</span>
|
|
<span class="reserved">text_substitution</span><span class="plain"> *</span><span class="identifier">ts</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">latest_ts_compiled</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">ts</span><span class="plain"> = </span><span class="identifier">FIRST_OBJECT</span><span class="plain">(</span><span class="reserved">text_substitution</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">ts</span><span class="plain"> = </span><span class="identifier">NEXT_OBJECT</span><span class="plain">(</span><span class="identifier">latest_ts_compiled</span><span class="plain">, </span><span class="reserved">text_substitution</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ts</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="identifier">latest_ts_compiled</span><span class="plain"> = </span><span class="identifier">ts</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">responding</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">ts</span><span class="plain">-</span><span class="element">>responding_to_rule</span><span class="plain">) </span><span class="identifier">responding</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">ts</span><span class="plain">-</span><span class="element">>dont_need_after_all</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) && (</span><span class="identifier">responding</span><span class="plain"> == </span><span class="identifier">in_response_mode</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">ts</span><span class="plain">-</span><span class="element">>tr_done_already</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)) {</span>
|
|
<span class="functiontext">Strings::TextSubstitutions::compile_single_substitution</span><span class="plain">(</span><span class="identifier">ts</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">N</span><span class="plain">++;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">compiling_text_routines_mode</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">N</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Strings::TextSubstitutions::compilation_coroutine is used in <a href="#SP12">§12</a>, 22/cs (<a href="22-cs.html#SP14">§14</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11"></a><b>§11. </b>We can now forget about the coroutine management, and just compile a single
|
|
text substitution. The main thing is to copy over references to local variables
|
|
from the stack frame creating this text substitution to the stack frame
|
|
compiling it.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Strings::TextSubstitutions::compile_single_substitution</span><span class="plain">(</span><span class="reserved">text_substitution</span><span class="plain"> *</span><span class="identifier">ts</span><span class="plain">) {</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TEXT_SUBSTITUTIONS</span><span class="plain">, </span><span class="string">"Compiling text routine %d %08x %W\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
|
|
<span class="identifier">ts</span><span class="plain">-></span><span class="identifier">allocation_id</span><span class="plain">, (</span><span class="reserved">int</span><span class="plain">) (</span><span class="identifier">ts</span><span class="plain">-</span><span class="element">>parked_stack_frame</span><span class="plain">), </span><span class="identifier">ts</span><span class="plain">-</span><span class="element">>unsubstituted_text</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">current_ts_being_compiled</span><span class="plain"> = </span><span class="identifier">ts</span><span class="plain">;</span>
|
|
<span class="identifier">ts</span><span class="plain">-</span><span class="element">>tr_done_already</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Routines::begin</span><span class="plain">(</span><span class="identifier">ts</span><span class="plain">-</span><span class="element">>ts_routine_iname</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">ts</span><span class="plain">-</span><span class="element">>parked_stack_frame</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ts</span><span class="plain">-</span><span class="element">>responding_to_rule</span><span class="plain">) && (</span><span class="identifier">ts</span><span class="plain">-</span><span class="element">>responding_to_marker</span><span class="plain"> >= 0)) {</span>
|
|
<span class="reserved">response_message</span><span class="plain"> *</span><span class="identifier">resp</span><span class="plain"> = </span><span class="functiontext">Rules::rule_defines_response</span><span class="plain">(</span>
|
|
<span class="identifier">ts</span><span class="plain">-</span><span class="element">>responding_to_rule</span><span class="plain">, </span><span class="identifier">ts</span><span class="plain">-</span><span class="element">>responding_to_marker</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">resp</span><span class="plain">) </span><span class="identifier">phsf</span><span class="plain"> = </span><span class="functiontext">Strings::frame_for_response</span><span class="plain">(</span><span class="identifier">resp</span><span class="plain">);</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="functiontext">LocalVariables::copy</span><span class="plain">(</span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">(), </span><span class="identifier">phsf</span><span class="plain">);</span>
|
|
<span class="functiontext">LocalVariables::monitor_local_parsing</span><span class="plain">(</span><span class="functiontext">Frames::current_stack_frame</span><span class="plain">());</span>
|
|
|
|
<<span class="cwebmacro">Compile a say-phrase</span> <span class="cwebmacronumber">11.1</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">makes_local_references</span><span class="plain"> =</span>
|
|
<span class="functiontext">LocalVariables::local_parsed_recently</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">makes_local_references</span><span class="plain">) {</span>
|
|
<span class="identifier">Produce::push_code_position</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">Produce::begin_position</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">()), </span><span class="identifier">Inter::Bookmarks::snapshot</span><span class="plain">(</span><span class="identifier">Packaging::at</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">())));</span>
|
|
<span class="functiontext">LocalVariables::compile_retrieval</span><span class="plain">(</span><span class="identifier">phsf</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::pop_code_position</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="plain">}</span>
|
|
<span class="functiontext">Routines::end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ts</span><span class="plain">-</span><span class="element">>ts_sb_needed</span><span class="plain">) {</span>
|
|
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Emit::named_array_begin</span><span class="plain">(</span><span class="identifier">ts</span><span class="plain">-</span><span class="element">>ts_iname</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">makes_local_references</span><span class="plain">)</span>
|
|
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">CONSTANT_PERISHABLE_TEXT_STORAGE_HL</span><span class="plain">));</span>
|
|
<span class="reserved">else</span>
|
|
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">CONSTANT_PACKED_TEXT_STORAGE_HL</span><span class="plain">));</span>
|
|
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="identifier">ts</span><span class="plain">-</span><span class="element">>ts_routine_iname</span><span class="plain">);</span>
|
|
<span class="functiontext">Emit::array_end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">current_ts_being_compiled</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 Strings::TextSubstitutions::compile_single_substitution is used in <a href="#SP10">§10</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11_1"></a><b>§11.1. </b>Of course, if we used Inform's standard phrase mechanism exactly, then
|
|
the whole thing would be circular, because that would once again generate
|
|
a request for a new text substitution to be compiled later...
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Compile a say-phrase</span> <span class="cwebmacronumber">11.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="constant">BEGIN_COMPILATION_MODE</span><span class="plain">;</span>
|
|
<span class="identifier">COMPILATION_MODE_EXIT</span><span class="plain">(</span><span class="constant">IMPLY_NEWLINES_IN_SAY_CMODE</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">this_is_a_release_compile</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) || (</span><span class="identifier">this_is_a_debug_compile</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">IFDEBUG_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::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</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">IF_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_number</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">SUPPRESS_TEXT_SUBSTITUTION_HL</span><span class="plain">));</span>
|
|
<span class="identifier">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</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">PRINT_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">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="string">"%W"</span><span class="plain">, </span><span class="identifier">ts</span><span class="plain">-</span><span class="element">>unsubstituted_text</span><span class="plain">);</span>
|
|
<span class="identifier">Produce::val_text</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">S</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">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="identifier">Produce::rtrue</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="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="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">ts_code_block</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="constant">ROUTINE_NT</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_module</span><span class="plain">(</span><span class="identifier">ts_code_block</span><span class="plain">, </span><span class="identifier">ts</span><span class="plain">-</span><span class="element">>belongs_to_module</span><span class="plain">);</span>
|
|
<span class="identifier">compilation_module</span><span class="plain"> *</span><span class="identifier">cm</span><span class="plain"> = </span><span class="functiontext">Modules::current</span><span class="plain">();</span>
|
|
<span class="functiontext">Modules::set_current_to</span><span class="plain">(</span><span class="identifier">ts</span><span class="plain">-</span><span class="element">>belongs_to_module</span><span class="plain">);</span>
|
|
<span class="identifier">ts_code_block</span><span class="plain">-</span><span class="element">>down</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="constant">INVOCATION_LIST_NT</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_text</span><span class="plain">(</span><span class="identifier">ts_code_block</span><span class="plain">-</span><span class="element">>down</span><span class="plain">, </span><span class="identifier">ts</span><span class="plain">-</span><span class="element">>unsubstituted_text</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">ts_code_block</span><span class="plain">-</span><span class="element">>down</span><span class="plain">, </span><span class="constant">from_text_substitution_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
|
|
<span class="functiontext">Sentences::RuleSubtrees::parse_routine_structure</span><span class="plain">(</span><span class="identifier">ts_code_block</span><span class="plain">);</span>
|
|
|
|
<span class="functiontext">Routines::Compile::code_block_outer</span><span class="plain">(0, </span><span class="identifier">ts_code_block</span><span class="plain">-</span><span class="element">>down</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">Produce::rtrue</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
|
|
|
|
<span class="constant">END_COMPILATION_MODE</span><span class="plain">;</span>
|
|
<span class="functiontext">Modules::set_current_to</span><span class="plain">(</span><span class="identifier">cm</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP11">§11</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12"></a><b>§12. </b>See the "Responses" section for why, but we sometimes want to force
|
|
the coroutine to go through the whole queue once, then go back to the
|
|
start again — which would be very inefficient except that in this mode
|
|
we aren't doing very much; most TSs will be passed quickly over.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Strings::TextSubstitutions::compile_text_routines_in_response_mode</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="identifier">latest_ts_compiled</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="functiontext">Strings::TextSubstitutions::compilation_coroutine</span><span class="plain">(</span><span class="identifier">TRUE</span><span class="plain">);</span>
|
|
<span class="identifier">latest_ts_compiled</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 Strings::TextSubstitutions::compile_text_routines_in_response_mode is used in 17/rs (<a href="17-rs.html#SP7">§7</a>).</p>
|
|
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><a href="17-tl.html">Back to 'Text Literals'</a></li><li><a href="17-rs.html">Continue with 'Responses'</a></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</body>
|
|
</html>
|
|
|