mirror of
https://github.com/ganelson/inform.git
synced 2024-07-17 06:24:24 +03:00
848 lines
106 KiB
HTML
848 lines
106 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>24/ch</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 '25/in' 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#25">Chapter 25: Compilation</a></li><li><b>Invocations</b></li></ul><p class="purpose">Specifications which ask to use a phrase (which are "phrasal") indicate which phrase they intend by means of a list of "invocations". This list goes on to record the outcome of type-checking and provides instructions for code generation, as we see here.</p>
|
|
|
|
<ul class="toc"><li><a href="#SP1">§1. Definitions</a></li><li><a href="#SP9">§9. Invocations themselves</a></li><li><a href="#SP22">§22. The implied newlines rule</a></li><li><a href="#SP23">§23. Invocation lists</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>An invocation is a request to perform a particular phrase with a
|
|
particular set of parameters. For instance, to perform "award (N - a number)
|
|
points" with N set to 100.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Phrasal specifications, the ones which request the use of phrases, are
|
|
built up by parsing the source text. This is often so ambiguous that it is
|
|
impossible, at first, to narrow down the meaning to a single invocation,
|
|
and so a phrasal specification builds up a list of possibilities.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The process of type-checking then strikes out definitely incorrect
|
|
invocations, reducing the size of the list. If it becomes empty, the
|
|
type-checker produces a Problem message; and similarly if it is
|
|
impossible to remove mutually exclusive possibilities, for that is
|
|
an ambiguity which Inform cannot resolve. But a successful type-checking
|
|
may still leave more than one invocation in the list. There are two
|
|
reasons for this:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<ul class="items"><li>(a) The list is bunched up into groups, which are numbered within the
|
|
list from 0 upwards. Type-checking proceeds on each group independently.
|
|
For most phrases, there is only one group — group 0 — and this business
|
|
therefore has no effect, but it comes into its own for "say" phrases:
|
|
</li></ul>
|
|
<blockquote>
|
|
<p>say "The time is ", time of day in words, " and you yawn."</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">Here what looks like a single phrase is in fact a sequence of three
|
|
phrases, to say each of the items required, and this gives rise to
|
|
groups 0, 1 and 2 in the invocation list: each group is treated as,
|
|
in effect, a separate phrase in its own right. (Except that compilation
|
|
of the final group has a small difference: that's where Inform appends
|
|
a line break to text which, from its punctuation, apparently ends a
|
|
sentence.) Groups are not interleaved: the list starts with the
|
|
whole of group 0, then the whole of group 1, and so on.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<ul class="items"><li>(b) More interestingly, type-checking of any individual invocation has
|
|
three possible outcomes, not two: as in Scottish law, the verdict
|
|
can be guilty, not guilty, or "not proven". An invocation which
|
|
can be disproved is thrown out of the list; but of the remainder,
|
|
some are marked as proven to be correct, some as unproven. What
|
|
this means is that we cannot tell at compile-time whether the usage
|
|
is valid, but that we will be able to tell at run-time: so the
|
|
code-generator must compile suitable disambiguation code to perform
|
|
this run-time checking automatically.
|
|
</li></ul>
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b>When necessary, and it usually isn't, an invocation has a packet of
|
|
details attached about any phrase options used; for instance, in
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>list the contents of the Box, with newlines;</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">this packet records the text "with newlines" along with its translation
|
|
as a run-time bitmap (with just one bit set, since only one option is used).
|
|
</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">invocation_options</span><span class="plain"> {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">options</span><span class="plain">; </span> <span class="comment">bitmap of any phrase options appended</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">options_invoked_text</span><span class="plain">; </span> <span class="comment">text of any phrase options appended</span>
|
|
<span class="plain">} </span><span class="reserved">invocation_options</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure invocation_options is private to this section.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. </b>An invocation can have an arbitrary number of "tokens". These are the
|
|
arguments for the phrase being invoked; so for instance in
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>a random number between 2 and 7;</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">token 0 is "2" and token 1 is "7". For each token we record both what
|
|
we've parsed — these will each be constant <code class="display"><span class="extract">VALUE_VNT</span></code> specifications of kind
|
|
"number" — and also what match the type-checker needs to make for them
|
|
to be valid.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§5. </b>At first sight, the <code class="display"><span class="extract">invocation</span></code> structure appears to contain redundant
|
|
information. And two of the fields are, in a way, redundant: the word number
|
|
fields holding the text will, of course, be common to every entry in its
|
|
group, so it is wasteful to store them so many times. But not very wasteful,
|
|
by our standards, and the information is not easily available
|
|
elsewhere, and it enables the debugging log to be much more informative
|
|
about the working of our most complicated algorithms.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Similarly, <code class="display"><span class="extract">token_as_parsed</span></code> values look as if they too must be the same
|
|
for everything in the group. But this is not always true. If we are
|
|
interpreting the text "award 11 points" against possible phrases
|
|
"award (O - an object)" and "award (N - a number) points", then
|
|
the 0th token will be "11 points" (probably parsing to <code class="display"><span class="extract">UNKNOWN_NT</span></code>)
|
|
for the first invocation, and "11" (<code class="display"><span class="extract">NUMBER</span></code>) for the second. We
|
|
shall of course accept the second. But the word positions for the 0th
|
|
token, and its parsing values, are different. So each invocation in
|
|
the list records its own <code class="display"><span class="extract">token_as_parsed</span></code> values.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§6. </b>On the other hand, <code class="display"><span class="extract">token_check_to_do</span></code> and <code class="display"><span class="extract">kind_resulting</span></code>
|
|
look as if they are purely a function of the <code class="display"><span class="extract">phrase_invoked</span></code>, and
|
|
therefore need not be in this structure at all. This is not true:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<ul class="items"><li>(i) A SP in <code class="display"><span class="extract">token_check_to_do</span></code> means that Inform has not yet satisfied
|
|
itself that the <code class="display"><span class="extract">token_as_parsed</span></code> value matches properly. Once the
|
|
type-checker does convince itself, the relevant entry in
|
|
<code class="display"><span class="extract">token_check_to_do</span></code> is cleared to <code class="display"><span class="extract">NULL</span></code>. If every token can be cleared,
|
|
the invocation is declared proven. But if the type-checker accepts the
|
|
invocation but marks it as "not proven", one or more values remain as a
|
|
sort of to-do list, telling the code generator what remains to be checked
|
|
at run-time. So <code class="display"><span class="extract">token_check_to_do</span></code> really is associated with a specific
|
|
invocation, and is not redundant.
|
|
</li></ul>
|
|
<ul class="items"><li>(ii) Because arithmetic phrases return different data depending
|
|
on the kinds fed in, <code class="display"><span class="extract">kind_resulting</span></code> will be different
|
|
for different invocations of, say, "+".
|
|
</li></ul>
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="identifier">LOOP_THROUGH_TOKENS_PARSED_IN_INV</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">)</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">lttpii_counter</span><span class="plain">, </span><span class="identifier">lttpii_upto</span><span class="plain"> = </span><span class="functiontext">Invocations::get_no_tokens</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">);</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lttpii_counter</span><span class="plain">=0,</span>
|
|
<span class="identifier">spec</span><span class="plain"> = (</span><span class="identifier">lttpii_counter</span><span class="plain"> < </span><span class="identifier">lttpii_upto</span><span class="plain">)?</span>
|
|
<span class="functiontext">Invocations::get_token_as_parsed</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">lttpii_counter</span><span class="plain">):</span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">lttpii_counter</span><span class="plain"> < </span><span class="identifier">lttpii_upto</span><span class="plain">;</span>
|
|
<span class="identifier">lttpii_counter</span><span class="plain">++,</span>
|
|
<span class="identifier">spec</span><span class="plain"> = (</span><span class="identifier">lttpii_counter</span><span class="plain"> < </span><span class="identifier">lttpii_upto</span><span class="plain">)?</span>
|
|
<span class="functiontext">Invocations::get_token_as_parsed</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">lttpii_counter</span><span class="plain">):</span><span class="identifier">NULL</span><span class="plain">)</span>
|
|
</pre>
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§7. </b></p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">MAX_INVOCATIONS_PER_PHRASE</span><span class="plain"> 4096</span>
|
|
</pre>
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. </b></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">invocation_sort_block</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">inv_data</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">unsorted_position</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">invocation_sort_block</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure invocation_sort_block is private to this section.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9"></a><b>§9. Invocations themselves. </b>Are created thus:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Invocations::new</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="constant">INVOCATION_NT</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_phrase_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_say_verb</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_modal_verb</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_say_adjective</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_kind_resulting</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_phrase_options_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_kind_variable_declarations</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="constant">ssp_closing_segment_wn_ANNOT</span><span class="plain">, -1);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">inv</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::new is used in 10/cap (<a href="10-cap.html#SP10">§10</a>, <a href="10-cap.html#SP11">§11</a>), 25/pi (<a href="25-pi.html#SP4">§4</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10"></a><b>§10. </b>And logging thus:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Invocations::log</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inv</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) { </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"<null invocation>"</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">inv</span><span class="plain">-></span><span class="identifier">node_type</span><span class="plain"> != </span><span class="constant">INVOCATION_NT</span><span class="plain">) { </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"$P"</span><span class="plain">, </span><span class="identifier">inv</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
|
|
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">verdict</span><span class="plain"> = </span><span class="functiontext">Dash::verdict_to_text</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"[%04d%s] %8s "</span><span class="plain">,</span>
|
|
<span class="functiontext">Routines::ToPhrases::sequence_count</span><span class="plain">(</span><span class="identifier">ParseTree::get_phrase_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">)),</span>
|
|
<span class="plain">(</span><span class="functiontext">Invocations::is_marked_to_save_self</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">))?</span><span class="string">"-save-self"</span><span class="plain">:</span><span class="string">""</span><span class="plain">,</span>
|
|
<span class="identifier">verdict</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_say_verb</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">)) {</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"verb:%d"</span><span class="plain">, </span><span class="identifier">ParseTree::get_say_verb</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">)-></span><span class="identifier">allocation_id</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_modal_verb</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">)) </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"modal:%d"</span><span class="plain">, </span><span class="identifier">ParseTree::get_modal_verb</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">)-></span><span class="identifier">allocation_id</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">ParseTree::get_say_adjective</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">)) {</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"adj:%d"</span><span class="plain">, </span><span class="identifier">ParseTree::get_say_adjective</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">)-></span><span class="identifier">allocation_id</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="functiontext">Phrases::log_briefly</span><span class="plain">(</span><span class="identifier">ParseTree::get_phrase_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">));</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"><</span><span class="functiontext">Invocations::get_no_tokens</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">); </span><span class="identifier">i</span><span class="plain">++) {</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">" ($P"</span><span class="plain">, </span><span class="functiontext">Invocations::get_token_as_parsed</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">));</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Invocations::get_token_check_to_do</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">))</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">" =? $P"</span><span class="plain">, </span><span class="functiontext">Invocations::get_token_check_to_do</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">));</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">")"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">OW</span><span class="plain"> = </span><span class="functiontext">Invocations::get_phrase_options</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">OW</span><span class="plain">))</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">" [0x%x %W]"</span><span class="plain">, </span><span class="functiontext">Invocations::get_phrase_options_bitmap</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">), </span><span class="identifier">OW</span><span class="plain">);</span>
|
|
<span class="identifier">kind_variable_declaration</span><span class="plain"> *</span><span class="identifier">kvd</span><span class="plain"> = </span><span class="identifier">ParseTree::get_kind_variable_declarations</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">);</span>
|
|
<span class="reserved">for</span><span class="plain"> (; </span><span class="identifier">kvd</span><span class="plain">; </span><span class="identifier">kvd</span><span class="plain">=</span><span class="identifier">kvd</span><span class="plain">-</span><span class="element">>next</span><span class="plain">) </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">" %c=$u"</span><span class="plain">, </span><span class="character">'A'</span><span class="plain">+</span><span class="identifier">kvd</span><span class="plain">-></span><span class="identifier">kv_number</span><span class="plain">-1, </span><span class="identifier">kvd</span><span class="plain">-></span><span class="identifier">kv_value</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::log is used in 1/cm (<a href="1-cm.html#SP5">§5</a>, <a href="1-cm.html#SP6_6">§6.6</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11"></a><b>§11. </b>Two important flags:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Invocations::mark_to_save_self</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">) {</span>
|
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="constant">save_self_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Invocations::is_marked_to_save_self</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">) {</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="constant">save_self_ANNOT</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Invocations::mark_unproven</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">) {</span>
|
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="constant">unproven_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Invocations::is_marked_unproven</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">) {</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="constant">unproven_ANNOT</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::mark_to_save_self is used in 14/ds2 (<a href="14-ds2.html#SP11_9_1_1_8">§11.9.1.1.8</a>).</p>
|
|
|
|
<p class="endnote">The function Invocations::is_marked_to_save_self is used in <a href="#SP10">§10</a>, 25/ci (<a href="25-ci.html#SP3">§3</a>).</p>
|
|
|
|
<p class="endnote">The function Invocations::mark_unproven is used in 14/ds2 (<a href="14-ds2.html#SP11_9_1_1_12">§11.9.1.1.12</a>).</p>
|
|
|
|
<p class="endnote">The function Invocations::is_marked_unproven is used in 25/ci (<a href="25-ci.html#SP3">§3</a>, <a href="25-ci.html#SP3_2_3_3">§3.2.3.3</a>, <a href="25-ci.html#SP3_2_3_5">§3.2.3.5</a>, <a href="25-ci.html#SP3_2_3_3_1_2">§3.2.3.3.1.2</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12"></a><b>§12. </b>The word range:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Invocations::set_word_range</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</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">inv</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to set word range of null inv"</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_text</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::set_word_range is used in 10/cap (<a href="10-cap.html#SP10">§10</a>, <a href="10-cap.html#SP11">§11</a>), 25/pi (<a href="25-pi.html#SP4">§4</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP13"></a><b>§13. </b>The say verb:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Invocations::set_verb_conjugation</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">,</span>
|
|
<span class="identifier">verb_conjugation</span><span class="plain"> *</span><span class="identifier">vc</span><span class="plain">, </span><span class="identifier">verb_conjugation</span><span class="plain"> *</span><span class="identifier">modal</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">neg</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inv</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to set VC of null inv"</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_say_verb</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">vc</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_modal_verb</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">modal</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="constant">say_verb_negated_ANNOT</span><span class="plain">, </span><span class="identifier">neg</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::set_verb_conjugation is used in 10/cap (<a href="10-cap.html#SP11">§11</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14"></a><b>§14. </b>The say adjective:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Invocations::set_adjectival_phrase</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">adjectival_phrase</span><span class="plain"> *</span><span class="identifier">aph</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inv</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to set ADJ of null inv"</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_say_adjective</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">aph</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::set_adjectival_phrase is used in 10/cap (<a href="10-cap.html#SP10">§10</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15"></a><b>§15. </b>The tokens. Recall that these are stored as a linked list; the following
|
|
creates a new entry structure.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Invocations::new_token</span><span class="plain">(</span><span class="identifier">node_type_t</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">it</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_token_check_to_do</span><span class="plain">(</span><span class="identifier">it</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_token_to_be_parsed_against</span><span class="plain">(</span><span class="identifier">it</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_kind_of_new_variable</span><span class="plain">(</span><span class="identifier">it</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">it</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::new_token is used in <a href="#SP16">§16</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP16"></a><b>§16. </b>However, we want to access it as if it were an array. (Speed is not too
|
|
vital here, and the list sizes are almost always lower than 3.) So:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Invocations::make_token</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">node_type_t</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">itl</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"><0) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to set token out of range"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain"> = </span><span class="functiontext">Invocations::new_token</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">);</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain">, </span><span class="identifier">k</span><span class="plain"> = 0; </span><span class="identifier">itl</span><span class="plain">; </span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>next</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">k</span><span class="plain"> == </span><span class="identifier">i</span><span class="plain">) {</span>
|
|
<span class="identifier">ParseTree::set_text</span><span class="plain">(</span><span class="identifier">itl</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_type</span><span class="plain">(</span><span class="identifier">itl</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_kind_required_by_context</span><span class="plain">(</span><span class="identifier">itl</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> = </span><span class="functiontext">Invocations::new_token</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Invocations::set_token_check_to_do</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">itl</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"><0) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to set token out of range"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain"> = </span><span class="functiontext">Invocations::new_token</span><span class="plain">(</span><span class="identifier">INVALID_NT</span><span class="plain">);</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain">, </span><span class="identifier">k</span><span class="plain"> = 0; </span><span class="identifier">itl</span><span class="plain">; </span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>next</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">k</span><span class="plain"> == </span><span class="identifier">i</span><span class="plain">) { </span><span class="identifier">ParseTree::set_token_check_to_do</span><span class="plain">(</span><span class="identifier">itl</span><span class="plain">, </span><span class="identifier">spec</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">itl</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> = </span><span class="functiontext">Invocations::new_token</span><span class="plain">(</span><span class="identifier">INVALID_NT</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Invocations::set_token_as_parsed</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">itl</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"><0) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to set token out of range"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain"> = </span><span class="functiontext">Invocations::new_token</span><span class="plain">(</span><span class="identifier">INVALID_NT</span><span class="plain">);</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain">, </span><span class="identifier">k</span><span class="plain"> = 0; </span><span class="identifier">itl</span><span class="plain">; </span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>next</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">k</span><span class="plain"> == </span><span class="identifier">i</span><span class="plain">) { </span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>down</span><span class="plain"> = </span><span class="identifier">spec</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">itl</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> = </span><span class="functiontext">Invocations::new_token</span><span class="plain">(</span><span class="identifier">INVALID_NT</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Invocations::set_token_to_be_parsed_against</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">itl</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"><0) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to set token out of range"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain"> = </span><span class="functiontext">Invocations::new_token</span><span class="plain">(</span><span class="identifier">INVALID_NT</span><span class="plain">);</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain">, </span><span class="identifier">k</span><span class="plain"> = 0; </span><span class="identifier">itl</span><span class="plain">; </span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>next</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">k</span><span class="plain"> == </span><span class="identifier">i</span><span class="plain">) { </span><span class="identifier">ParseTree::set_token_to_be_parsed_against</span><span class="plain">(</span><span class="identifier">itl</span><span class="plain">, </span><span class="identifier">spec</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">itl</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> = </span><span class="functiontext">Invocations::new_token</span><span class="plain">(</span><span class="identifier">INVALID_NT</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Invocations::set_token_variable_kind</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">itl</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"><0) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to set token out of range"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain"> = </span><span class="functiontext">Invocations::new_token</span><span class="plain">(</span><span class="identifier">INVALID_NT</span><span class="plain">);</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain">, </span><span class="identifier">k</span><span class="plain"> = 0; </span><span class="identifier">itl</span><span class="plain">; </span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>next</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">k</span><span class="plain"> == </span><span class="identifier">i</span><span class="plain">) { </span><span class="identifier">ParseTree::set_kind_of_new_variable</span><span class="plain">(</span><span class="identifier">itl</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">; }</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> = </span><span class="functiontext">Invocations::new_token</span><span class="plain">(</span><span class="identifier">INVALID_NT</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::make_token is used in 25/pi (<a href="25-pi.html#SP4_2">§4.2</a>).</p>
|
|
|
|
<p class="endnote">The function Invocations::set_token_check_to_do is used in 14/ds2 (<a href="14-ds2.html#SP11_9_1_1_3">§11.9.1.1.3</a>, <a href="14-ds2.html#SP11_9_1_1_3_1">§11.9.1.1.3.1</a>).</p>
|
|
|
|
<p class="endnote">The function Invocations::set_token_as_parsed is used in 14/ds2 (<a href="14-ds2.html#SP11_9_1_1_3_1_1">§11.9.1.1.3.1.1</a>), 25/pi (<a href="25-pi.html#SP4_2">§4.2</a>, <a href="25-pi.html#SP5">§5</a>).</p>
|
|
|
|
<p class="endnote">The function Invocations::set_token_to_be_parsed_against is used in 25/pi (<a href="25-pi.html#SP4_2">§4.2</a>).</p>
|
|
|
|
<p class="endnote">The function Invocations::set_token_variable_kind is used in 14/ds2 (<a href="14-ds2.html#SP11_9_1_1_3_1">§11.9.1.1.3.1</a>, <a href="14-ds2.html#SP14">§14</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP17"></a><b>§17. </b>And similarly for reading them:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Invocations::get_token</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">itl</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain">, </span><span class="identifier">k</span><span class="plain"> = 0; </span><span class="identifier">itl</span><span class="plain">; </span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>next</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">k</span><span class="plain"> == </span><span class="identifier">i</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">itl</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Invocations::get_token_check_to_do</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">itl</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain">, </span><span class="identifier">k</span><span class="plain"> = 0; </span><span class="identifier">itl</span><span class="plain">; </span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>next</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">k</span><span class="plain"> == </span><span class="identifier">i</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::get_token_check_to_do</span><span class="plain">(</span><span class="identifier">itl</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Invocations::get_token_as_parsed</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">itl</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain">, </span><span class="identifier">k</span><span class="plain"> = 0; </span><span class="identifier">itl</span><span class="plain">; </span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>next</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">k</span><span class="plain"> == </span><span class="identifier">i</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>down</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Invocations::get_token_to_be_parsed_against</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">itl</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain">, </span><span class="identifier">k</span><span class="plain"> = 0; </span><span class="identifier">itl</span><span class="plain">; </span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>next</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">k</span><span class="plain"> == </span><span class="identifier">i</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::get_token_to_be_parsed_against</span><span class="plain">(</span><span class="identifier">itl</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">Invocations::get_token_variable_kind</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">itl</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain">, </span><span class="identifier">k</span><span class="plain"> = 0; </span><span class="identifier">itl</span><span class="plain">; </span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>next</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">k</span><span class="plain"> == </span><span class="identifier">i</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::get_kind_of_new_variable</span><span class="plain">(</span><span class="identifier">itl</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Invocations::get_no_tokens</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">itl</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">inv</span><span class="plain">-</span><span class="element">>down</span><span class="plain">, </span><span class="identifier">k</span><span class="plain"> = 0; </span><span class="identifier">itl</span><span class="plain">; </span><span class="identifier">itl</span><span class="plain"> = </span><span class="identifier">itl</span><span class="plain">-</span><span class="element">>next</span><span class="plain">, </span><span class="identifier">k</span><span class="plain">++) ;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::get_token is used in 14/ds2 (<a href="14-ds2.html#SP11_9_1_1_2_2_1">§11.9.1.1.2.2.1</a>, <a href="14-ds2.html#SP11_9_1_1_3_1">§11.9.1.1.3.1</a>, <a href="14-ds2.html#SP15_4">§15.4</a>).</p>
|
|
|
|
<p class="endnote">The function Invocations::get_token_check_to_do is used in <a href="#SP10">§10</a>, 25/ci (<a href="25-ci.html#SP3_2_3_5">§3.2.3.5</a>, <a href="25-ci.html#SP3_2_3_3_1_2">§3.2.3.3.1.2</a>, <a href="25-ci.html#SP3_2_3_4_1_1">§3.2.3.4.1.1</a>, <a href="25-ci.html#SP3_2_3_3_1_2_1">§3.2.3.3.1.2.1</a>).</p>
|
|
|
|
<p class="endnote">The function Invocations::get_token_as_parsed is used in <a href="#SP6">§6</a>, <a href="#SP10">§10</a>, <a href="#SP28">§28</a>, <a href="#SP31">§31</a>, 10/cap (<a href="10-cap.html#SP12_1">§12.1</a>), 14/ds2 (<a href="14-ds2.html#SP10_1_1_3_1_2">§10.1.1.3.1.2</a>, <a href="14-ds2.html#SP11_9_1_1_2_1">§11.9.1.1.2.1</a>, <a href="14-ds2.html#SP11_9_1_1_3_1_1">§11.9.1.1.3.1.1</a>, <a href="14-ds2.html#SP11_9_1_1_4">§11.9.1.1.4</a>, <a href="14-ds2.html#SP11_9_1_1_5">§11.9.1.1.5</a>, <a href="14-ds2.html#SP11_9_1_1_8">§11.9.1.1.8</a>, <a href="14-ds2.html#SP14_1">§14.1</a>), 22/dptd (<a href="22-dptd.html#SP3_1_2">§3.1.2</a>), 25/pi (<a href="25-pi.html#SP5">§5</a>), 25/ci (<a href="25-ci.html#SP3_1_1_1">§3.1.1.1</a>, <a href="25-ci.html#SP3_2_3_1_1">§3.2.3.1.1</a>).</p>
|
|
|
|
<p class="endnote">The function Invocations::get_token_to_be_parsed_against is used in <a href="#SP28">§28</a>, 25/pi (<a href="25-pi.html#SP5">§5</a>).</p>
|
|
|
|
<p class="endnote">The function Invocations::get_token_variable_kind is used in 14/ds2 (<a href="14-ds2.html#SP14">§14</a>), 25/cii (<a href="25-cii.html#SP1_2">§1.2</a>).</p>
|
|
|
|
<p class="endnote">The function Invocations::get_no_tokens is used in <a href="#SP6">§6</a>, <a href="#SP10">§10</a>, <a href="#SP28">§28</a>, <a href="#SP31">§31</a>, 14/ds2 (<a href="14-ds2.html#SP10_1_1_3_1_2">§10.1.1.3.1.2</a>, <a href="14-ds2.html#SP11_9_2_3_1">§11.9.2.3.1</a>, <a href="14-ds2.html#SP11_9_1_1_3">§11.9.1.1.3</a>, <a href="14-ds2.html#SP11_9_1_1_4">§11.9.1.1.4</a>, <a href="14-ds2.html#SP11_9_1_1_8">§11.9.1.1.8</a>, <a href="14-ds2.html#SP14">§14</a>, <a href="14-ds2.html#SP15_4">§15.4</a>), 25/pi (<a href="25-pi.html#SP5">§5</a>), 25/ci (<a href="25-ci.html#SP3_2">§3.2</a>, <a href="25-ci.html#SP3_2_3_5">§3.2.3.5</a>, <a href="25-ci.html#SP3_2_3_3_1_2">§3.2.3.3.1.2</a>, <a href="25-ci.html#SP3_2_3_4_1_1">§3.2.3.4.1.1</a>, <a href="25-ci.html#SP3_2_3_3_1_2_1">§3.2.3.3.1.2.1</a>), 25/cii (<a href="25-cii.html#SP1_2">§1.2</a>, <a href="25-cii.html#SP1_4">§1.4</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP18"></a><b>§18. </b>The following routine might become more interesting if we ever allowed
|
|
variable-argument phrases like C's <code class="display"><span class="extract">printf</span></code>.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Invocations::get_no_tokens_needed</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inv</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to read NTI of null inv"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_phrase_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Phrases::TypeData::get_no_tokens</span><span class="plain">(</span>
|
|
<span class="plain">&(</span><span class="identifier">ParseTree::get_phrase_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">)-</span><span class="element">>type_data</span><span class="plain">));</span>
|
|
<span class="reserved">return</span><span class="plain"> 0;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::get_no_tokens_needed is used in 25/ci (<a href="25-ci.html#SP3_1_1_1">§3.1.1.1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP19"></a><b>§19. </b>The phrase options invoked:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Invocations::set_phrase_options</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</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">invocation_options</span><span class="plain"> *</span><span class="identifier">invo</span><span class="plain"> = </span><span class="identifier">ParseTree::get_phrase_options_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">invo</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<span class="identifier">invo</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">invocation_options</span><span class="plain">);</span>
|
|
<span class="identifier">invo</span><span class="plain">-</span><span class="element">>options</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">ParseTree::set_phrase_options_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">invo</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">invo</span><span class="plain">-</span><span class="element">>options_invoked_text</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::set_phrase_options is used in 25/pi (<a href="25-pi.html#SP4">§4</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20"></a><b>§20. </b>Reading the word range:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="functiontext">Invocations::get_phrase_options</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">) {</span>
|
|
<span class="reserved">invocation_options</span><span class="plain"> *</span><span class="identifier">invo</span><span class="plain"> = </span><span class="identifier">ParseTree::get_phrase_options_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">invo</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">invo</span><span class="plain">-</span><span class="element">>options_invoked_text</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::get_phrase_options is used in <a href="#SP10">§10</a>, 22/po (<a href="22-po.html#SP10">§10</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP21"></a><b>§21. </b>The functional part is of course the bitmap, which we read and write thus.
|
|
When no options are set, the bitmap is always 0.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Invocations::get_phrase_options_bitmap</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">) {</span>
|
|
<span class="reserved">invocation_options</span><span class="plain"> *</span><span class="identifier">invo</span><span class="plain"> = </span><span class="identifier">ParseTree::get_phrase_options_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">invo</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> 0;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">invo</span><span class="plain">-</span><span class="element">>options</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Invocations::set_phrase_options_bitmap</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">further_bits</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">further_bits</span><span class="plain"> == 0) </span><span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="reserved">invocation_options</span><span class="plain"> *</span><span class="identifier">invo</span><span class="plain"> = </span><span class="identifier">ParseTree::get_phrase_options_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">invo</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<span class="identifier">invo</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">invocation_options</span><span class="plain">);</span>
|
|
<span class="identifier">invo</span><span class="plain">-</span><span class="element">>options_invoked_text</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
|
|
<span class="identifier">invo</span><span class="plain">-</span><span class="element">>options</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">ParseTree::set_phrase_options_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">invo</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">invo</span><span class="plain">-</span><span class="element">>options</span><span class="plain"> |= </span><span class="identifier">further_bits</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::get_phrase_options_bitmap is used in <a href="#SP10">§10</a>, 25/ciac (<a href="25-ciac.html#SP1">§1</a>), 25/cii (<a href="25-cii.html#SP3_1">§3.1</a>).</p>
|
|
|
|
<p class="endnote">The function Invocations::set_phrase_options_bitmap is used in 22/po (<a href="22-po.html#SP10">§10</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP22"></a><b>§22. The implied newlines rule. </b>This is applied only when the invocation passes the following stringent test:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Invocations::implies_newline</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (!(</span><span class="functiontext">Phrases::TypeData::is_a_say_phrase</span><span class="plain">(</span><span class="identifier">ParseTree::get_phrase_invoked</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">)))) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (!(</span><span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">IMPLY_NEWLINES_IN_SAY_CMODE</span><span class="plain">))) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::implies_newline is used in 25/ci (<a href="25-ci.html#SP4_2">§4.2</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP23"></a><b>§23. Invocation lists. </b>An invocation list is a chain of alternatives in the parse tree.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Invocations::add_to_list</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">invl</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">invl</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">inv</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="identifier">invl</span><span class="plain">;</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">p</span><span class="plain">-></span><span class="identifier">next_alternative</span><span class="plain">) </span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-></span><span class="identifier">next_alternative</span><span class="plain">;</span>
|
|
<span class="identifier">p</span><span class="plain">-></span><span class="identifier">next_alternative</span><span class="plain"> = </span><span class="identifier">inv</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">invl</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::add_to_list is used in 10/cap (<a href="10-cap.html#SP10">§10</a>, <a href="10-cap.html#SP11">§11</a>, <a href="10-cap.html#SP12_1">§12.1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24"></a><b>§24. </b>That completes the construction routines. Now, reading the length and first item:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Invocations::length_of_list</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">invl</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">L</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">for</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="identifier">invl</span><span class="plain">; </span><span class="identifier">p</span><span class="plain">; </span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">p</span><span class="plain">-></span><span class="identifier">next_alternative</span><span class="plain">) </span><span class="identifier">L</span><span class="plain">++;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">L</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::length_of_list is used in <a href="#SP26">§26</a>, <a href="#SP30">§30</a>, <a href="#SP31">§31</a>, 10/cap (<a href="10-cap.html#SP12">§12</a>), 14/ds2 (<a href="14-ds2.html#SP11_9_2_4">§11.9.2.4</a>), 25/ci (<a href="25-ci.html#SP3">§3</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP25"></a><b>§25. </b>That completes the construction routines. Now, reading the length and first item:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Invocations::first_in_list</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">invl</span><span class="plain">) {</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">invl</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::first_in_list is used in 25/ci (<a href="25-ci.html#SP3">§3</a>, <a href="25-ci.html#SP3_1_1_1">§3.1.1.1</a>, <a href="25-ci.html#SP3_2">§3.2</a>, <a href="25-ci.html#SP3_2_3_1_1">§3.2.3.1.1</a>), 25/cp (<a href="25-cp.html#SP5_2_1">§5.2.1</a>, <a href="25-cp.html#SP6">§6</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP26"></a><b>§26. </b>Sorting the invocations in a list is much more important than it may
|
|
at first appear, since the sorted order is a precedence order for parsing
|
|
purposes: that is, the earliest type-checked match is the one accepted,
|
|
so that being sorted up front gives a possible interpretation of a phrase
|
|
priority over those sorted to the back.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">invocation_sort_block</span><span class="plain"> *</span><span class="identifier">pigeon_holes</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="identifier">number_of_pigeon_holes</span><span class="plain"> = 0;</span>
|
|
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Invocations::sort_list</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">invl</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">L</span><span class="plain"> = </span><span class="functiontext">Invocations::length_of_list</span><span class="plain">(</span><span class="identifier">invl</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">L</span><span class="plain"> > 0) {</span>
|
|
<<span class="cwebmacro">Make sure there are at least L pigeonholes available for sorting into</span> <span class="cwebmacronumber">26.1</span>><span class="plain">;</span>
|
|
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">ent</span><span class="plain">=</span><span class="identifier">invl</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; (</span><span class="identifier">i</span><span class="plain"><</span><span class="identifier">L</span><span class="plain">) && (</span><span class="identifier">ent</span><span class="plain">); </span><span class="identifier">i</span><span class="plain">++, </span><span class="identifier">ent</span><span class="plain">=</span><span class="identifier">ent</span><span class="plain">-></span><span class="identifier">next_alternative</span><span class="plain">) {</span>
|
|
<span class="identifier">pigeon_holes</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.inv_data</span><span class="plain"> = </span><span class="identifier">ent</span><span class="plain">;</span>
|
|
<span class="identifier">pigeon_holes</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.unsorted_position</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">qsort</span><span class="plain">(</span><span class="identifier">pigeon_holes</span><span class="plain">, (</span><span class="identifier">size_t</span><span class="plain">) </span><span class="identifier">L</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">invocation_sort_block</span><span class="plain">), </span><span class="functiontext">Invocations::comparison</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">tail</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">invl</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"><</span><span class="identifier">L</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">i_n</span><span class="plain"> = </span><span class="identifier">pigeon_holes</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.inv_data</span><span class="plain">; </span><span class="identifier">i_n</span><span class="plain">-></span><span class="identifier">next_alternative</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tail</span><span class="plain">) </span><span class="identifier">tail</span><span class="plain">-></span><span class="identifier">next_alternative</span><span class="plain"> = </span><span class="identifier">i_n</span><span class="plain">; </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">invl</span><span class="plain"> = </span><span class="identifier">i_n</span><span class="plain">;</span>
|
|
<span class="identifier">tail</span><span class="plain"> = </span><span class="identifier">i_n</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">invl</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::sort_list is used in 10/cap (<a href="10-cap.html#SP12">§12</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP26_1"></a><b>§26.1. </b>We allocate 1000 pigeonholes in the first instance, then double each time
|
|
we run out. (We will quite likely never run out, as 1000 is plenty. But we
|
|
want to avoid all possible arbitrary limits.)
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Make sure there are at least L pigeonholes available for sorting into</span> <span class="cwebmacronumber">26.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">L</span><span class="plain"> > </span><span class="identifier">number_of_pigeon_holes</span><span class="plain">) {</span>
|
|
<span class="identifier">number_of_pigeon_holes</span><span class="plain"> = 2*</span><span class="identifier">L</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">number_of_pigeon_holes</span><span class="plain"> < 1000)</span>
|
|
<span class="identifier">number_of_pigeon_holes</span><span class="plain"> = 1000;</span>
|
|
<span class="identifier">pigeon_holes</span><span class="plain"> =</span>
|
|
<span class="identifier">Memory::I7_calloc</span><span class="plain">(</span><span class="identifier">number_of_pigeon_holes</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="reserved">invocation_sort_block</span><span class="plain">), </span><span class="constant">INV_LIST_MREASON</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP26">§26</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP27"></a><b>§27. </b>So much for the mechanism. The sorting order is specified by the following.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<ul class="items"><li>(a) We first sort by logical priority. This is quite an expensive test, and
|
|
therefore we effectively cache it by referring to the "sequence count" of the
|
|
phrases instead: that is, to the numbered position in the logical priority
|
|
ordering of the phrases. It's very important that each phrase has a unique
|
|
sequence count value, because the C library sorting function <code class="display"><span class="extract">qsort</span></code> is
|
|
unstable, so that it might arbitrarily rearrange invocations which happened to
|
|
have equal sequence counts — a problem because Inform's behaviour in terms of
|
|
logical priority must be predictable.
|
|
</li></ul>
|
|
<ul class="items"><li>(b) Our final sorting is on the original parsing sequence order, which we
|
|
preserve in cases where two different invocations both invoke the same phrase
|
|
(as for instance where "two minutes before two minutes before midnight" can be
|
|
invoked either as "two minutes before (two minutes before midnight)" or "(two
|
|
minutes before two minutes) before midnight"). The result is that the comparison
|
|
function can return 0 only when the invocations are actually equal, so that the
|
|
instability of the sorting algorithm does not produce any ambiguity in how
|
|
Inform prioritises phrases.
|
|
</li></ul>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Invocations::comparison</span><span class="plain">(</span><span class="reserved">const</span><span class="plain"> </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">i1</span><span class="plain">, </span><span class="reserved">const</span><span class="plain"> </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">i2</span><span class="plain">) {</span>
|
|
<span class="reserved">invocation_sort_block</span><span class="plain"> *</span><span class="identifier">inv1</span><span class="plain"> = (</span><span class="reserved">invocation_sort_block</span><span class="plain"> *) </span><span class="identifier">i1</span><span class="plain">;</span>
|
|
<span class="reserved">invocation_sort_block</span><span class="plain"> *</span><span class="identifier">inv2</span><span class="plain"> = (</span><span class="reserved">invocation_sort_block</span><span class="plain"> *) </span><span class="identifier">i2</span><span class="plain">;</span>
|
|
|
|
<span class="comment">(a) sort by logical priority</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">delta</span><span class="plain"> =</span>
|
|
<span class="functiontext">Routines::ToPhrases::sequence_count</span><span class="plain">(</span><span class="identifier">ParseTree::get_phrase_invoked</span><span class="plain">(</span><span class="identifier">inv1</span><span class="plain">-</span><span class="element">>inv_data</span><span class="plain">)) -</span>
|
|
<span class="functiontext">Routines::ToPhrases::sequence_count</span><span class="plain">(</span><span class="identifier">ParseTree::get_phrase_invoked</span><span class="plain">(</span><span class="identifier">inv2</span><span class="plain">-</span><span class="element">>inv_data</span><span class="plain">));</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">delta</span><span class="plain"> != 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">delta</span><span class="plain">;</span>
|
|
|
|
<span class="comment">(b) sort by creation sequence</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">inv1</span><span class="plain">-</span><span class="element">>unsorted_position</span><span class="plain"> - </span><span class="identifier">inv2</span><span class="plain">-</span><span class="element">>unsorted_position</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::comparison is used in <a href="#SP26">§26</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP28"></a><b>§28. </b>By contrast, this compares two invocations by their contents:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Invocations::eq</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv1</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv2</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">inv1</span><span class="plain">) && (</span><span class="identifier">inv2</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">inv1</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) && (</span><span class="identifier">inv2</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">inv1</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_phrase_invoked</span><span class="plain">(</span><span class="identifier">inv1</span><span class="plain">) != </span><span class="identifier">ParseTree::get_phrase_invoked</span><span class="plain">(</span><span class="identifier">inv2</span><span class="plain">))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Invocations::get_no_tokens</span><span class="plain">(</span><span class="identifier">inv1</span><span class="plain">) != </span><span class="functiontext">Invocations::get_no_tokens</span><span class="plain">(</span><span class="identifier">inv2</span><span class="plain">))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"><</span><span class="functiontext">Invocations::get_no_tokens</span><span class="plain">(</span><span class="identifier">inv1</span><span class="plain">); </span><span class="identifier">i</span><span class="plain">++) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">m1</span><span class="plain"> = </span><span class="functiontext">Invocations::get_token_to_be_parsed_against</span><span class="plain">(</span><span class="identifier">inv1</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">);</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">m2</span><span class="plain"> = </span><span class="functiontext">Invocations::get_token_to_be_parsed_against</span><span class="plain">(</span><span class="identifier">inv2</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">m1</span><span class="plain">) != </span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">m2</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">v1</span><span class="plain"> = </span><span class="functiontext">Invocations::get_token_as_parsed</span><span class="plain">(</span><span class="identifier">inv1</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">);</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">v2</span><span class="plain"> = </span><span class="functiontext">Invocations::get_token_as_parsed</span><span class="plain">(</span><span class="identifier">inv2</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">v1</span><span class="plain">) != </span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">v2</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (!</span><span class="identifier">Wordings::eq</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">v1</span><span class="plain">), </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">v2</span><span class="plain">))) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</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 Invocations::eq appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP29"></a><b>§29. </b>The following macro abstracts the process of looping through the invocations
|
|
in a list:
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="identifier">LOOP_THROUGH_INVOCATION_LIST</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">invl</span><span class="plain">)</span>
|
|
<span class="identifier">LOOP_THROUGH_ALTERNATIVES</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">invl</span><span class="plain">)</span>
|
|
</pre>
|
|
<p class="inwebparagraph"><a id="SP30"></a><b>§30. </b>The log routines demonstrate its use:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Invocations::log_list</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">invl</span><span class="plain">) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">;</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Invocation list (%d):\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="functiontext">Invocations::length_of_list</span><span class="plain">(</span><span class="identifier">invl</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">LOOP_THROUGH_INVOCATION_LIST</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">invl</span><span class="plain">)</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"P%d: $e\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">n</span><span class="plain">++, </span><span class="identifier">inv</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Invocations::log_list is used in 1/cm (<a href="1-cm.html#SP5">§5</a>, <a href="1-cm.html#SP6_6">§6.6</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP31"></a><b>§31. </b>A more detailed version, which hierarchically shows the lists inside the
|
|
invocations listed:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Invocations::log_list_in_detail</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">invl</span><span class="plain">) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">;</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Invocation list in detail (%d):\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="functiontext">Invocations::length_of_list</span><span class="plain">(</span><span class="identifier">invl</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">LOOP_THROUGH_INVOCATION_LIST</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">invl</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">;</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"P%d: $e\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">n</span><span class="plain">++, </span><span class="identifier">inv</span><span class="plain">);</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain"><</span><span class="functiontext">Invocations::get_no_tokens</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">); </span><span class="identifier">j</span><span class="plain">++) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">tok</span><span class="plain"> = </span><span class="functiontext">Invocations::get_token_as_parsed</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">);</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">" %d: $P\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">j</span><span class="plain">, </span><span class="identifier">tok</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">tok</span><span class="plain">-</span><span class="element">>down</span><span class="plain">, </span><span class="constant">INVOCATION_LIST_NT</span><span class="plain">)) {</span>
|
|
<span class="identifier">LOG_INDENT</span><span class="plain">;</span>
|
|
<span class="functiontext">Invocations::log_list_in_detail</span><span class="plain">(</span><span class="identifier">tok</span><span class="plain">-</span><span class="element">>down</span><span class="plain">-</span><span class="element">>down</span><span class="plain">);</span>
|
|
<span class="identifier">LOG_OUTDENT</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 Invocations::log_list_in_detail appears nowhere else.</p>
|
|
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><i>(This section begins Chapter 25: Compilation.)</i></li><li><a href="25-pi.html">Continue with 'Parse Invocations'</a></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</body>
|
|
</html>
|
|
|