mirror of
https://github.com/ganelson/inform.git
synced 2024-07-05 16:44:21 +03:00
703 lines
56 KiB
HTML
703 lines
56 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>22/itp</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 '22/cs' 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#22">Chapter 22: Phrases</a></li><li><b>Construction Sequence</b></li></ul><p class="purpose">To deal with all the |.i6t| interpreted commands which bring about the compilation of phrases, and to ensure that they are used in the correct order.</p>
|
|
|
|
<ul class="toc"><li><a href="#SP1">§1. A day in the life</a></li><li><a href="#SP2">§2. Early morning</a></li><li><a href="#SP3">§3. Mid-morning</a></li><li><a href="#SP4">§4. Late morning</a></li><li><a href="#SP5">§5. Just before noon</a></li><li><a href="#SP6">§6. Noon</a></li><li><a href="#SP7">§7. Early afternoon</a></li><li><a href="#SP10">§10. Mid-afternoon</a></li><li><a href="#SP11">§11. Late Afternoon</a></li><li><a href="#SP14">§14. Evening</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. A day in the life. </b>Suppose we compare the run of Inform to a single day. At dawn the program
|
|
starts up. In the morning it finds out the names of all the constant values
|
|
defined in the source text: names like "Mrs Blenkinsop", "hatstand", and
|
|
so on. By noon it has also found out the wording used for phrases, such as
|
|
"award prize (N - a number) to (gardener - a woman)". This means that in
|
|
the afternoon it knows every name it ever will, and so it can work through
|
|
the definitions of phrases like "award prize...". In the evening, it does
|
|
some book-keeping, and at nightfall it shuts down.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">We will use the story of our single day throughout this section on timing,
|
|
because everything has to happen in just the right order.
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">DAWN_PHT</span><span class="plain"> 0</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">EARLY_MORNING_PHT</span><span class="plain"> 1</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">LATE_MORNING_PHT</span><span class="plain"> 2</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">PRE_NOON_PHT</span><span class="plain"> 3</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">EARLY_AFTERNOON_PHT</span><span class="plain"> 4</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">MID_AFTERNOON_PHT</span><span class="plain"> 5</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">LATE_AFTERNOON_PHT</span><span class="plain"> 6</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">EVENING_PHT</span><span class="plain"> 7</span>
|
|
</pre>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">phrase_time_now</span><span class="plain"> = </span><span class="constant">DAWN_PHT</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::advance_phrase_time_to</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">advance_to</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">advance_to</span><span class="plain"> < </span><span class="identifier">phrase_time_now</span><span class="plain">) {</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Advance from %d to %d\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">phrase_time_now</span><span class="plain">, </span><span class="identifier">advance_to</span><span class="plain">);</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span>
|
|
<span class="string">"The necessary phrase construction events are out of sequence"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">phrase_time_now</span><span class="plain"> = </span><span class="identifier">advance_to</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Phrases::Manager::advance_phrase_time_to is used in <a href="#SP2">§2</a>, <a href="#SP4">§4</a>, <a href="#SP5">§5</a>, <a href="#SP7">§7</a>, <a href="#SP8">§8</a>, <a href="#SP9">§9</a>, <a href="#SP10">§10</a>, <a href="#SP11">§11</a>, <a href="#SP12">§12</a>, <a href="#SP13">§13</a>, <a href="#SP14">§14</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP2"></a><b>§2. Early morning. </b>We run through the phrase preambles to look for named rules like this:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Instead of pushing the red button (this is the fire alarm rule): ...</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">This looking-for-names is done by parsing the preamble text to a PHUD in
|
|
what is called "coarse mode", which can only get an approximate idea at
|
|
best: at this stage the "Instead" rulebook and the "red button" don't
|
|
exist, so most of the words here are meaningless. The PHUD which coarse
|
|
mode parsing produces is far too sketchy to use, and is thrown away.
|
|
But at least it does pick out the name "fire alarm rule", and Inform
|
|
creates an empty "rule" structure called this, registering this as the
|
|
name of a new constant.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::traverse_for_names</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="functiontext">Phrases::Manager::advance_phrase_time_to</span><span class="plain">(</span><span class="constant">EARLY_MORNING_PHT</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::traverse</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::visit_for_names</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::visit_for_names</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">) == </span><span class="constant">ROUTINE_NT</span><span class="plain">)</span>
|
|
<span class="functiontext">Phrases::Usage::predeclare_name_in</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Phrases::Manager::traverse_for_names is used in 1/mr (<a href="1-mr.html#SP4_10">§4.10</a>).</p>
|
|
|
|
<p class="endnote">The function Phrases::Manager::visit_for_names appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. Mid-morning. </b>This is when Inform is making its main traverses through assertions.
|
|
Something very useful is happening, but it's happening somewhere else.
|
|
Assertions such as
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Instead is a rulebook.</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">are being read, and rulebooks are therefore being created.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">We do nothing at all. We see nodes in the parse tree for phrase definitions,
|
|
but we let them go by. The <code class="display"><span class="extract">NULL</span></code>s in these two definitions tell Inform not
|
|
to do anything when the assertion traverse reaches nodes of these types:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">sentence_handler</span><span class="plain"> </span><span class="identifier">COMMAND_SH_handler</span><span class="plain"> = { </span><span class="constant">INVOCATION_LIST_NT</span><span class="plain">, -1, 0, </span><span class="identifier">NULL</span><span class="plain"> };</span>
|
|
<span class="reserved">sentence_handler</span><span class="plain"> </span><span class="identifier">ROUTINE_SH_handler</span><span class="plain"> = { </span><span class="constant">ROUTINE_NT</span><span class="plain">, -1, 0, </span><span class="identifier">NULL</span><span class="plain"> };</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. Late morning. </b>With the assertions read, all the values have their names, and that means
|
|
we can go back to phrases like:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Instead of pushing the red button (this is the fire alarm rule): ...</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">and read them properly. So Inform now runs through the preambles again and
|
|
parses them for a second time to PHUDs, but this time in "fine mode" rather
|
|
than "coarse mode", and this time the result is not thrown away. If the
|
|
phrase is a "To..." phrase declaration, then the PHUD is pretty sketchy and
|
|
we parse more substantial PHTD and PHOD structures to accompany it. But if
|
|
it is a rule, the PHUD contains a great deal of useful information, and we
|
|
accompany it with essentially blank PHTD and PHOD structures. Either way, we
|
|
end up with a triplet of PHUD, PHTD and PHOD, and these are combined into a
|
|
new <code class="display"><span class="extract">phrase</span></code> structure. The PHSF structure is initially created as a
|
|
function of the PHTD: for example, if the phrase reads
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>To award (points - a number): ...</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">then the PHTD notes that "points" is the name of a parameter whose kind is
|
|
to be "number". The stack frame, PHSF, deduces that "points" will be a
|
|
local variable of kind "number" within the phrase when it's running.
|
|
Lastly, a blank PHRCD structure is created, filling out the set of five
|
|
substructures.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">As they are created, the "To..." phrases are insertion-sorted into a list of
|
|
phrases in logical precedence order. This can be done now because it relies
|
|
only on the kinds listed in the PHTD, all of which have existed since
|
|
mid-morning.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">For reasons discussed below, rules are not yet sorted. But the names created
|
|
in mid-morning, such as "fire alarm rule", are associated with their
|
|
phrases, and they are marked for what's called "automatic placement". For
|
|
example, the fire alarm rule will automatically be placed into the Instead
|
|
rulebook, because its preamble begins "Instead". The reason rules are only
|
|
marked to be placed later is that placement has to occur in logical
|
|
precedence order, but rules are harder to sort than phrases. They have to be
|
|
sorted by their PHRCDs, not their PHTDs, and a PHRCD cannot even be parsed
|
|
until afternoon because the conditions for a rule often mention phrases —
|
|
for instance, "Instead of waiting when in darkness", making use of an "in
|
|
darkness" phrase. So for now we just make a mental note to do automatic
|
|
placement later on.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::traverse</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="functiontext">Phrases::Manager::advance_phrase_time_to</span><span class="plain">(</span><span class="constant">LATE_MORNING_PHT</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">progress_target</span><span class="plain"> = 0, </span><span class="identifier">progress_made</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">ParseTree::traverse_int</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::visit_to_count</span><span class="plain">, &</span><span class="identifier">progress_target</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::traverse_int_int</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::visit_to_create</span><span class="plain">, &</span><span class="identifier">progress_target</span><span class="plain">, &</span><span class="identifier">progress_made</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::visit_to_count</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">progress_target</span><span class="plain">) {</span>
|
|
<span class="plain">(*</span><span class="identifier">progress_target</span><span class="plain">)++;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::visit_to_create</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">progress_target</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">progress_made</span><span class="plain">) {</span>
|
|
<span class="plain">(*</span><span class="identifier">progress_made</span><span class="plain">)++;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((*</span><span class="identifier">progress_made</span><span class="plain">) % 10 == 0)</span>
|
|
<span class="functiontext">ProgressBar::update_progress_bar</span><span class="plain">(3,</span>
|
|
<span class="plain">((</span><span class="reserved">float</span><span class="plain">) (*</span><span class="identifier">progress_made</span><span class="plain">))/((</span><span class="reserved">float</span><span class="plain">) (*</span><span class="identifier">progress_target</span><span class="plain">)));</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">) == </span><span class="constant">ROUTINE_NT</span><span class="plain">) {</span>
|
|
<span class="functiontext">Phrases::create_from_preamble</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Phrases::Manager::traverse is used in 1/mr (<a href="1-mr.html#SP4_14">§4.14</a>).</p>
|
|
|
|
<p class="endnote">The function Phrases::Manager::visit_to_count appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function Phrases::Manager::visit_to_create appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§5. Just before noon. </b>It is now nearly noon, and things appear to be a little untidy. Why
|
|
are the "To..." phrases not yet registered with the excerpt parser?
|
|
The answer is that we needed to wait until all of the "To..." phrases
|
|
had been created as structures before we could safely proceed. The first
|
|
phrase couldn't be registered until we knew the complete logical order
|
|
of them all. Well: at last, we do know that, and can make the registration.
|
|
Phrases are the very last things to get their names in Inform (well, not
|
|
counting local variables, whose names only exist fleetingly).
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::register_meanings</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="functiontext">Phrases::Manager::advance_phrase_time_to</span><span class="plain">(</span><span class="constant">PRE_NOON_PHT</span><span class="plain">);</span>
|
|
|
|
<span class="functiontext">Routines::ToPhrases::register_all</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Phrases::Manager::register_meanings is used in 1/mr (<a href="1-mr.html#SP4_14">§4.14</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§6. Noon. </b>When the final phrase is registered, the hour chimes. From this point
|
|
onwards, there's no longer any text which can't be parsed because some
|
|
of the names don't exist yet: everything exists.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§7. Early afternoon. </b>In the afternoon, we begin by binding up the rulebooks. First, we go through
|
|
the phrases destined to be rules, and for each we translate the PHUD (which
|
|
contains mainly textual representations of the usage information, e.g.
|
|
"taking something (called the thingummy) which is in a lighted room during
|
|
Scene Two when the marble slab is open") to a PHRCD (which contains fully
|
|
parsed Inform data structures, e.g., an action pattern and a pointer to a
|
|
<code class="display"><span class="extract">scene</span></code> structure). As noted above, this often means parsing conditions
|
|
which involve phrases, and that's why we're doing it in the afternoon.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">During this PHUD-to-PHRCD parsing process, we make sure that the relevant
|
|
phrase's PHSF is the current stack frame, because it's here that the names
|
|
of any callings (e.g. "thingummy") are created as local variables to be
|
|
valid throughout the phrase.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Once we're done with this, the PHUD will never be used again.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Note that the PHRCDs have to be parsed in source text appearance order (the
|
|
order which <code class="display"><span class="extract">LOOP_OVER</span></code> follows) so that the back reference "doing it" can
|
|
correctly refer to the most recently mentioned action.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::parse_rule_parameters</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="functiontext">Phrases::Manager::advance_phrase_time_to</span><span class="plain">(</span><span class="constant">EARLY_AFTERNOON_PHT</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">, </span><span class="reserved">phrase</span><span class="plain">) {</span>
|
|
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">ph</span><span class="plain">-</span><span class="element">>declaration_node</span><span class="plain">;</span>
|
|
<span class="functiontext">Frames::make_current</span><span class="plain">(&(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">>stack_frame</span><span class="plain">));</span>
|
|
<span class="identifier">ph</span><span class="plain">-</span><span class="element">>runtime_context_data</span><span class="plain"> =</span>
|
|
<span class="functiontext">Phrases::Usage::to_runtime_context_data</span><span class="plain">(&(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">>usage_data</span><span class="plain">));</span>
|
|
<span class="functiontext">Frames::remove_current</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Phrases::Manager::parse_rule_parameters is used in 1/mr (<a href="1-mr.html#SP4_14">§4.14</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. </b>We can finally make the automatic placements of rules into rulebooks: so
|
|
our "fire alarm rule" will at last be placed in the "Instead" rulebook. The
|
|
PHRCDs are used to make sure it appears in the right position.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::add_rules_to_rulebooks</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="functiontext">Phrases::Manager::advance_phrase_time_to</span><span class="plain">(</span><span class="constant">EARLY_AFTERNOON_PHT</span><span class="plain">);</span>
|
|
<span class="functiontext">Rules::Bookings::make_automatic_placements</span><span class="plain">();</span>
|
|
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">NUMBER_RULEBOOKS_CREATED_HL</span><span class="plain">);</span>
|
|
<span class="functiontext">Emit::named_numeric_constant</span><span class="plain">(</span><span class="identifier">iname</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">NUMBER_CREATED</span><span class="plain">(</span><span class="reserved">rulebook</span><span class="plain">));</span>
|
|
<span class="functiontext">Hierarchy::make_available</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">iname</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Phrases::Manager::add_rules_to_rulebooks is used in 1/mr (<a href="1-mr.html#SP4_14">§4.14</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9"></a><b>§9. </b>It might seem as if the rulebooks are now complete, but this is not true,
|
|
because we still have to take care of manual placements like:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>The fire alarm rule is listed in the safety procedures rulebook.</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">This is where we get on with that, traversing the parse tree for sentences
|
|
of this general sort. Rules can also be unlisted, or constrained to happen
|
|
only conditionally, or substituted by other rules.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::parse_rule_placements</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="functiontext">Phrases::Manager::advance_phrase_time_to</span><span class="plain">(</span><span class="constant">EARLY_AFTERNOON_PHT</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::traverse</span><span class="plain">(</span><span class="functiontext">Phrases::Manager::visit_to_parse_placements</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::visit_to_parse_placements</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">) == </span><span class="identifier">SENTENCE_NT</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>down</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>down</span><span class="plain">) == </span><span class="identifier">AVERB_NT</span><span class="plain">)) {</span>
|
|
<span class="identifier">prevailing_mood</span><span class="plain"> =</span>
|
|
<span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>down</span><span class="plain">, </span><span class="identifier">verbal_certainty_ANNOT</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">-</span><span class="element">>down</span><span class="plain">, </span><span class="constant">verb_id_ANNOT</span><span class="plain">) == </span><span class="constant">SPECIAL_MEANING_VB</span><span class="plain">)</span>
|
|
<span class="functiontext">Assertions::Traverse::try_special_meaning</span><span class="plain">(</span><span class="constant">TRAVERSE_FOR_RULE_FILING_SMFT</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">-</span><span class="element">>down</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Phrases::Manager::parse_rule_placements is used in 1/mr (<a href="1-mr.html#SP4_14">§4.14</a>).</p>
|
|
|
|
<p class="endnote">The function Phrases::Manager::visit_to_parse_placements appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10"></a><b>§10. Mid-afternoon. </b>It is now mid-afternoon, and the rulebooks are complete. It is time to
|
|
compile the I6 routines which will provide the run-time definitions of all
|
|
these phrases. This will be a long task, and much of it will be left until
|
|
the evening. But we do get rid of some easy cases now: the rules and
|
|
adjective definitions.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">total_phrases_to_compile</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">total_phrases_compiled</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::compile_first_block</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="functiontext">Phrases::Manager::advance_phrase_time_to</span><span class="plain">(</span><span class="constant">MID_AFTERNOON_PHT</span><span class="plain">);</span>
|
|
|
|
<<span class="cwebmacro">Count up the scale of the task</span> <span class="cwebmacronumber">10.1</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Compile definitions of rules in rulebooks</span> <span class="cwebmacronumber">10.2</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Compile definitions of rules left out of rulebooks</span> <span class="cwebmacronumber">10.3</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Compile phrases which define adjectives</span> <span class="cwebmacronumber">10.4</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Mark To... phrases which have definite kinds for future compilation</span> <span class="cwebmacronumber">10.5</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Throw problems for phrases with return kinds too vaguely defined</span> <span class="cwebmacronumber">10.6</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Throw problems for inline phrases named as constants</span> <span class="cwebmacronumber">10.7</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Phrases::Manager::compile_first_block is used in 1/mr (<a href="1-mr.html#SP4_15">§4.15</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10_1"></a><b>§10.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Count up the scale of the task</span> <span class="cwebmacronumber">10.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">total_phrases_compiled</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">, </span><span class="reserved">phrase</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">>at_least_one_compiled_form_needed</span><span class="plain">)</span>
|
|
<span class="identifier">total_phrases_to_compile</span><span class="plain">++;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP10">§10</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10_2"></a><b>§10.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Compile definitions of rules in rulebooks</span> <span class="cwebmacronumber">10.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">rulebook</span><span class="plain"> *</span><span class="identifier">rb</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">rb</span><span class="plain">, </span><span class="reserved">rulebook</span><span class="plain">)</span>
|
|
<span class="functiontext">Rulebooks::compile_rule_phrases</span><span class="plain">(</span><span class="identifier">rb</span><span class="plain">,</span>
|
|
<span class="plain">&</span><span class="identifier">total_phrases_compiled</span><span class="plain">, </span><span class="identifier">total_phrases_to_compile</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP10">§10</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10_3"></a><b>§10.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Compile definitions of rules left out of rulebooks</span> <span class="cwebmacronumber">10.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">rule</span><span class="plain">)</span>
|
|
<span class="functiontext">Rules::compile_definition</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">,</span>
|
|
<span class="plain">&</span><span class="identifier">total_phrases_compiled</span><span class="plain">, </span><span class="identifier">total_phrases_to_compile</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP10">§10</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10_4"></a><b>§10.4. </b>This doesn't compile all adjective definitions, only the ones which supply
|
|
a whole multi-step phrase to define them — a relatively little-used feature
|
|
of Inform.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Compile phrases which define adjectives</span> <span class="cwebmacronumber">10.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">, </span><span class="reserved">phrase</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Phrases::Usage::get_effect</span><span class="plain">(&(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">>usage_data</span><span class="plain">)) ==</span>
|
|
<span class="constant">DEFINITIONAL_PHRASE_EFF</span><span class="plain">)</span>
|
|
<span class="functiontext">Phrases::compile</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">, &</span><span class="identifier">total_phrases_compiled</span><span class="plain">,</span>
|
|
<span class="identifier">total_phrases_to_compile</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">NULL</span><span class="plain">);</span>
|
|
<span class="functiontext">Adjectives::Meanings::compile_support_code</span><span class="plain">();</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP10">§10</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10_5"></a><b>§10.5. </b>As we'll see, it's legal in Inform to define "To..." phrases with vague
|
|
kinds: "To expose (X - a value)", for example. This can't be compiled as
|
|
vaguely as the definition implies, since there would be no way to know how
|
|
to store X. Instead, for each different kind of X which is actually needed,
|
|
a fresh version of the phrase is compiled — one where X is a number, one
|
|
where it's a text, and so on. This is handled by making a "request" for the
|
|
phrase, indicating that a compiled version of it will be needed.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Since "To..." phrases are only compiled on request, we must remember to
|
|
request the boring ones with straightforward kinds ("To award (N - a number)
|
|
points", say). This is where we do it:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Mark To... phrases which have definite kinds for future compilation</span> <span class="cwebmacronumber">10.5</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">, </span><span class="reserved">phrase</span><span class="plain">) {</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Phrases::TypeData::kind</span><span class="plain">(&(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">>type_data</span><span class="plain">));</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Behaviour::definite</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">>at_least_one_compiled_form_needed</span><span class="plain">)</span>
|
|
<span class="functiontext">Routines::ToPhrases::make_request</span><span class="plain">(</span><span class="identifier">ph</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">EMPTY_WORDING</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="#SP10">§10</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10_6"></a><b>§10.6. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Throw problems for phrases with return kinds too vaguely defined</span> <span class="cwebmacronumber">10.6</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">, </span><span class="reserved">phrase</span><span class="plain">) {</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">KR</span><span class="plain"> = </span><span class="functiontext">Phrases::TypeData::get_return_kind</span><span class="plain">(&(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">>type_data</span><span class="plain">));</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Kinds::Behaviour::semidefinite</span><span class="plain">(</span><span class="identifier">KR</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">Phrases::TypeData::arithmetic_operation</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">) == -1)) {</span>
|
|
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="functiontext">Phrases::declaration_node</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_ReturnKindVague</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"The declaration %1 tries to set up a phrase which decides a "</span>
|
|
<span class="string">"value which is too vaguely described. For example, 'To decide "</span>
|
|
<span class="string">"which number is the target: ...' is fine, because 'number' "</span>
|
|
<span class="string">"is clear about what kind of value should emerge; but 'To "</span>
|
|
<span class="string">"decide which value is the target: ...' is not clear enough."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</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">k</span><span class="plain">=1; </span><span class="identifier">k</span><span class="plain"><=26; </span><span class="identifier">k</span><span class="plain">++)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Kinds::Behaviour::involves_var</span><span class="plain">(</span><span class="identifier">KR</span><span class="plain">, </span><span class="identifier">k</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">Phrases::TypeData::tokens_contain_variable</span><span class="plain">(&(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">>type_data</span><span class="plain">), </span><span class="identifier">k</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) {</span>
|
|
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="functiontext">Phrases::declaration_node</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">);</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">var_letter</span><span class="plain">);</span>
|
|
<span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">var_letter</span><span class="plain">, </span><span class="character">'A'</span><span class="plain">+</span><span class="identifier">k</span><span class="plain">-1);</span>
|
|
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_stream</span><span class="plain">(2, </span><span class="identifier">var_letter</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_ReturnKindUndetermined</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"The declaration %1 tries to set up a phrase which decides a "</span>
|
|
<span class="string">"value which is too vaguely described, because it involves "</span>
|
|
<span class="string">"a kind variable (%2) which it can't determine through "</span>
|
|
<span class="string">"usage."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">var_letter</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="#SP10">§10</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10_7"></a><b>§10.7. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Throw problems for inline phrases named as constants</span> <span class="cwebmacronumber">10.7</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">, </span><span class="reserved">phrase</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Phrases::TypeData::invoked_inline</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">Phrases::Usage::has_name_as_constant</span><span class="plain">(&(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">>usage_data</span><span class="plain">)))) {</span>
|
|
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="functiontext">Phrases::declaration_node</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_NamedInline</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"The declaration %1 tries to give a name to a phrase which is "</span>
|
|
<span class="string">"defined using inline Inform 6 code in (- markers -). Such "</span>
|
|
<span class="string">"phrases can't be named and used as constants because they "</span>
|
|
<span class="string">"have no independent existence, being instead made fresh "</span>
|
|
<span class="string">"each time they are used."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP10">§10</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11"></a><b>§11. Late Afternoon. </b>Rules are pretty well sorted out now, but we still need to compile some I6
|
|
to show how they fit together. These miscellaneous function calls can happen
|
|
in any order, so long as they all occur in the late afternoon.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">First, rules set to go off at a particular time need to have their timings
|
|
noted down:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::TimedEventsTable</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="functiontext">Phrases::Manager::advance_phrase_time_to</span><span class="plain">(</span><span class="constant">LATE_AFTERNOON_PHT</span><span class="plain">);</span>
|
|
<span class="functiontext">Phrases::Timed::TimedEventsTable</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::TimedEventTimesTable</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="functiontext">Phrases::Manager::advance_phrase_time_to</span><span class="plain">(</span><span class="constant">LATE_AFTERNOON_PHT</span><span class="plain">);</span>
|
|
<span class="functiontext">Phrases::Timed::TimedEventTimesTable</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Phrases::Manager::TimedEventsTable appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function Phrases::Manager::TimedEventTimesTable appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12"></a><b>§12. </b>Second, the rulebooks need to be compiled into I6 arrays:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::rulebooks_array</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="functiontext">Phrases::Manager::advance_phrase_time_to</span><span class="plain">(</span><span class="constant">LATE_AFTERNOON_PHT</span><span class="plain">);</span>
|
|
<span class="functiontext">Rulebooks::rulebooks_array_array</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::compile_rulebooks</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="functiontext">Phrases::Manager::advance_phrase_time_to</span><span class="plain">(</span><span class="constant">LATE_AFTERNOON_PHT</span><span class="plain">);</span>
|
|
<span class="functiontext">Rulebooks::compile_rulebooks</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::RulebookNames_array</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="functiontext">Phrases::Manager::advance_phrase_time_to</span><span class="plain">(</span><span class="constant">LATE_AFTERNOON_PHT</span><span class="plain">);</span>
|
|
<span class="functiontext">Rulebooks::RulebookNames_array</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Phrases::Manager::rulebooks_array is used in 1/mr (<a href="1-mr.html#SP4_15">§4.15</a>).</p>
|
|
|
|
<p class="endnote">The function Phrases::Manager::compile_rulebooks is used in 1/mr (<a href="1-mr.html#SP4_15">§4.15</a>).</p>
|
|
|
|
<p class="endnote">The function Phrases::Manager::RulebookNames_array is used in 1/mr (<a href="1-mr.html#SP4_15">§4.15</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP13"></a><b>§13. </b>And finally, just as the sun slips below the horizon, we compile the code
|
|
which prints out values of the kind "rule" at run-time — for example, taking
|
|
the address of the routine which our example rule was compiled to and then
|
|
printing out "fire alarm rule".
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::RulePrintingRule_routine</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="functiontext">Phrases::Manager::advance_phrase_time_to</span><span class="plain">(</span><span class="constant">LATE_AFTERNOON_PHT</span><span class="plain">);</span>
|
|
<span class="functiontext">Rules::RulePrintingRule_routine</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Phrases::Manager::RulePrintingRule_routine is used in 1/mr (<a href="1-mr.html#SP4_15">§4.15</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14"></a><b>§14. Evening. </b>The twilight gathers, but our work is far from done. Recall that we have
|
|
accumulated compilation requests for "To..." phrases, but haven't actually
|
|
acted on them yet.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">We have to do this in quite an open-ended way, because compiling one phrase
|
|
can easily generate fresh requests for others. For instance, suppose we have
|
|
the definition "To expose (X - a value)" in play, and suppose that when
|
|
compiling the phrase "To advertise", Inform runs into the line "expose the
|
|
hoarding text". This causes it to issue a compilation request for "To expose
|
|
(X - a text)". Perhaps we've compiled such a form already, but perhaps we
|
|
haven't. Compilation therefore goes on until all requests have been dealt
|
|
with.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Compiling phrases also produces the need for other pieces of code to be
|
|
generated — for example, suppose our phrase being compiled, "To advertise",
|
|
includes the text:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>let Z be "Two for the price of one! Just [expose price]!";</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">We are going to need to compile "Two for the price of one! Just [expose price]!"
|
|
later on, in its own text substitution routine; but notice that it contains
|
|
the need for "To expose (X - a number)", and that will generate a further
|
|
phrase request.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Because of this and similar problems, it's impossible to compile all the
|
|
phrases alone: we must compile phrases, then things arising from them, then
|
|
phrases arising from those, then things arising from the phrases arising
|
|
from those, and so on, until we're done. The process is therefore structured
|
|
as a set of "coroutines" which each carry out as much as they can and then
|
|
hand over to the others to generate more work. (Indeed, the routine below
|
|
can be called multiple times in the course of the evening.)
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Phrases::Manager::compile_as_needed</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="functiontext">Phrases::Manager::advance_phrase_time_to</span><span class="plain">(</span><span class="constant">EVENING_PHT</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="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">, </span><span class="reserved">rule</span><span class="plain">)</span>
|
|
<span class="functiontext">Rules::compile_definition</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">,</span>
|
|
<span class="plain">&</span><span class="identifier">total_phrases_compiled</span><span class="plain">, </span><span class="identifier">total_phrases_to_compile</span><span class="plain">);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">repeat</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">repeat</span><span class="plain">) {</span>
|
|
<span class="identifier">repeat</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Routines::ToPhrases::compilation_coroutine</span><span class="plain">(</span>
|
|
<span class="plain">&</span><span class="identifier">total_phrases_compiled</span><span class="plain">, </span><span class="identifier">total_phrases_to_compile</span><span class="plain">) > 0)</span>
|
|
<span class="identifier">repeat</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="functiontext">ListTogether::compilation_coroutine</span><span class="plain">() > 0)</span>
|
|
<span class="identifier">repeat</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PL::Actions::ScopeLoops::compilation_coroutine</span><span class="plain">() > 0)</span>
|
|
<span class="identifier">repeat</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Strings::TextSubstitutions::compilation_coroutine</span><span class="plain">(</span><span class="identifier">FALSE</span><span class="plain">) > 0)</span>
|
|
<span class="identifier">repeat</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="functiontext">Calculus::Propositions::Deferred::compilation_coroutine</span><span class="plain">() > 0)</span>
|
|
<span class="identifier">repeat</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Phrases::Manager::compile_as_needed is used in 1/mr (<a href="1-mr.html#SP4_15">§4.15</a>).</p>
|
|
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><a href="22-itp.html">Back to 'Introduction to Phrases'</a></li><li><a href="22-ph.html">Continue with 'Phrases'</a></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</body>
|
|
</html>
|
|
|