1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-06-02 16:38:08 +03:00
inform7/docs/core-module/18-lc.html
2020-03-11 00:21:09 +00:00

506 lines
55 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>17/rs</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 '18/lc' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">core</a></li><li><a href="index.html#18">Chapter 18: List Data</a></li><li><b>List Constants</b></li></ul><p class="purpose">In this section we compile I6 arrays for constant lists arising from braced literals.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Every literal list in the source text, such as
</p>
<blockquote>
<p>{2, 12, 13}</p>
</blockquote>
<p class="inwebparagraph">is parsed into an instance of the following structure. There are two rules:
</p>
<ul class="items"><li>(1) every LL structure represents a syntactically well-formed list, in which
braces and commas balance; and
</li><li>(2) there can be at most one LL structure at any word position.
</li></ul>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">literal_list</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">unbraced_text</span><span class="plain">; </span> <span class="comment">position in the source of quoted text, excluding braces</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">list_text</span><span class="plain">; </span> <span class="comment">used for problem reporting only</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">listed_within_code</span><span class="plain">; </span> <span class="comment">appears within a phrase, rather than (say) a table entry?</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">entry_kind</span><span class="plain">; </span> <span class="comment">i.e., of the entries, not the list</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">kinds_known_to_be_inconsistent</span><span class="plain">; </span> <span class="comment">problem(s) thrown when parsing these</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">llist_entry</span><span class="plain"> *</span><span class="identifier">first_llist_entry</span><span class="plain">; </span> <span class="comment">linked list of contents</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">ll_package</span><span class="plain">; </span> <span class="comment">which will be the enclosure for...</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">ll_iname</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">list_compiled</span><span class="plain">; </span> <span class="comment">lists are compiled at several different points: has this one been done?</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">literal_list</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure literal_list is accessed in 27/ei and here.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>I believe "llath" is the Welsh word for "mile": not sure about "llist".
</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">llist_entry</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">llist_entry_value</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">llist_entry</span><span class="plain"> *</span><span class="identifier">next_llist_entry</span><span class="plain">;</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">llist_entry</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure llist_entry is private to this section.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>One of the few pieces of Inform syntax which wouldn't look out of place in
a conventional programming language; list constants are series of values,
separated by commas, and enclosed in braces. The empty list <code class="display"><span class="extract">{ }</span></code> is valid
as a constant.
</p>
<p class="inwebparagraph">The values are in fact eventually required to be constants, and to have
mutually consistent kinds, but that checking is done after parsing, so it
isn't expressed in this grammar.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">literal</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">&gt; ::=</span>
<span class="plain">\{ \} | ==&gt; </span><span class="functiontext">Rvalues::from_wording_of_list</span><span class="plain">(</span><span class="functiontext">Lists::kind_of_ll</span><span class="plain">(</span><span class="functiontext">Lists::empty_literal_list</span><span class="plain">(</span><span class="identifier">Wordings::last_word</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)), </span><span class="identifier">FALSE</span><span class="plain">), </span><span class="identifier">W</span><span class="plain">)</span>
<span class="plain">\{ &lt;</span><span class="identifier">literal</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">-</span><span class="identifier">contents</span><span class="plain">&gt; \} ==&gt; </span><span class="functiontext">Rvalues::from_wording_of_list</span><span class="plain">(</span><span class="functiontext">Lists::kind_of_ll</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[1], </span><span class="identifier">FALSE</span><span class="plain">), </span><span class="identifier">W</span><span class="plain">)</span>
<span class="plain">&lt;</span><span class="identifier">literal</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">-</span><span class="identifier">contents</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">literal</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">-</span><span class="identifier">entry</span><span class="plain">&gt; , &lt;</span><span class="identifier">literal</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">-</span><span class="identifier">contents</span><span class="plain">&gt; | ==&gt; 0; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="functiontext">Lists::add_to_ll</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[1], </span><span class="identifier">RP</span><span class="plain">[2], </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">[1])</span>
<span class="plain">&lt;</span><span class="identifier">literal</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">-</span><span class="identifier">entry</span><span class="plain">&gt; ==&gt; 0; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="functiontext">Lists::add_to_ll</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[1], </span><span class="functiontext">Lists::empty_literal_list</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">), </span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">[1])</span>
<span class="plain">&lt;</span><span class="identifier">literal</span><span class="plain">-</span><span class="identifier">list</span><span class="plain">-</span><span class="identifier">entry</span><span class="plain">&gt; ::=</span>
<span class="plain">&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">&gt; | ==&gt; </span><span class="identifier">FALSE</span><span class="plain">; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">...... ==&gt; </span><span class="identifier">TRUE</span><span class="plain">; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="functiontext">Specifications::new_UNKNOWN</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>The grammar above builds our list structures from the bottom up. They begin
with a call to:
</p>
<pre class="display">
<span class="reserved">literal_list</span><span class="plain"> *</span><span class="functiontext">Lists::empty_literal_list</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">literal_list</span><span class="plain"> *</span><span class="identifier">ll</span><span class="plain"> = </span><span class="functiontext">Lists::find_list_at</span><span class="plain">(</span><span class="identifier">Wordings::first_wn</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">ll</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">ll</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">literal_list</span><span class="plain">);</span>
<span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;list_compiled</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;unbraced_text</span><span class="plain"> = </span><span class="identifier">W</span><span class="plain">; </span><span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;entry_kind</span><span class="plain"> = </span><span class="identifier">K_value</span><span class="plain">;</span>
<span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;listed_within_code</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;kinds_known_to_be_inconsistent</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;ll_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;first_llist_entry</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;list_text</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;ll_package</span><span class="plain"> = </span><span class="functiontext">Emit::current_enclosure</span><span class="plain">();</span>
<span class="functiontext">Kinds::RunTime::ensure_basic_heap_present</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ll</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Lists::empty_literal_list is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>Parsing is quadratic in the number of constant lists in the source text,
which is in principle a bad thing, but in practice the following causes no
speed problems even on large-scale tests. If it becomes a problem, we can
easily trade the time spent here for memory, by attaching a pointer to
each word in the source text, or for complexity, by constructing some kind
of binary search tree.
</p>
<pre class="display">
<span class="reserved">literal_list</span><span class="plain"> *</span><span class="functiontext">Lists::find_list_at</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">incipit</span><span class="plain">) {</span>
<span class="reserved">literal_list</span><span class="plain"> *</span><span class="identifier">ll</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ll</span><span class="plain">, </span><span class="reserved">literal_list</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;unbraced_text</span><span class="plain">) == </span><span class="identifier">incipit</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ll</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Lists::find_list_at is used in <a href="#SP5">&#167;5</a>, <a href="#SP7">&#167;7</a>, <a href="#SP9">&#167;9</a>, <a href="#SP11">&#167;11</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>Note that the entry kind is initially unknown, and it's not even decided
for sure when we add the first entry. Here's how each entry is added,
recursing right to left (i.e., reversing the direction of reading):
</p>
<pre class="display">
<span class="reserved">literal_list</span><span class="plain"> *</span><span class="functiontext">Lists::add_to_ll</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">literal_list</span><span class="plain"> *</span><span class="identifier">ll</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">int</span><span class="plain"> </span><span class="identifier">bad</span><span class="plain">) {</span>
<span class="reserved">llist_entry</span><span class="plain"> *</span><span class="identifier">lle</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">llist_entry</span><span class="plain">);</span>
<span class="identifier">lle</span><span class="plain">-</span><span class="element">&gt;next_llist_entry</span><span class="plain"> = </span><span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;first_llist_entry</span><span class="plain">;</span>
<span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;first_llist_entry</span><span class="plain"> = </span><span class="identifier">lle</span><span class="plain">;</span>
<span class="identifier">lle</span><span class="plain">-</span><span class="element">&gt;llist_entry_value</span><span class="plain"> = </span><span class="identifier">spec</span><span class="plain">;</span>
<span class="reserved">literal_list</span><span class="plain"> *</span><span class="identifier">ll2</span><span class="plain"> = </span><span class="functiontext">Lists::find_list_at</span><span class="plain">(</span><span class="identifier">Wordings::first_wn</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">ll2</span><span class="plain">) </span><span class="identifier">ll</span><span class="plain"> = </span><span class="identifier">ll2</span><span class="plain">;</span>
<span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;unbraced_text</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">bad</span><span class="plain">) </span><span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;kinds_known_to_be_inconsistent</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ll</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Lists::add_to_ll is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>With all the entries in place, we now have to reconcile their kinds, if
that's possible. Problems are only issued on request, and with the current
sentence cut down to just the list itself &mdash; since otherwise we might be
printing out an entire huge table to report a problem in a single entry
which happens to be a malformed list.
</p>
<pre class="display">
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">Lists::kind_of_ll</span><span class="plain">(</span><span class="reserved">literal_list</span><span class="plain"> *</span><span class="identifier">ll</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">issue_problems</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">cs</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">issue_problems</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;list_text</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
<span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;list_text</span><span class="plain"> = </span><span class="identifier">NounPhrases::new_raw</span><span class="plain">(</span><span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;unbraced_text</span><span class="plain">);</span>
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;list_text</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="identifier">K_value</span><span class="plain">;</span>
<span class="reserved">llist_entry</span><span class="plain"> *</span><span class="identifier">lle</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lle</span><span class="plain"> = </span><span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;first_llist_entry</span><span class="plain">; </span><span class="identifier">lle</span><span class="plain">; </span><span class="identifier">lle</span><span class="plain"> = </span><span class="identifier">lle</span><span class="plain">-</span><span class="element">&gt;next_llist_entry</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="identifier">lle</span><span class="plain">-</span><span class="element">&gt;llist_entry_value</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">spec</span><span class="plain">, </span><span class="constant">UNKNOWN_NT</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Conditions::is_TEST_ACTION</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">))</span>
<span class="functiontext">Dash::check_value_silently</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">K_stored_action</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="functiontext">Dash::check_value_silently</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">spec</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::substitute_constants</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">E</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Work out the entry kind E</span> <span class="cwebmacronumber">8.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">)) </span><span class="identifier">K</span><span class="plain"> = </span><span class="identifier">E</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Revise K in the light of E</span> <span class="cwebmacronumber">8.2</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;kinds_known_to_be_inconsistent</span><span class="plain">) </span><span class="identifier">K</span><span class="plain"> = </span><span class="identifier">K_value</span><span class="plain">;</span>
<span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;entry_kind</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">;</span>
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">cs</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Kinds::unary_construction</span><span class="plain">(</span><span class="identifier">CON_list_of</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 Lists::kind_of_ll is used in <a href="#SP4">&#167;4</a>, <a href="#SP9">&#167;9</a>, <a href="#SP10">&#167;10</a>, <a href="#SP11">&#167;11</a>, <a href="#SP12">&#167;12</a>, <a href="#SP12_1">&#167;12.1</a>.</p>
<p class="inwebparagraph"><a id="SP8_1"></a><b>&#167;8.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Work out the entry kind E</span> <span class="cwebmacronumber">8.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">UNKNOWN_NT</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">issue_problems</span><span class="plain">) </span>&lt;<span class="cwebmacro">Issue a bad list entry problem</span> <span class="cwebmacronumber">8.1.1</span>&gt;<span class="plain">;</span>
<span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;kinds_known_to_be_inconsistent</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">E</span><span class="plain"> = </span><span class="identifier">K</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::is</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">CONSTANT_NT</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Lvalues::is_constant_NONLOCAL_VARIABLE</span><span class="plain">(</span><span class="identifier">spec</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">issue_problems</span><span class="plain">) </span>&lt;<span class="cwebmacro">Issue a nonconstant list entry problem</span> <span class="cwebmacronumber">8.1.2</span>&gt;<span class="plain">;</span>
<span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;kinds_known_to_be_inconsistent</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">E</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">E</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">E</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">issue_problems</span><span class="plain">) </span>&lt;<span class="cwebmacro">Issue a bad list entry problem</span> <span class="cwebmacronumber">8.1.1</span>&gt;<span class="plain">;</span>
<span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;kinds_known_to_be_inconsistent</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8">&#167;8</a>.</p>
<p class="inwebparagraph"><a id="SP8_2"></a><b>&#167;8.2. </b>The following broadens K to include E, if necessary, but never narrows K.
Thus a list containing a person, a woman and a door will see K become
successively "person", "person" (E being narrower), then "thing" (E being
incomparable, and "thing" being the max of "person" and "door").
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Revise K in the light of E</span> <span class="cwebmacronumber">8.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">previous_K</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">;</span>
<span class="identifier">K</span><span class="plain"> = </span><span class="identifier">Kinds::Compare::max</span><span class="plain">(</span><span class="identifier">E</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">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">issue_problems</span><span class="plain">) </span>&lt;<span class="cwebmacro">Issue a list entry kind mismatch problem</span> <span class="cwebmacronumber">8.2.1</span>&gt;<span class="plain">;</span>
<span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;kinds_known_to_be_inconsistent</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8">&#167;8</a>.</p>
<p class="inwebparagraph"><a id="SP8_1_1"></a><b>&#167;8.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a bad list entry problem</span> <span class="cwebmacronumber">8.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_BadConstantListEntry</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The constant list %1 contains an entry '%2' which isn't any "</span>
<span class="string">"form of constant I'm able to read."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"%PNote that lists have to be written with spaces after commas, "</span>
<span class="string">"so I like '{2, 4}' but not '{2,4}', for instance."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8_1">&#167;8.1</a> (twice).</p>
<p class="inwebparagraph"><a id="SP8_1_2"></a><b>&#167;8.1.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a nonconstant list entry problem</span> <span class="cwebmacronumber">8.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">));</span>
<span class="functiontext">Problems::quote_spec</span><span class="plain">(3, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_NonconstantConstantListEntry</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The constant list %1 contains an entry '%2' which does make sense, "</span>
<span class="string">"but isn't a constant (it's %3). Only constants can appear as entries in "</span>
<span class="string">"constant lists, i.e., in lists written in braces '{' and '}'."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8_1">&#167;8.1</a>.</p>
<p class="inwebparagraph"><a id="SP8_2_1"></a><b>&#167;8.2.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a list entry kind mismatch problem</span> <span class="cwebmacronumber">8.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">));</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(3, </span><span class="identifier">E</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(4, </span><span class="identifier">previous_K</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_IncompatibleConstantListEntry</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"The constant list %1 contains an entry '%2' whose kind is '%3', but "</span>
<span class="string">"that's not compatible with the kind I had established from looking at "</span>
<span class="string">"earlier entries ('%4')."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8_2">&#167;8.2</a>.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>The following allow other parts of Inform to find the kind of a constant
list at a given word position; either to discover the answer, or to force
problem messages out into the open &mdash;
</p>
<pre class="display">
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">Lists::kind_of_list_at</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">int</span><span class="plain"> </span><span class="identifier">incipit</span><span class="plain"> = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">literal_list</span><span class="plain"> *</span><span class="identifier">ll</span><span class="plain"> = </span><span class="functiontext">Lists::find_list_at</span><span class="plain">(</span><span class="identifier">incipit</span><span class="plain">+1);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ll</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Lists::kind_of_ll</span><span class="plain">(</span><span class="identifier">ll</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">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Lists::check_one</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">int</span><span class="plain"> </span><span class="identifier">incipit</span><span class="plain"> = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">literal_list</span><span class="plain"> *</span><span class="identifier">ll</span><span class="plain"> = </span><span class="functiontext">Lists::find_list_at</span><span class="plain">(</span><span class="identifier">incipit</span><span class="plain">+1);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ll</span><span class="plain">) </span><span class="functiontext">Lists::kind_of_ll</span><span class="plain">(</span><span class="identifier">ll</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 Lists::kind_of_list_at is used in 14/rv (<a href="14-rv.html#SP23_4">&#167;23.4</a>).</p>
<p class="endnote">The function Lists::check_one is used in 14/ds2 (<a href="14-ds2.html#SP14_1_1_2">&#167;14.1.1.2</a>).</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>And this checks every list, with problem messages on:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Lists::check</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0) {</span>
<span class="reserved">literal_list</span><span class="plain"> *</span><span class="identifier">ll</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ll</span><span class="plain">, </span><span class="reserved">literal_list</span><span class="plain">)</span>
<span class="functiontext">Lists::kind_of_ll</span><span class="plain">(</span><span class="identifier">ll</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Lists::check is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>That leaves just the compilation of lists at run-time. This used to be a
complex dance with initialisation code interleaved with heap construction,
so there was once a two-page explanation here, but it is now blessedly simple.
</p>
<pre class="display">
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Lists::compile_literal_list</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">int</span><span class="plain"> </span><span class="identifier">incipit</span><span class="plain"> = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">literal_list</span><span class="plain"> *</span><span class="identifier">ll</span><span class="plain"> = </span><span class="functiontext">Lists::find_list_at</span><span class="plain">(</span><span class="identifier">incipit</span><span class="plain">+1);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ll</span><span class="plain">) {</span>
<span class="functiontext">Lists::kind_of_ll</span><span class="plain">(</span><span class="identifier">ll</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">PR</span><span class="plain"> = </span><span class="functiontext">Hierarchy::package_in_enclosure</span><span class="plain">(</span><span class="constant">BLOCK_CONSTANTS_HAP</span><span class="plain">);</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">BLOCK_CONSTANT_HL</span><span class="plain">, </span><span class="identifier">PR</span><span class="plain">);</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Emit::named_late_array_begin</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">);</span>
<span class="functiontext">Emit::array_iname_entry</span><span class="plain">(</span><span class="functiontext">Lists::iname</span><span class="plain">(</span><span class="identifier">ll</span><span class="plain">));</span>
<span class="functiontext">Emit::array_numeric_entry</span><span class="plain">(0);</span>
<span class="functiontext">Emit::array_end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">N</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Lists::iname</span><span class="plain">(</span><span class="reserved">literal_list</span><span class="plain"> *</span><span class="identifier">ll</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;ll_iname</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">PR</span><span class="plain"> = </span><span class="functiontext">Hierarchy::package_in_enclosure</span><span class="plain">(</span><span class="constant">LITERALS_HAP</span><span class="plain">);</span>
<span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;ll_iname</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">LIST_LITERAL_HL</span><span class="plain">, </span><span class="identifier">PR</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;ll_iname</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Lists::compile_literal_list is used in 14/rv (<a href="14-rv.html#SP24_3">&#167;24.3</a>).</p>
<p class="endnote">The function Lists::iname appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>Using:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Lists::compile</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">literal_list</span><span class="plain"> *</span><span class="identifier">ll</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">problem_count</span><span class="plain"> == 0)</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ll</span><span class="plain">, </span><span class="reserved">literal_list</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;list_compiled</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;ll_iname</span><span class="plain">)) {</span>
<span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;list_compiled</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;list_text</span><span class="plain">;</span>
<span class="functiontext">Lists::kind_of_ll</span><span class="plain">(</span><span class="identifier">ll</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">problem_count</span><span class="plain"> == 0) </span>&lt;<span class="cwebmacro">Actually compile the list array</span> <span class="cwebmacronumber">12.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Lists::compile is used in 1/htc (<a href="1-htc.html#SP2_8">&#167;2.8</a>).</p>
<p class="inwebparagraph"><a id="SP12_1"></a><b>&#167;12.1. </b>These are I6 word arrays, with the contents:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) a zero word, used as a flag at run-time;
</li><li>(b) the strong kind ID of the kind of entry the list holds (not the kind of
the list!);
</li><li>(c) the number of entries in the list; and
</li><li>(d) that number of values, each representing one entry.
</li></ul>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Actually compile the list array</span> <span class="cwebmacronumber">12.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Emit::named_array_begin</span><span class="plain">(</span><span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;ll_iname</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">);</span>
<span class="reserved">llist_entry</span><span class="plain"> *</span><span class="identifier">lle</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="reserved">for</span><span class="plain"> (</span><span class="identifier">lle</span><span class="plain"> = </span><span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;first_llist_entry</span><span class="plain">; </span><span class="identifier">lle</span><span class="plain">; </span><span class="identifier">lle</span><span class="plain"> = </span><span class="identifier">lle</span><span class="plain">-</span><span class="element">&gt;next_llist_entry</span><span class="plain">) </span><span class="identifier">n</span><span class="plain">++;</span>
<span class="functiontext">Kinds::RunTime::emit_block_value_header</span><span class="plain">(</span><span class="functiontext">Lists::kind_of_ll</span><span class="plain">(</span><span class="identifier">ll</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">), </span><span class="identifier">TRUE</span><span class="plain">, </span><span class="identifier">n</span><span class="plain">+2);</span>
<span class="functiontext">Kinds::RunTime::emit_strong_id</span><span class="plain">(</span><span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;entry_kind</span><span class="plain">);</span>
<span class="functiontext">Emit::array_numeric_entry</span><span class="plain">((</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">n</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">lle</span><span class="plain"> = </span><span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;first_llist_entry</span><span class="plain">; </span><span class="identifier">lle</span><span class="plain">; </span><span class="identifier">lle</span><span class="plain"> = </span><span class="identifier">lle</span><span class="plain">-</span><span class="element">&gt;next_llist_entry</span><span class="plain">)</span>
<span class="functiontext">Specifications::Compiler::emit_constant_to_kind</span><span class="plain">(</span>
<span class="identifier">lle</span><span class="plain">-</span><span class="element">&gt;llist_entry_value</span><span class="plain">, </span><span class="identifier">ll</span><span class="plain">-</span><span class="element">&gt;entry_kind</span><span class="plain">);</span>
<span class="functiontext">Emit::array_end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP12">&#167;12</a>.</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>The default list of any given kind is empty.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Lists::compile_default_list</span><span class="plain">(</span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">identifier</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="identifier">packaging_state</span><span class="plain"> </span><span class="identifier">save</span><span class="plain"> = </span><span class="functiontext">Emit::named_array_begin</span><span class="plain">(</span><span class="identifier">identifier</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">);</span>
<span class="functiontext">Kinds::RunTime::emit_block_value_header</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">, 2);</span>
<span class="functiontext">Kinds::RunTime::emit_strong_id</span><span class="plain">(</span><span class="identifier">Kinds::unary_construction_material</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">));</span>
<span class="functiontext">Emit::array_numeric_entry</span><span class="plain">(0);</span>
<span class="functiontext">Emit::array_end</span><span class="plain">(</span><span class="identifier">save</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Lists::compile_default_list is used in 13/rsfk (<a href="13-rsfk.html#SP16_2">&#167;16.2</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 18: List Data.)</i></li><li><i>(This section ends Chapter 18: List Data.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>