mirror of
https://github.com/ganelson/inform.git
synced 2024-07-17 06:24:24 +03:00
2163 lines
254 KiB
HTML
2163 lines
254 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>19/tc</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 '19/tb' 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#19">Chapter 19: Table Data</a></li><li><b>Tables</b></li></ul><p class="purpose">To manage and compile tables, which are two-dimensional arrays with associative look-up facilities provided at run-time.</p>
|
|
|
|
<ul class="toc"><li><a href="#SP1">§1. Definitions</a></li><li><a href="#SP5">§5. Traversing for tables</a></li><li><a href="#SP9">§9. Table basics</a></li><li><a href="#SP15">§15. Table creation</a></li><li><a href="#SP22">§22. Table stocking</a></li><li><a href="#SP26">§26. Completing tables</a></li><li><a href="#SP27">§27. Amending tables</a></li><li><a href="#SP29">§29. Indexing</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>This is how a table is stored. Note that the limit on columns per table
|
|
must not rise to 100 or beyond because that would break the system of table
|
|
column ID numbers used at run-time.
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">MAX_COLUMNS_PER_TABLE</span><span class="plain"> 99</span>
|
|
</pre>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">table</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">table_no_text</span><span class="plain">; </span> <span class="comment">the table number (if any)</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">table_name_text</span><span class="plain">; </span> <span class="comment">the table name (if any)</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">table_contribution</span><span class="plain"> *</span><span class="identifier">table_created_at</span><span class="plain">; </span> <span class="comment">where created in source</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">headline_fragment</span><span class="plain">; </span> <span class="comment">a pseudo-sentence formed by the heading line</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">package_request</span><span class="plain"> *</span><span class="identifier">table_package</span><span class="plain">; </span> <span class="comment">where in the Inter</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">blank_rows</span><span class="plain">; </span> <span class="comment">number of entirely blank rows to be appended (may be 0)</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">blank_rows_for_each_text</span><span class="plain">; </span> <span class="comment">add one blank for each instance</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">blank_rows_text</span><span class="plain">; </span> <span class="comment">text of blank rows specification</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">fill_in_blanks</span><span class="plain">; </span> <span class="comment">if set, fill any blank entries with default values</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">first_column_by_definition</span><span class="plain">; </span> <span class="comment">if set, first column defines new value names</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">kind_defined_in_this_table</span><span class="plain">; </span> <span class="comment">...of this kind</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">contains_property_values_at_run_time</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">where_used_to_define</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">preserve_row_order_at_run_time</span><span class="plain">; </span> <span class="comment">if set, don't sort this table</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">table</span><span class="plain"> *</span><span class="identifier">amendment_of</span><span class="plain">; </span> <span class="comment">if amendment of earlier table</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">has_been_amended</span><span class="plain">; </span> <span class="comment">if there exists an amendment of this</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inter_name</span><span class="plain"> *</span><span class="identifier">table_identifier</span><span class="plain">; </span> <span class="comment">at run-time</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">approximate_array_space_needed</span><span class="plain">; </span> <span class="comment">at run-time, in words</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">disable_block_constant_correction</span><span class="plain">; </span> <span class="comment">if set, don't translate block constant entries</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_columns</span><span class="plain">; </span> <span class="comment">must be at least 1</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">table_column_usage</span><span class="plain"> </span><span class="identifier">columns</span><span class="plain">[</span><span class="constant">MAX_COLUMNS_PER_TABLE</span><span class="plain">];</span>
|
|
|
|
<span class="identifier">MEMORY_MANAGEMENT</span>
|
|
<span class="plain">} </span><span class="reserved">table</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure table is accessed in 2/si, 19/tc, 19/rsft, 19/tod and here.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b>For indexing purposes only:
|
|
</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">table_contribution</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">source_table</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">table_contribution</span><span class="plain"> *</span><span class="identifier">next</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">table_contribution</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure table_contribution is accessed in 3/pd, 5/lp, 5/ut, 5/un, 5/ins, 6/rlt, 6/nv, 7/ss, 7/hdn, 7/ns, 7/oaf, 7/rs, 8/ie, 8/ec, 8/ed, 9/tfa, 9/tbath, 9/rpt, 9/tc, 9/ma, 9/rk, 9/ass, 9/imp, 9/pd, 10/teav, 10/cap, 11/ap, 11/pr, 11/bas, 11/tc, 11/sm, 12/dtd, 12/cdp, 14/rv, 14/lv, 14/cn, 14/ds, 14/ds2, 15/cp, 16/is, 16/in, 19/rsft, 19/tod, 20/eq, 21/rl, 21/rl2, 21/fao, 21/rps, 21/sv, 21/ac, 22/ph, 22/tp, 22/tp2, 23/ad, 24/lv, 24/sf, 25/in, 25/pi, 25/cii, 25/cp, 26/uo, 26/tti, 26/pc, 26/ts, 27/cm, 27/is and here.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. </b>These are convenient during parsing.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">table_cell_node</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">table_cell_row</span><span class="plain"> = -1;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">table_cell_col</span><span class="plain"> = -1;</span>
|
|
<span class="reserved">table</span><span class="plain"> *</span><span class="identifier">table_being_examined</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§5. Traversing for tables. </b>Tables of data are created in two special passes through the source text:
|
|
the first finds their names and registers them with the parser, while
|
|
the second (much later) works out their columns and contents. At some
|
|
point we also try to find ambiguity problems which might bite us later on.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">During the main assertions traverses, we simply skip over tables, which
|
|
is why the following sentence handler is null:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">sentence_handler</span><span class="plain"> </span><span class="identifier">TABLE_SH_handler</span><span class="plain"> = { </span><span class="constant">TABLE_NT</span><span class="plain">, -1, 0, </span><span class="identifier">NULL</span><span class="plain"> };</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§6. </b>So here are the specialised table-on traverses. First, the early one,
|
|
which can't do very much about the contents of the tables, but just
|
|
established names of tables and columns:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Tables::traverse_to_create</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="identifier">ParseTree::traverse</span><span class="plain">(</span><span class="functiontext">Tables::visit_to_create</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Tables::visit_to_create</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">) == </span><span class="constant">TABLE_NT</span><span class="plain">)</span>
|
|
<span class="functiontext">Tables::create_table</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Tables::traverse_to_create is used in 1/mr (<a href="1-mr.html#SP4_9">§4.9</a>).</p>
|
|
|
|
<p class="endnote">The function Tables::visit_to_create appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§7. </b>Second, the later one. By this point all of the constant values in Inform
|
|
exist, and so do all of the kinds, so we can now make sense of the kinds
|
|
of the columns and of what's in them; and we can check that this is all
|
|
consistent. This is called "stocking", and it comes in three phases:
|
|
see below.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Tables::traverse_to_stock</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">phase</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">phase</span><span class="plain"> = 1; </span><span class="identifier">phase</span><span class="plain"> <= 3; </span><span class="identifier">phase</span><span class="plain">++) {</span>
|
|
<span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">table</span><span class="plain">) {</span>
|
|
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_created_at</span><span class="plain">-</span><span class="element">>source_table</span><span class="plain">;</span>
|
|
<span class="functiontext">Tables::stock_table</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">phase</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 Tables::traverse_to_stock is used in 1/mr (<a href="1-mr.html#SP4_10">§4.10</a>, <a href="1-mr.html#SP4_13">§4.13</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. </b>Last and least: a traverse existing just to issue a problem message in a
|
|
case which Inform can often cope with, but which the experience of users
|
|
suggests is never a good idea.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Tables::check_tables_for_kind_clashes</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">table</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">t</span><span class="plain">-</span><span class="element">>table_name_text</span><span class="plain">)) && (<</span><span class="identifier">k</span><span class="plain">-</span><span class="identifier">kind</span><span class="plain">-</span><span class="identifier">articled</span><span class="plain">>(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_name_text</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Kinds::Compare::lt</span><span class="plain">(<<</span><span class="identifier">rp</span><span class="plain">>>, </span><span class="identifier">K_object</span><span class="plain">))) {</span>
|
|
<span class="functiontext">Problems::quote_table</span><span class="plain">(1, </span><span class="identifier">t</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_name_text</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableCoincidesWithKind</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"The name %1 will have to be disallowed because '%2' is also the "</span>
|
|
<span class="string">"name of a kind, or of the plural of a kind. (For instance, writing "</span>
|
|
<span class="string">"'Table of Rooms' is disallowed - it could lead to great confusion.)"</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</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 Tables::check_tables_for_kind_clashes is used in 1/mr (<a href="1-mr.html#SP4_12">§4.12</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9"></a><b>§9. Table basics. </b>The following makes a blank structure for a table, but it isn't valid until
|
|
some of these fields have been properly filled in.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">table</span><span class="plain"> *</span><span class="functiontext">Tables::new_table_structure</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">table</span><span class="plain">);</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>table_no_text</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>table_name_text</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>headline_fragment</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows_text</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows_for_each_text</span><span class="plain"> = </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>fill_in_blanks</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>first_column_by_definition</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>kind_defined_in_this_table</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>where_used_to_define</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>contains_property_values_at_run_time</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>preserve_row_order_at_run_time</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>amendment_of</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>has_been_amended</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>table_package</span><span class="plain"> = </span><span class="functiontext">Hierarchy::local_package</span><span class="plain">(</span><span class="constant">TABLES_HAP</span><span class="plain">);</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>table_identifier</span><span class="plain"> = </span><span class="functiontext">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="constant">TABLE_DATA_HL</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_package</span><span class="plain">);</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>approximate_array_space_needed</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>disable_block_constant_correction</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>table_created_at</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="functiontext">Tables::add_table_contribution</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Tables::new_table_structure is used in <a href="#SP20">§20</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10"></a><b>§10. </b>A little linked list of chunks of source contributing to the table:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Tables::add_table_contribution</span><span class="plain">(</span><span class="reserved">table</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">src</span><span class="plain">) {</span>
|
|
<span class="reserved">table_contribution</span><span class="plain"> *</span><span class="identifier">tc</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">table_contribution</span><span class="plain">);</span>
|
|
<span class="identifier">tc</span><span class="plain">-</span><span class="element">>source_table</span><span class="plain"> = </span><span class="identifier">src</span><span class="plain">;</span>
|
|
<span class="identifier">tc</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="reserved">table_contribution</span><span class="plain"> *</span><span class="identifier">ltc</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_created_at</span><span class="plain">;</span>
|
|
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">ltc</span><span class="plain">) && (</span><span class="identifier">ltc</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)) </span><span class="identifier">ltc</span><span class="plain"> = </span><span class="identifier">ltc</span><span class="plain">-</span><span class="element">>next</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ltc</span><span class="plain">) </span><span class="identifier">ltc</span><span class="plain">-</span><span class="element">>next</span><span class="plain"> = </span><span class="identifier">tc</span><span class="plain">; </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_created_at</span><span class="plain"> = </span><span class="identifier">tc</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Tables::add_table_contribution is used in <a href="#SP9">§9</a>, <a href="#SP20_10">§20.10</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11"></a><b>§11. </b>Logging:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Tables::log</span><span class="plain">(</span><span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain">) {</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"{%n}"</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_identifier</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Tables::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="SP12"></a><b>§12. </b>Dimensions:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Tables::get_no_columns</span><span class="plain">(</span><span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain">) {</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Tables::get_no_rows</span><span class="plain">(</span><span class="reserved">table</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">PN</span><span class="plain">; </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">c</span><span class="plain">=0;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">PN</span><span class="plain">=</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[0]</span><span class="element">.entries</span><span class="plain">-</span><span class="element">>down</span><span class="plain">; </span><span class="identifier">PN</span><span class="plain">; </span><span class="identifier">PN</span><span class="plain">=</span><span class="identifier">PN</span><span class="plain">-</span><span class="element">>next</span><span class="plain">) </span><span class="identifier">c</span><span class="plain">++;</span>
|
|
<span class="identifier">c</span><span class="plain"> += </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">c</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Tables::cells_in_ith_column</span><span class="plain">(</span><span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t</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">t</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">"no such table"</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">i</span><span class="plain">>=</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">)) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"column out of range"</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.entries</span><span class="plain">-</span><span class="element">>down</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Tables::get_no_columns appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function Tables::get_no_rows is used in <a href="#SP30_1">§30.1</a>.</p>
|
|
|
|
<p class="endnote">The function Tables::cells_in_ith_column appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP13"></a><b>§13. </b>Miscellaneous services:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Tables::expand_block_constants</span><span class="plain">(</span><span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>amendment_of</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">t</span><span class="plain">-</span><span class="element">>disable_block_constant_correction</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>
|
|
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">Tables::kind_of_ith_column</span><span class="plain">(</span><span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t</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">i</span><span class="plain"><0) || (</span><span class="identifier">i</span><span class="plain">>=</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">))</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tcdt for column out of range"</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Tables::Columns::get_kind</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Tables::expand_block_constants appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function Tables::kind_of_ith_column appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14"></a><b>§14. </b>Oddball forms of naming:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">inter_name</span><span class="plain"> *</span><span class="functiontext">Tables::identifier</span><span class="plain">(</span><span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain">) {</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_identifier</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Tables::get_headline</span><span class="plain">(</span><span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain">) {</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>headline_fragment</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Tables::identifier is used in 14/rv (<a href="14-rv.html#SP24_3">§24.3</a>), 19/rsft (<a href="19-rsft.html#SP1_1_1_1">§1.1.1.1</a>, <a href="19-rsft.html#SP1_3">§1.3</a>, <a href="19-rsft.html#SP2">§2</a>).</p>
|
|
|
|
<p class="endnote">The function Tables::get_headline is used in 2/sq (<a href="2-sq.html#SP2">§2</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15"></a><b>§15. Table creation. </b>Tables can be new, when they appear in the source, or can be related to
|
|
already-existing ones with the same name:
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">TABLE_IS_NEW</span><span class="plain"> 1</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">TABLE_IS_CONTINUED</span><span class="plain"> 2</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">TABLE_IS_AMENDED</span><span class="plain"> 3</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">TABLE_IS_REPLACED</span><span class="plain"> 4</span>
|
|
</pre>
|
|
<p class="inwebparagraph"><a id="SP16"></a><b>§16. </b>Their headers can have three forms:
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">TABLE_HAS_ONLY_NUMBER</span><span class="plain"> 1</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">TABLE_HAS_ONLY_NAME</span><span class="plain"> 2</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">TABLE_HAS_NUMBER_AND_NAME</span><span class="plain"> 3</span>
|
|
</pre>
|
|
<p class="inwebparagraph"><a id="SP17"></a><b>§17. </b>The source text declaration of tables is not easy to parse. Tabs are
|
|
significantly different from spaces or new-lines, for instance — so the
|
|
ordinary rules about white space are suspended. Tabs divide entries in a row;
|
|
new-lines divide rows in a paragraph; and the table is terminated by a
|
|
paragraph break.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">If a table is declared as
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Table 12 - Chemical Elements</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">then it can be referred to elsewhere in the source either as "Table 12"
|
|
or as "Table of Chemical Elements", so both excerpts are registered
|
|
as meaningful. But it is legal to declare a table with only one of the
|
|
two forms in any case.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"><</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">header</span><span class="plain">> ::=</span>
|
|
<span class="plain"><</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">new</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">> ( </span><span class="identifier">continued</span><span class="plain"> ) | ==> </span><span class="constant">TABLE_IS_CONTINUED</span><span class="plain">; <<</span><span class="identifier">nameforms</span><span class="plain">>> = </span><span class="identifier">R</span><span class="plain">[1]</span>
|
|
<span class="plain"><</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">new</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">> ( </span><span class="identifier">amended</span><span class="plain"> ) | ==> </span><span class="constant">TABLE_IS_AMENDED</span><span class="plain">; <<</span><span class="identifier">nameforms</span><span class="plain">>> = </span><span class="identifier">R</span><span class="plain">[1]</span>
|
|
<span class="plain"><</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">new</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">> ( </span><span class="identifier">replaced</span><span class="plain"> ) | ==> </span><span class="constant">TABLE_IS_REPLACED</span><span class="plain">; <<</span><span class="identifier">nameforms</span><span class="plain">>> = </span><span class="identifier">R</span><span class="plain">[1]</span>
|
|
<span class="plain"><</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">new</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">> ==> </span><span class="constant">TABLE_IS_NEW</span><span class="plain">; <<</span><span class="identifier">nameforms</span><span class="plain">>> = </span><span class="identifier">R</span><span class="plain">[1]</span>
|
|
|
|
<span class="plain"><</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">new</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">> ::=</span>
|
|
<span class="reserved">table</span><span class="plain"> ... - ... | ==> </span><span class="constant">TABLE_HAS_NUMBER_AND_NAME</span>
|
|
<span class="reserved">table</span><span class="plain"> ### | ==> </span><span class="constant">TABLE_HAS_ONLY_NUMBER</span>
|
|
<span class="reserved">table</span><span class="plain"> </span><span class="identifier">of</span><span class="plain"> ... | ==> </span><span class="constant">TABLE_HAS_ONLY_NAME</span>
|
|
<span class="reserved">table</span><span class="plain"> ... ==> </span><<span class="cwebmacro">Issue PM_TableMisnamed problem</span> <span class="cwebmacronumber">17.1</span>>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP17_1"></a><b>§17.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Issue PM_TableMisnamed problem</span> <span class="cwebmacronumber">17.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = </span><span class="constant">TABLE_HAS_ONLY_NAME</span><span class="plain">; </span> <span class="comment">for recovery</span>
|
|
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableMisnamed</span><span class="plain">),</span>
|
|
<span class="string">"this isn't allowed as the name of a Table"</span><span class="plain">,</span>
|
|
<span class="string">"since a table is required either to have a number, or to be a table 'of' "</span>
|
|
<span class="string">"something (or both). For example: 'Table 5', 'Table of Blue Meanies', and "</span>
|
|
<span class="string">"'Table 2 - Submarine Hues' are all allowed, but 'Table concerning "</span>
|
|
<span class="string">"Pepperland' is not."</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP17">§17</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP18"></a><b>§18. </b>The following is then used to register table names as constants. The idea
|
|
is that "Table 12 - Chemical Elements" will be registered both as Table 12
|
|
and as Table of Chemical Elements.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"><</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">names</span><span class="plain">-</span><span class="identifier">construction</span><span class="plain">> ::=</span>
|
|
<span class="reserved">table</span><span class="plain"> ... |</span>
|
|
<span class="reserved">table</span><span class="plain"> </span><span class="identifier">of</span><span class="plain"> ...</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP19"></a><b>§19. </b>Optionally, tables can have a footer line specifying additional entirely
|
|
blank rows. In (b), the <code class="display"><span class="extract">...</span></code> is eventually required to be a kind, but this
|
|
happens later on, since the bare bones of tables are parsed very early in
|
|
Inform's run, when kinds haven't yet been created.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"><</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">footer</span><span class="plain">> ::=</span>
|
|
<span class="plain">*** </span><span class="identifier">with</span><span class="plain"> <</span><span class="identifier">cardinal</span><span class="plain">-</span><span class="identifier">number</span><span class="plain">> </span><span class="identifier">blank</span><span class="plain"> </span><span class="identifier">row</span><span class="plain">/</span><span class="identifier">rows</span><span class="plain"> | ==> </span><span class="identifier">R</span><span class="plain">[1]; <<</span><span class="identifier">each</span><span class="plain">>> = </span><span class="identifier">FALSE</span>
|
|
<span class="plain">*** </span><span class="identifier">with</span><span class="plain"> ... </span><span class="identifier">blank</span><span class="plain"> </span><span class="identifier">row</span><span class="plain">/</span><span class="identifier">rows</span><span class="plain"> | ==> 0; <<</span><span class="identifier">each</span><span class="plain">>> = </span><span class="identifier">NOT_APPLICABLE</span>
|
|
<span class="plain">*** </span><span class="identifier">with</span><span class="plain"> </span><span class="identifier">blank</span><span class="plain"> </span><span class="identifier">row</span><span class="plain">/</span><span class="identifier">rows</span><span class="plain"> </span><span class="reserved">for</span><span class="plain"> </span><span class="identifier">each</span><span class="plain">/</span><span class="identifier">every</span><span class="plain"> ... ==> 0; <<</span><span class="identifier">each</span><span class="plain">>> = </span><span class="identifier">TRUE</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20"></a><b>§20. </b>So, here goes. We first identify the top line of the table declaration
|
|
(the "headline"), then set the current sentence to that, even though in
|
|
parse tree terms it's only a fragment of a sentence: this makes problem
|
|
messages about the headline much more readable. We extract the table's
|
|
name, number and connection to other tables, and count its rows. In some
|
|
cases, for example where we are continuing an existing table, we use the
|
|
new table structure only temporarily: we transfer its rows to the existing
|
|
table and then destroy the temporary one made here.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Tables::create_table</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">PN</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">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">PN</span><span class="plain">);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">connection</span><span class="plain"> = </span><span class="constant">TABLE_IS_NEW</span><span class="plain">; </span> <span class="comment">i.e., no connection with existing tables</span>
|
|
<span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain"> = </span><span class="functiontext">Tables::new_table_structure</span><span class="plain">();</span>
|
|
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">HW</span><span class="plain"> = </span><span class="identifier">Wordings::up_to</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">Wordings::last_word_of_formatted_text</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="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::length</span><span class="plain">(</span><span class="identifier">HW</span><span class="plain">) == 1) </span><<span class="cwebmacro">Reject this lexically malformed table declaration</span> <span class="cwebmacronumber">20.1</span>><span class="plain">;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>headline_fragment</span><span class="plain"> = </span><span class="identifier">NounPhrases::new_raw</span><span class="plain">(</span><span class="identifier">HW</span><span class="plain">);</span>
|
|
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>headline_fragment</span><span class="plain">;</span>
|
|
|
|
<<span class="cwebmacro">Parse the table's header for a name and/or number, and connection to other tables</span> <span class="cwebmacronumber">20.2</span>><span class="character">;</span>
|
|
<<span class="cwebmacro">Require the table name not to tread on some other value</span> <span class="cwebmacronumber">20.3</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">table</span><span class="plain"> *</span><span class="identifier">existing_table_with_same_name</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<<span class="cwebmacro">Find the first existing table with the same name, if any</span> <span class="cwebmacronumber">20.4</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">connection</span><span class="plain"> != </span><span class="constant">TABLE_IS_NEW</span><span class="plain">) </span><<span class="cwebmacro">Require the previous table to exist</span> <span class="cwebmacronumber">20.5</span>>
|
|
<span class="reserved">else</span><span class="plain"> </span><<span class="cwebmacro">Require the previous table not to exist</span> <span class="cwebmacronumber">20.6</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">connection</span><span class="plain"> == </span><span class="constant">TABLE_IS_NEW</span><span class="plain">) {</span>
|
|
<<span class="cwebmacro">Register the names of the new table</span> <span class="cwebmacronumber">20.7</span>><span class="plain">;</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TABLES</span><span class="plain">, </span><span class="string">"Created: $B\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<<span class="cwebmacro">Parse the table's footer for a number of blank rows</span> <span class="cwebmacronumber">20.8</span>><span class="character">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">row_count</span><span class="plain"> = 0;</span>
|
|
<<span class="cwebmacro">Count out the rows and columns in the new table</span> <span class="cwebmacronumber">20.9</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">connection</span><span class="plain"> != </span><span class="constant">TABLE_IS_NEW</span><span class="plain">)</span>
|
|
<<span class="cwebmacro">Act on the connection, possibly destroying the temporary table just made</span> <span class="cwebmacronumber">20.10</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Tables::create_table is used in <a href="#SP6">§6</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_1"></a><b>§20.1. </b>Changes to the lexer mean that this shouldn't happen, but just in case:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Reject this lexically malformed table declaration</span> <span class="cwebmacronumber">20.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">BelievedImpossible</span><span class="plain">),</span>
|
|
<span class="string">"this table does not strictly speaking start a paragraph"</span><span class="plain">,</span>
|
|
<span class="string">"and I'm afraid we need to speak strictly here. Even a comment coming before "</span>
|
|
<span class="string">"the start of the table is too much."</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20">§20</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_2"></a><b>§20.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Parse the table's header for a name and/or number, and connection to other tables</span> <span class="cwebmacronumber">20.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TABLES</span><span class="plain">, </span><span class="string">"Parsing table headline %W\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">HW</span><span class="plain">);</span>
|
|
<span class="plain"><</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">header</span><span class="plain">>(</span><span class="identifier">HW</span><span class="plain">);</span>
|
|
<span class="identifier">connection</span><span class="plain"> = <<</span><span class="identifier">r</span><span class="plain">>>;</span>
|
|
|
|
<span class="reserved">switch</span><span class="plain"> (<<</span><span class="identifier">nameforms</span><span class="plain">>>) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">TABLE_HAS_ONLY_NUMBER</span><span class="plain">:</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>table_no_text</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(<</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">new</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">>, 1);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">TABLE_HAS_ONLY_NAME</span><span class="plain">:</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>table_name_text</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(<</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">new</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">>, 1);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">TABLE_HAS_NUMBER_AND_NAME</span><span class="plain">:</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>table_no_text</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(<</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">new</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">>, 1);</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>table_name_text</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(<</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">new</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">>, 2);</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="#SP20">§20</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_3"></a><b>§20.3. </b>Practical experience showed that the following restriction was wise:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Require the table name not to tread on some other value</span> <span class="cwebmacronumber">20.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (<</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">type</span><span class="plain">-</span><span class="identifier">expression</span><span class="plain">-</span><span class="identifier">or</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">>(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_name_text</span><span class="plain">)) {</span>
|
|
<span class="identifier">Problems::quote_wording_as_source</span><span class="plain">(1, </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_name_text</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableNameAmbiguous</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"The table name %1 will have to be disallowed as it is text which "</span>
|
|
<span class="string">"already has a meaning to Inform. For instance, creating the 'Table "</span>
|
|
<span class="string">"of Seven' would be disallowed because of the possible confusion "</span>
|
|
<span class="string">"with the number 'seven'."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="identifier">DESTROY</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">table</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20">§20</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_4"></a><b>§20.4. </b>It's not as simple as it seems to decide when a new table headline refers
|
|
back to a table which already exists — there are several ways we could play
|
|
this. What we say is that if the new headline gives both name and number,
|
|
then both must match; if it gives name only, that must match; if it gives
|
|
number only, that must. Suppose that "Table 2 - Trees" already exists. Then:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<ul class="items"><li>(a) if "Table 2 - Shrubs" or "Table 3 - Trees" comes along, there's no match;
|
|
</li><li>(b) if "Table of Trees" comes along, that does match;
|
|
</li><li>(c) if "Table 2" comes along, so does that.
|
|
</li></ul>
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="identifier">TABLE_NAMES_MATCH</span><span class="plain">(</span><span class="identifier">t1</span><span class="plain">, </span><span class="identifier">t2</span><span class="plain">)</span>
|
|
<span class="plain">((</span><span class="identifier">t1</span><span class="plain"> != </span><span class="identifier">t2</span><span class="plain">) && (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">t1</span><span class="plain">-</span><span class="element">>table_name_text</span><span class="plain">)) && (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">t2</span><span class="plain">-</span><span class="element">>table_name_text</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Wordings::match</span><span class="plain">(</span><span class="identifier">t2</span><span class="plain">-</span><span class="element">>table_name_text</span><span class="plain">, </span><span class="identifier">t1</span><span class="plain">-</span><span class="element">>table_name_text</span><span class="plain">)))</span>
|
|
<span class="definitionkeyword">define</span> <span class="identifier">TABLE_NUMBERS_MATCH</span><span class="plain">(</span><span class="identifier">t1</span><span class="plain">, </span><span class="identifier">t2</span><span class="plain">)</span>
|
|
<span class="plain">((</span><span class="identifier">t1</span><span class="plain"> != </span><span class="identifier">t2</span><span class="plain">) && (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">t1</span><span class="plain">-</span><span class="element">>table_no_text</span><span class="plain">)) && (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">t2</span><span class="plain">-</span><span class="element">>table_no_text</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Wordings::match</span><span class="plain">(</span><span class="identifier">t2</span><span class="plain">-</span><span class="element">>table_no_text</span><span class="plain">, </span><span class="identifier">t1</span><span class="plain">-</span><span class="element">>table_no_text</span><span class="plain">)))</span>
|
|
</pre>
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Find the first existing table with the same name, if any</span> <span class="cwebmacronumber">20.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_name_text</span><span class="plain">)) && (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_no_text</span><span class="plain">))) {</span>
|
|
<span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t2</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">t2</span><span class="plain">, </span><span class="reserved">table</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">TABLE_NAMES_MATCH</span><span class="plain">(</span><span class="identifier">t2</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">)) && (</span><span class="identifier">TABLE_NUMBERS_MATCH</span><span class="plain">(</span><span class="identifier">t2</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">)))</span>
|
|
<span class="identifier">existing_table_with_same_name</span><span class="plain"> = </span><span class="identifier">t2</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">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_name_text</span><span class="plain">)) {</span>
|
|
<span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t2</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">t2</span><span class="plain">, </span><span class="reserved">table</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TABLE_NAMES_MATCH</span><span class="plain">(</span><span class="identifier">t2</span><span class="plain">, </span><span class="identifier">t</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">t</span><span class="plain">-</span><span class="element">>table_no_text</span><span class="plain">)) && (!(</span><span class="identifier">TABLE_NUMBERS_MATCH</span><span class="plain">(</span><span class="identifier">t2</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">))))</span>
|
|
<span class="reserved">continue</span><span class="plain">;</span>
|
|
<span class="identifier">existing_table_with_same_name</span><span class="plain"> = </span><span class="identifier">t2</span><span class="plain">;</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">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_no_text</span><span class="plain">)) {</span>
|
|
<span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t2</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">t2</span><span class="plain">, </span><span class="reserved">table</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TABLE_NUMBERS_MATCH</span><span class="plain">(</span><span class="identifier">t2</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">))</span>
|
|
<span class="identifier">existing_table_with_same_name</span><span class="plain"> = </span><span class="identifier">t2</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20">§20</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_5"></a><b>§20.5. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Require the previous table to exist</span> <span class="cwebmacronumber">20.5</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">existing_table_with_same_name</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<span class="functiontext">Problems::quote_table</span><span class="plain">(1, </span><span class="identifier">t</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableNotContinuation</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"It looks as if %1 is meant to be related to an existing table, "</span>
|
|
<span class="string">"but I can't find one if it is. %P"</span>
|
|
<span class="string">"Perhaps you've put the new part before the original? The original "</span>
|
|
<span class="string">"has to be earlier in the source text."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="identifier">DESTROY</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">table</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20">§20</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_6"></a><b>§20.6. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Require the previous table not to exist</span> <span class="cwebmacronumber">20.6</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">existing_table_with_same_name</span><span class="plain">) {</span>
|
|
<span class="functiontext">Problems::quote_table</span><span class="plain">(1, </span><span class="identifier">t</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_table</span><span class="plain">(2, </span><span class="identifier">existing_table_with_same_name</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_wording</span><span class="plain">(3, </span><span class="identifier">HW</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableNameDuplicate</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"I can't create %1 because its name overlaps with one that already "</span>
|
|
<span class="string">"exists: %2. %P"</span>
|
|
<span class="string">"It's possible to continue the existing one, if you just want to "</span>
|
|
<span class="string">"add more rows, by writing '%3 (continued)' here."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="identifier">DESTROY</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">table</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20">§20</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_7"></a><b>§20.7. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Register the names of the new table</span> <span class="cwebmacronumber">20.7</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_no_text</span><span class="plain">)) {</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TABLES</span><span class="plain">, </span><span class="string">"Registering table by number: table %W\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_no_text</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">wa</span><span class="plain"> = </span><span class="identifier">Preform::Nonparsing::merge</span><span class="plain">(<</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">names</span><span class="plain">-</span><span class="identifier">construction</span><span class="plain">>, 0,</span>
|
|
<span class="identifier">WordAssemblages::from_wording</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_no_text</span><span class="plain">));</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">AW</span><span class="plain"> = </span><span class="identifier">WordAssemblages::to_wording</span><span class="plain">(&</span><span class="identifier">wa</span><span class="plain">);</span>
|
|
<span class="identifier">Nouns::new_proper_noun</span><span class="plain">(</span><span class="identifier">AW</span><span class="plain">, </span><span class="identifier">NEUTER_GENDER</span><span class="plain">,</span>
|
|
<span class="identifier">REGISTER_SINGULAR_NTOPT</span><span class="plain"> + </span><span class="identifier">PARSE_EXACTLY_NTOPT</span><span class="plain">,</span>
|
|
<span class="constant">TABLE_MC</span><span class="plain">, </span><span class="functiontext">Rvalues::from_table</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">));</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">t</span><span class="plain">-</span><span class="element">>table_name_text</span><span class="plain">)) {</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TABLES</span><span class="plain">, </span><span class="string">"Registering table by name: table of %W\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_name_text</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">wa</span><span class="plain"> = </span><span class="identifier">Preform::Nonparsing::merge</span><span class="plain">(<</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">names</span><span class="plain">-</span><span class="identifier">construction</span><span class="plain">>, 1,</span>
|
|
<span class="identifier">WordAssemblages::from_wording</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_name_text</span><span class="plain">));</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">AW</span><span class="plain"> = </span><span class="identifier">WordAssemblages::to_wording</span><span class="plain">(&</span><span class="identifier">wa</span><span class="plain">);</span>
|
|
<span class="identifier">Nouns::new_proper_noun</span><span class="plain">(</span><span class="identifier">AW</span><span class="plain">, </span><span class="identifier">NEUTER_GENDER</span><span class="plain">,</span>
|
|
<span class="identifier">REGISTER_SINGULAR_NTOPT</span><span class="plain"> + </span><span class="identifier">PARSE_EXACTLY_NTOPT</span><span class="plain">,</span>
|
|
<span class="constant">TABLE_MC</span><span class="plain">, </span><span class="functiontext">Rvalues::from_table</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">));</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20">§20</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_8"></a><b>§20.8. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Parse the table's footer for a number of blank rows</span> <span class="cwebmacronumber">20.8</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (<</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">footer</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">GET_RW</span><span class="plain">(<</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">footer</span><span class="plain">>, 1);</span>
|
|
<span class="reserved">switch</span><span class="plain"> (<<</span><span class="identifier">each</span><span class="plain">>>) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">: </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows_for_each_text</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(<</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">footer</span><span class="plain">>, 2); </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">: </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows</span><span class="plain"> = <<</span><span class="identifier">r</span><span class="plain">>>; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">: </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows</span><span class="plain"> = 1; </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows_text</span><span class="plain"> = </span><span class="identifier">GET_RW</span><span class="plain">(<</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">footer</span><span class="plain">>, 2); </span><span class="reserved">break</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="#SP20">§20</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_9"></a><b>§20.9. </b>Here's where we start building. The table's representation in the parse
|
|
tree is currently very unhelpful: it's just one enormous sentence node with
|
|
all the words in, headings and cells merged together. Instead of using this
|
|
we hang a list of parse nodes, one for each cell, as children of the entries
|
|
node for each column.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Count out the rows and columns in the new table</span> <span class="cwebmacronumber">20.9</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">pos</span><span class="plain"> = </span><span class="identifier">Wordings::last_wn</span><span class="plain">(</span><span class="identifier">HW</span><span class="plain">)+1;</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">pos</span><span class="plain"> <= </span><span class="identifier">Wordings::last_wn</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">col_count</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">row_end</span><span class="plain"> = </span><span class="identifier">Wordings::last_word_of_formatted_text</span><span class="plain">(</span><span class="identifier">Wordings::from</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">pos</span><span class="plain">), </span><span class="identifier">FALSE</span><span class="plain">);</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TABLES</span><span class="plain">, </span><span class="string">"Row %d is %W\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">row_count</span><span class="plain">, </span><span class="identifier">Wordings::new</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">row_end</span><span class="plain">));</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">pos</span><span class="plain"> <= </span><span class="identifier">row_end</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">cell_end</span><span class="plain"> = </span><span class="identifier">Wordings::last_word_of_formatted_text</span><span class="plain">(</span><span class="identifier">Wordings::new</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">row_end</span><span class="plain">), </span><span class="identifier">TRUE</span><span class="plain">);</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TABLES</span><span class="plain">, </span><span class="string">"Cell (%d, %d) is %W\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">row_count</span><span class="plain">, </span><span class="identifier">col_count</span><span class="plain">, </span><span class="identifier">Wordings::new</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">cell_end</span><span class="plain">));</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">row_count</span><span class="plain"> == 0) </span><<span class="cwebmacro">This is a column-heading cell</span> <span class="cwebmacronumber">20.9.1</span>>
|
|
<span class="reserved">else</span><span class="plain"> </span><<span class="cwebmacro">This is a data cell</span> <span class="cwebmacronumber">20.9.2</span>><span class="plain">;</span>
|
|
<span class="identifier">col_count</span><span class="plain">++;</span>
|
|
<span class="identifier">pos</span><span class="plain"> = </span><span class="identifier">cell_end</span><span class="plain"> + 1;</span>
|
|
<span class="plain">}</span>
|
|
<<span class="cwebmacro">Add implied blank data cells to fill out the row as needed</span> <span class="cwebmacronumber">20.9.3</span>><span class="plain">;</span>
|
|
<span class="identifier">row_count</span><span class="plain">++;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">row_count</span><span class="plain"> < 2) && (</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows</span><span class="plain"> == 0)) {</span>
|
|
<span class="functiontext">Problems::Issue::table_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableWithoutRows</span><span class="plain">),</span>
|
|
<span class="identifier">t</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">PN</span><span class="plain">, </span><span class="string">"%1 has no rows."</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20">§20</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_9_1"></a><b>§20.9.1. </b>See "Table Columns" for the actual column creation: note that this makes
|
|
a node in the parse tree representing the column's use within this table.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">This is a column-heading cell</span> <span class="cwebmacronumber">20.9.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">PN</span><span class="plain">;</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">CW</span><span class="plain"> = </span><span class="identifier">Wordings::new</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">cell_end</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">col_count</span><span class="plain"> == </span><span class="constant">MAX_COLUMNS_PER_TABLE</span><span class="plain">) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">overflow</span><span class="plain"> = </span><span class="identifier">NounPhrases::new_raw</span><span class="plain">(</span><span class="identifier">CW</span><span class="plain">);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">limit</span><span class="plain"> = </span><span class="constant">MAX_COLUMNS_PER_TABLE</span><span class="plain">;</span>
|
|
<span class="identifier">Problems::quote_number</span><span class="plain">(4, &</span><span class="identifier">limit</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::Issue::table_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableTooManyColumns</span><span class="plain">),</span>
|
|
<span class="identifier">t</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">overflow</span><span class="plain">,</span>
|
|
<span class="string">"There are %4 columns in %1 already, and that's the absolute limit, "</span>
|
|
<span class="string">"so the column %3 can't be added."</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">col_count</span><span class="plain"> < </span><span class="constant">MAX_COLUMNS_PER_TABLE</span><span class="plain">) {</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TABLES</span><span class="plain">, </span><span class="string">"Creating col %d from '%W'\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">, </span><span class="identifier">CW</span><span class="plain">);</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">] = </span><span class="functiontext">Tables::Columns::add_to_table</span><span class="plain">(</span><span class="identifier">CW</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">) </span> <span class="comment">i.e., no Problem occurred</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">++;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20_9">§20.9</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_9_2"></a><b>§20.9.2. </b>Each data cell becomes a node, and is added to the list under its column.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">This is a data cell</span> <span class="cwebmacronumber">20.9.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">CW</span><span class="plain"> = </span><span class="identifier">Wordings::new</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">, </span><span class="identifier">cell_end</span><span class="plain">);</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">cell</span><span class="plain"> = </span><span class="identifier">NounPhrases::new_raw</span><span class="plain">(</span><span class="identifier">CW</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">col_count</span><span class="plain"> >= </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">) {</span>
|
|
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">PN</span><span class="plain">;</span>
|
|
<span class="identifier">Problems::quote_number</span><span class="plain">(4, &(</span><span class="identifier">row_count</span><span class="plain">));</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">given_col</span><span class="plain"> = </span><span class="identifier">col_count</span><span class="plain"> + 1; </span> <span class="comment">i.e., counting from 1 rather than 0</span>
|
|
<span class="identifier">Problems::quote_number</span><span class="plain">(5, &(</span><span class="identifier">given_col</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::quote_number</span><span class="plain">(6, &(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">));</span>
|
|
<span class="functiontext">Problems::Issue::table_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableRowFull</span><span class="plain">),</span>
|
|
<span class="identifier">t</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">cell</span><span class="plain">,</span>
|
|
<span class="string">"In row %4 of the table %1, the entry %3 won't fit, because its row "</span>
|
|
<span class="string">"is already full. (This entry would be in column %5 and the table has "</span>
|
|
<span class="string">"only %6.)"</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">cell</span><span class="plain">, </span><span class="constant">table_cell_unspecified_ANNOT</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::graft</span><span class="plain">(</span><span class="identifier">cell</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">col_count</span><span class="plain">]</span><span class="element">.entries</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20_9">§20.9</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_9_3"></a><b>§20.9.3. </b>If a row finishes early, we pad it out with blanks.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Add implied blank data cells to fill out the row as needed</span> <span class="cwebmacronumber">20.9.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">col_count</span><span class="plain"> < </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">) { </span> <span class="comment">which can only happen on data rows</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">cell</span><span class="plain"> = </span><span class="functiontext">Tables::empty_cell_node</span><span class="plain">();</span>
|
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">cell</span><span class="plain">, </span><span class="constant">table_cell_unspecified_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::graft</span><span class="plain">(</span><span class="identifier">cell</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">col_count</span><span class="plain">]</span><span class="element">.entries</span><span class="plain">);</span>
|
|
<span class="identifier">col_count</span><span class="plain">++;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20_9">§20.9</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_10"></a><b>§20.10. </b>All parsing is finished now.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Act on the connection, possibly destroying the temporary table just made</span> <span class="cwebmacronumber">20.10</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">table</span><span class="plain"> *</span><span class="identifier">old_t</span><span class="plain"> = </span><span class="identifier">existing_table_with_same_name</span><span class="plain">;</span>
|
|
<span class="functiontext">Tables::add_table_contribution</span><span class="plain">(</span><span class="identifier">old_t</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>headline_fragment</span><span class="plain">);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">new_to_old</span><span class="plain">[</span><span class="constant">MAX_COLUMNS_PER_TABLE</span><span class="plain">], </span><span class="identifier">old_to_new</span><span class="plain">[</span><span class="constant">MAX_COLUMNS_PER_TABLE</span><span class="plain">];</span>
|
|
<<span class="cwebmacro">Build the column correspondence tables</span> <span class="cwebmacronumber">20.10.1</span>><span class="plain">;</span>
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">connection</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">TABLE_IS_CONTINUED</span><span class="plain">: </span><<span class="cwebmacro">Make the new part a continuation of the existing table</span> <span class="cwebmacronumber">20.10.2</span>><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">TABLE_IS_AMENDED</span><span class="plain">: </span><<span class="cwebmacro">Make the new part an amendment of the existing table</span> <span class="cwebmacronumber">20.10.4</span>><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">TABLE_IS_REPLACED</span><span class="plain">: </span><<span class="cwebmacro">Make the new part a replacement of the existing table</span> <span class="cwebmacronumber">20.10.3</span>><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">default</span><span class="plain">: </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"unknown form of table connection"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20">§20</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_10_1"></a><b>§20.10.1. </b>We assume that columns in the new and old tables will be partial permutations
|
|
of each other: for example the old might have columns "fish", "mammals", "birds"
|
|
(index <code class="display"><span class="extract">j</span></code> running from 0 to 2) and the new "mammals", "reptiles", "fish",
|
|
"fungi" (index <code class="display"><span class="extract">i</span></code> running from 0 to 3). We're going to store both the permutation
|
|
and its inverse, with the index <code class="display"><span class="extract">-1</span></code> meaning that the column doesn't appear in
|
|
the other table at all. The result will be:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">old_to_new: 2, 0, -1</span>
|
|
<span class="plain">new_to_old: 1, -1, 0, -1</span>
|
|
|
|
<<span class="cwebmacrodefn">Build the column correspondence tables</span> <span class="cwebmacronumber">20.10.1</span>> =
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">j</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="identifier">old_t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">; </span><span class="identifier">j</span><span class="plain">++) </span><span class="identifier">old_to_new</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] = -1;</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="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">new_to_old</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = -1;</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="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">; </span><span class="identifier">i</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="identifier">old_t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">; </span><span class="identifier">j</span><span class="plain">++)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain"> == </span><span class="identifier">old_t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">) {</span>
|
|
<span class="identifier">new_to_old</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">j</span><span class="plain">; </span><span class="identifier">old_to_new</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] = </span><span class="identifier">i</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TABLES</span><span class="plain">, </span><span class="string">"Column correspondence table:\</span><span class="plain">n</span><span class="string"> old->new: "</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="identifier">old_t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">; </span><span class="identifier">j</span><span class="plain">++)</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TABLES</span><span class="plain">, </span><span class="string">"%d (%W) "</span><span class="plain">, </span><span class="identifier">old_to_new</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">],</span>
|
|
<span class="identifier">Nouns::nominative</span><span class="plain">(</span><span class="identifier">old_t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">-</span><span class="element">>name</span><span class="plain">));</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TABLES</span><span class="plain">, </span><span class="string">"\</span><span class="plain">n</span><span class="string"> new->old: "</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="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TABLES</span><span class="plain">, </span><span class="string">"%d (%W) "</span><span class="plain">, </span><span class="identifier">new_to_old</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">],</span>
|
|
<span class="identifier">Nouns::nominative</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">-</span><span class="element">>name</span><span class="plain">));</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TABLES</span><span class="plain">, </span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20_10">§20.10</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_10_2"></a><b>§20.10.2. </b>We can carry out the continuation immediately, since it just means splicing
|
|
the new table's rows onto the ends of the old table's columns.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Make the new part a continuation of the existing table</span> <span class="cwebmacronumber">20.10.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<<span class="cwebmacro">Require that every column of the new table is also found in the old one</span> <span class="cwebmacronumber">20.10.2.2</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Transfer blank rows of the new table to the old one</span> <span class="cwebmacronumber">20.10.2.1</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">row_count</span><span class="plain"> >= 2) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</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="identifier">old_t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">; </span><span class="identifier">j</span><span class="plain">++)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">old_to_new</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] >= 0) {</span>
|
|
<span class="identifier">ParseTree::graft</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">old_to_new</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]]</span><span class="element">.entries</span><span class="plain">-</span><span class="element">>down</span><span class="plain">,</span>
|
|
<span class="identifier">old_t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]</span><span class="element">.entries</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</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">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=1; </span><span class="identifier">i</span><span class="plain"><</span><span class="identifier">row_count</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) { </span> <span class="comment">from 1 to omit the column headings</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">blank</span><span class="plain"> = </span><span class="functiontext">Tables::empty_cell_node</span><span class="plain">();</span>
|
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">blank</span><span class="plain">, </span><span class="constant">table_cell_unspecified_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::graft</span><span class="plain">(</span><span class="identifier">blank</span><span class="plain">, </span><span class="identifier">old_t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]</span><span class="element">.entries</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">DESTROY</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">table</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20_10">§20.10</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_10_2_1"></a><b>§20.10.2.1. </b>It's a little awkward to work out what the policy is if the original table
|
|
wants a row for each man, and the continuation wants a row for each woman.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Transfer blank rows of the new table to the old one</span> <span class="cwebmacronumber">20.10.2.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">old_t</span><span class="plain">-</span><span class="element">>blank_rows</span><span class="plain"> += </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows</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">t</span><span class="plain">-</span><span class="element">>blank_rows_for_each_text</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">old_t</span><span class="plain">-</span><span class="element">>blank_rows_for_each_text</span><span class="plain">)) {</span>
|
|
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_created_at</span><span class="plain">-</span><span class="element">>source_table</span><span class="plain">;</span>
|
|
<span class="functiontext">Problems::quote_table</span><span class="plain">(1, </span><span class="identifier">t</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_table</span><span class="plain">(2, </span><span class="identifier">old_t</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_wording</span><span class="plain">(3, </span><span class="identifier">old_t</span><span class="plain">-</span><span class="element">>blank_rows_for_each_text</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_wording</span><span class="plain">(4, </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows_for_each_text</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableContinuationContradicts</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"The table %1 says that it should have a blank row for each "</span>
|
|
<span class="string">"%4, but the original %2 already says it has a blank for each "</span>
|
|
<span class="string">"%3. It can only be specified once."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">old_t</span><span class="plain">-</span><span class="element">>blank_rows_for_each_text</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows_for_each_text</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20_10_2">§20.10.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_10_3"></a><b>§20.10.3. </b>And similarly for replacements...
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Make the new part a replacement of the existing table</span> <span class="cwebmacronumber">20.10.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<<span class="cwebmacro">Require that every column of the old table is also found in the new one</span> <span class="cwebmacronumber">20.10.3.2</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Copy blank rows of the new table to the old one</span> <span class="cwebmacronumber">20.10.3.1</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="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="identifier">old_t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">; </span><span class="identifier">j</span><span class="plain">++)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">old_to_new</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] >= 0) </span> <span class="comment">and if this isn't true, we've issued a Problem already</span>
|
|
<span class="identifier">old_t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]</span><span class="element">.entries</span><span class="plain">-</span><span class="element">>down</span>
|
|
<span class="plain">= </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">old_to_new</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]]</span><span class="element">.entries</span><span class="plain">-</span><span class="element">>down</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">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="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</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">new_to_old</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] == -1)</span>
|
|
<span class="identifier">old_t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">old_t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">++] = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]; </span> <span class="comment">old table must have room</span>
|
|
<span class="identifier">DESTROY</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">table</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20_10">§20.10</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_10_3_1"></a><b>§20.10.3.1. </b>...but this is easier:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Copy blank rows of the new table to the old one</span> <span class="cwebmacronumber">20.10.3.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">old_t</span><span class="plain">-</span><span class="element">>blank_rows</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows</span><span class="plain">;</span>
|
|
<span class="identifier">old_t</span><span class="plain">-</span><span class="element">>blank_rows_text</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows_text</span><span class="plain">;</span>
|
|
<span class="identifier">old_t</span><span class="plain">-</span><span class="element">>blank_rows_for_each_text</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows_for_each_text</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20_10_3">§20.10.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_10_4"></a><b>§20.10.4. </b>Amendments can't be done yet, because they depend on recognising values,
|
|
and it's far too early in Inform's run to recognise constants. So we must
|
|
postpone the work until later: note that we don't destroy the new table
|
|
structure in this case.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Make the new part an amendment of the existing table</span> <span class="cwebmacronumber">20.10.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<<span class="cwebmacro">Require that the old and new tables have exactly matching columns</span> <span class="cwebmacronumber">20.10.4.1</span>><span class="plain">;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>amendment_of</span><span class="plain"> = </span><span class="identifier">old_t</span><span class="plain">;</span>
|
|
<span class="identifier">old_t</span><span class="plain">-</span><span class="element">>has_been_amended</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TABLES</span><span class="plain">, </span><span class="string">"Amendment table created pro tem\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20_10">§20.10</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_10_2_2"></a><b>§20.10.2.2. </b>Here each new column must appear once in the old table, but the new
|
|
table doesn't have to cover everything in the old table. (Blanks are
|
|
used in continuation rows for columns not mentioned.)
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Require that every column of the new table is also found in the old one</span> <span class="cwebmacronumber">20.10.2.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">missing</span><span class="plain"> = 0;</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="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</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">new_to_old</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] == -1)</span>
|
|
<span class="identifier">missing</span><span class="plain">++;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">missing</span><span class="plain"> > 0) {</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="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</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">"nto[%d] = %d, otn[%d] = %d\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">new_to_old</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">], </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">old_to_new</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]);</span>
|
|
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_created_at</span><span class="plain">-</span><span class="element">>source_table</span><span class="plain">;</span>
|
|
<span class="functiontext">Problems::quote_table</span><span class="plain">(1, </span><span class="identifier">t</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_table</span><span class="plain">(2, </span><span class="identifier">old_t</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">missing</span><span class="plain"> == 1) </span><span class="identifier">Problems::quote_text</span><span class="plain">(3, </span><span class="string">"a column"</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Problems::quote_text</span><span class="plain">(3, </span><span class="string">"columns"</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableContinuationAddsCols</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"The table %1 won't work as a continuation, because it contains "</span>
|
|
<span class="string">"%3 not found in the original %2."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<<span class="cwebmacro">Display the old and new table column names</span> <span class="cwebmacronumber">20.10.2.2.1</span>><span class="plain">;</span>
|
|
<span class="identifier">DESTROY</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">table</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20_10_2">§20.10.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_10_3_2"></a><b>§20.10.3.2. </b>Here each old column must appear once in the new table, but the new
|
|
table is allowed to have extra columns. (This means the new table can
|
|
be "wider" than the old one.)
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Require that every column of the old table is also found in the new one</span> <span class="cwebmacronumber">20.10.3.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">, </span><span class="identifier">missing</span><span class="plain"> = 0;</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="identifier">old_t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">; </span><span class="identifier">j</span><span class="plain">++)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">old_to_new</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] == -1)</span>
|
|
<span class="identifier">missing</span><span class="plain">++;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">missing</span><span class="plain"> > 0) {</span>
|
|
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_created_at</span><span class="plain">-</span><span class="element">>source_table</span><span class="plain">;</span>
|
|
<span class="functiontext">Problems::quote_table</span><span class="plain">(1, </span><span class="identifier">t</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_table</span><span class="plain">(2, </span><span class="identifier">old_t</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">missing</span><span class="plain"> == 1) </span><span class="identifier">Problems::quote_text</span><span class="plain">(3, </span><span class="string">"a column"</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Problems::quote_text</span><span class="plain">(3, </span><span class="string">"columns"</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableReplacementMissesCols</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"The table %1 won't work as a replacement, because it's missing "</span>
|
|
<span class="string">"%3 found in the original %2."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<<span class="cwebmacro">Display the old and new table column names</span> <span class="cwebmacronumber">20.10.2.2.1</span>><span class="plain">;</span>
|
|
<span class="identifier">DESTROY</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">table</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20_10_3">§20.10.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_10_4_1"></a><b>§20.10.4.1. </b>We require this to be the identity permutation, i.e., exactly the same
|
|
columns and in the same order.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Require that the old and new tables have exactly matching columns</span> <span class="cwebmacronumber">20.10.4.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">mismatch</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">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain"> != </span><span class="identifier">old_t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">) </span><span class="identifier">mismatch</span><span class="plain"> = </span><span class="identifier">TRUE</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="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="identifier">old_t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">; </span><span class="identifier">j</span><span class="plain">++)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">old_to_new</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">] != </span><span class="identifier">j</span><span class="plain">)</span>
|
|
<span class="identifier">mismatch</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">mismatch</span><span class="plain">) {</span>
|
|
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_created_at</span><span class="plain">-</span><span class="element">>source_table</span><span class="plain">;</span>
|
|
<span class="functiontext">Problems::quote_table</span><span class="plain">(1, </span><span class="identifier">t</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_table</span><span class="plain">(2, </span><span class="identifier">old_t</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableAmendmentMisfit</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"Columns in %1 do not exactly match the original %2. I can only "</span>
|
|
<span class="string">"make changes to rows in an existing table if the amended versions "</span>
|
|
<span class="string">"have the same columns and in the same order."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<<span class="cwebmacro">Display the old and new table column names</span> <span class="cwebmacronumber">20.10.2.2.1</span>><span class="plain">;</span>
|
|
<span class="identifier">DESTROY</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">table</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20_10_4">§20.10.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_10_2_2_1"></a><b>§20.10.2.2.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Display the old and new table column names</span> <span class="cwebmacronumber">20.10.2.2.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">Problems::issue_problem_begin</span><span class="plain">(</span><span class="string">"****"</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"The old table has columns: "</span><span class="plain">); {</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">TEMP</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="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="identifier">old_t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">; </span><span class="identifier">j</span><span class="plain">++) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">j</span><span class="plain"> > 0) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">, </span><span class="string">", "</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">, </span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">Nouns::nominative</span><span class="plain">(</span><span class="identifier">old_t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">-</span><span class="element">>name</span><span class="plain">));</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">, </span><span class="string">". "</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_segment_from_stream</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="identifier">Problems::issue_problem_begin</span><span class="plain">(</span><span class="string">"****"</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"The new table has columns: "</span><span class="plain">); {</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">TEMP</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">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="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</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">i</span><span class="plain"> > 0) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">, </span><span class="string">", "</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">, </span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">Nouns::nominative</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">-</span><span class="element">>name</span><span class="plain">));</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">, </span><span class="string">"."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_segment_from_stream</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">);</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="#SP20_10_2_2">§20.10.2.2</a>, <a href="#SP20_10_3_2">§20.10.3.2</a>, <a href="#SP20_10_4_1">§20.10.4.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP21"></a><b>§21. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Tables::empty_cell_node</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">PN</span><span class="plain">;</span>
|
|
<span class="identifier">PN</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="identifier">PROPER_NOUN_NT</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">PN</span><span class="plain">, </span><span class="identifier">nounphrase_article_ANNOT</span><span class="plain">, </span><span class="identifier">NO_ART</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">PN</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Tables::empty_cell_node is used in <a href="#SP20_9_3">§20.9.3</a>, <a href="#SP20_10_2">§20.10.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP22"></a><b>§22. Table stocking. </b>See also the corresponding code in "Table Sections".
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Note that the first column plays a special role in tables used to define new
|
|
constants, because it holds the names of things which don't exist yet — the
|
|
things to be defined. So we exempt it from the checking below.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Tables::stock_table</span><span class="plain">(</span><span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">phase</span><span class="plain">) {</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TABLES</span><span class="plain">, </span><span class="string">"Stocking $B (%d cols): phase %d\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">, </span><span class="identifier">phase</span><span class="plain">);</span>
|
|
<span class="identifier">table_being_examined</span><span class="plain"> = </span><span class="identifier">t</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="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>first_column_by_definition</span><span class="plain">) </span><span class="identifier">i</span><span class="plain"> = 1;</span>
|
|
<span class="reserved">for</span><span class="plain"> (; </span><span class="identifier">i</span><span class="plain"><</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
|
|
<span class="reserved">table_column_usage</span><span class="plain"> *</span><span class="identifier">tcu</span><span class="plain"> = &(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]);</span>
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">phase</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> 1:</span>
|
|
<span class="identifier">tcu</span><span class="plain">-</span><span class="element">>kind_name_entries</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">tcu</span><span class="plain">-</span><span class="element">>actual_constant_entries</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">tcu</span><span class="plain">-</span><span class="element">>observed_constant_cell</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="functiontext">Tables::Columns::check_explicit_headings</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">tcu</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> 2: {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">row_count</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">PN</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">PN</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.entries</span><span class="plain">-</span><span class="element">>down</span><span class="plain">, </span><span class="identifier">row_count</span><span class="plain"> = 1; </span><span class="identifier">PN</span><span class="plain">; </span><span class="identifier">PN</span><span class="plain"> = </span><span class="identifier">PN</span><span class="plain">-</span><span class="element">>next</span><span class="plain">, </span><span class="identifier">row_count</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">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">PN</span><span class="plain">))) </span> <span class="comment">if there's anything written there at all</span>
|
|
<span class="functiontext">Tables::stock_table_cell</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">PN</span><span class="plain">, </span><span class="identifier">row_count</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">case</span><span class="plain"> 3: </span><span class="functiontext">Tables::Columns::approve_kind</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">tcu</span><span class="plain">);</span>
|
|
<span class="reserved">break</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 Tables::stock_table is used in <a href="#SP7">§7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP23"></a><b>§23. </b>All of that is delegated to "Table Columns" except for the <code class="display"><span class="extract">Tables::stock_table_cell</span></code>
|
|
routine, which comes next. It will parse the text of the entry in a cell
|
|
and act accordingly; the grammar returns one of the following:
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">BLANK_TABLE_ENTRY</span><span class="plain"> 1</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">SPEC_TABLE_ENTRY</span><span class="plain"> 2</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">ACTION_TABLE_ENTRY</span><span class="plain"> 3</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">TOPIC_TABLE_ENTRY</span><span class="plain"> 4</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">INSTANCE_TABLE_ENTRY</span><span class="plain"> 5</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">KIND_TABLE_ENTRY</span><span class="plain"> 6</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">NAMED_CONSTANT_ENTRY</span><span class="plain"> 7</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">PROBLEMATIC_TABLE_ENTRY</span><span class="plain"> -1</span>
|
|
</pre>
|
|
<p class="inwebparagraph"><a id="SP24"></a><b>§24. </b>Every cell of every table is required to match the following. Perhaps
|
|
unexpectedly, the syntax doesn't require each entry to be a valid Inform
|
|
constant; entries can also be blanks, or names of kinds (thus specifying the
|
|
kind of the table but not the contents), and there are special arrangements
|
|
for grammar to be understood (in "topic" columns) and for actions written as
|
|
constants.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Despite appearances, fully general type expressions (such as "open doors", or
|
|
"number of women") can't legally appear in table cells. The contents have
|
|
to be constants; the grammar lets more general text through only to let
|
|
us issue more contextual problem messages.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"><</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">cell</span><span class="plain">> ::=</span>
|
|
<span class="plain"><</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">cell</span><span class="plain">-</span><span class="identifier">blank</span><span class="plain">> | ==> </span><<span class="cwebmacro">Make anomalous entry for blank</span> <span class="cwebmacronumber">24.1</span>>
|
|
<span class="plain"><</span><span class="identifier">k</span><span class="plain">-</span><span class="identifier">kind</span><span class="plain">-</span><span class="identifier">articled</span><span class="plain">> | ==> </span><<span class="cwebmacro">Make anomalous entry for kind</span> <span class="cwebmacronumber">24.2</span>>
|
|
<span class="plain"><</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">named</span><span class="plain">-</span><span class="identifier">constant</span><span class="plain">> | ==> </span><span class="constant">NAMED_CONSTANT_ENTRY</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"><</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">global</span><span class="plain">-</span><span class="identifier">variable</span><span class="plain">> | ==> </span><<span class="cwebmacro">Issue PM_TablePlayerEntry or C20TableVariableEntry problem</span> <span class="cwebmacronumber">24.5</span>>
|
|
<span class="plain"><</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">cell</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">> | ==> </span><span class="identifier">R</span><span class="plain">[1]; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">RP</span><span class="plain">[1]</span>
|
|
<span class="plain"><</span><span class="identifier">list</span><span class="plain">-</span><span class="identifier">of</span><span class="plain">-</span><span class="reserved">double</span><span class="plain">-</span><span class="identifier">quotes</span><span class="plain">> | ==> </span><<span class="cwebmacro">Make anomalous entry for text to be understood</span> <span class="cwebmacronumber">24.3</span>>
|
|
<span class="plain">... ==> </span><<span class="cwebmacro">Issue PM_TableUnknownEntry problem</span> <span class="cwebmacronumber">24.6</span>>
|
|
|
|
<span class="plain"><</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">cell</span><span class="plain">-</span><span class="identifier">blank</span><span class="plain">> ::=</span>
|
|
<span class="plain">--</span>
|
|
|
|
<span class="plain"><</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">cell</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">> ::=</span>
|
|
<span class="identifier">the</span><span class="plain"> </span><span class="identifier">action</span><span class="plain"> </span><span class="identifier">of</span><span class="plain"> <</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">constant</span><span class="plain">-</span><span class="identifier">action</span><span class="plain">> | ==> </span><span class="constant">ACTION_TABLE_ENTRY</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"><</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">constant</span><span class="plain">-</span><span class="identifier">action</span><span class="plain">> | ==> </span><span class="constant">ACTION_TABLE_ENTRY</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="identifier">the</span><span class="plain"> </span><span class="identifier">action</span><span class="plain"> </span><span class="identifier">of</span><span class="plain"> <</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">explicit</span><span class="plain">-</span><span class="identifier">action</span><span class="plain">> | ==> </span><<span class="cwebmacro">Issue PM_NonconstantActionInTable problem</span> <span class="cwebmacronumber">24.4</span>>
|
|
<span class="plain"><</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">explicit</span><span class="plain">-</span><span class="identifier">action</span><span class="plain">> | ==> </span><<span class="cwebmacro">Issue PM_NonconstantActionInTable problem</span> <span class="cwebmacronumber">24.4</span>>
|
|
<span class="plain"><</span><span class="reserved">instance</span><span class="plain">-</span><span class="identifier">of</span><span class="plain">-</span><span class="identifier">non</span><span class="plain">-</span><span class="identifier">object</span><span class="plain">> | ==> </span><span class="constant">INSTANCE_TABLE_ENTRY</span><span class="plain">; *</span><span class="identifier">XP</span><span class="plain"> = </span><span class="functiontext">Rvalues::from_instance</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[1])</span>
|
|
<span class="plain"><</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">type</span><span class="plain">-</span><span class="identifier">expression</span><span class="plain">> ==> </span><span class="constant">SPEC_TABLE_ENTRY</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"><</span><span class="identifier">list</span><span class="plain">-</span><span class="identifier">of</span><span class="plain">-</span><span class="reserved">double</span><span class="plain">-</span><span class="identifier">quotes</span><span class="plain">> ::=</span>
|
|
<span class="plain"><</span><span class="identifier">quoted</span><span class="plain">-</span><span class="identifier">text</span><span class="plain">> </span><span class="identifier">or</span><span class="plain"> <</span><span class="identifier">list</span><span class="plain">-</span><span class="identifier">of</span><span class="plain">-</span><span class="reserved">double</span><span class="plain">-</span><span class="identifier">quotes</span><span class="plain">> |</span>
|
|
<span class="plain"><</span><span class="identifier">quoted</span><span class="plain">-</span><span class="identifier">text</span><span class="plain">></span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24_1"></a><b>§24.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Make anomalous entry for blank</span> <span class="cwebmacronumber">24.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = </span><span class="constant">BLANK_TABLE_ENTRY</span><span class="plain">;</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="endnote">This code is used in <a href="#SP24">§24</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24_2"></a><b>§24.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Make anomalous entry for kind</span> <span class="cwebmacronumber">24.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = </span><span class="constant">KIND_TABLE_ENTRY</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">new</span><span class="plain"> = </span><span class="functiontext">Specifications::from_kind</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[1]);</span>
|
|
<span class="identifier">ParseTree::set_text</span><span class="plain">(</span><span class="identifier">new</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
|
|
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">new</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP24">§24</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24_3"></a><b>§24.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Make anomalous entry for text to be understood</span> <span class="cwebmacronumber">24.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = </span><span class="constant">TOPIC_TABLE_ENTRY</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">new</span><span class="plain"> = </span><span class="functiontext">Specifications::from_kind</span><span class="plain">(</span><span class="identifier">K_text</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::set_text</span><span class="plain">(</span><span class="identifier">new</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
|
|
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">new</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP24">§24</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24_4"></a><b>§24.4. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Issue PM_NonconstantActionInTable problem</span> <span class="cwebmacronumber">24.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = </span><span class="constant">PROBLEMATIC_TABLE_ENTRY</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">quoted_col</span><span class="plain"> = </span><span class="identifier">table_cell_col</span><span class="plain"> + 1; </span> <span class="comment">i.e., counting from 1</span>
|
|
<span class="identifier">Problems::quote_number</span><span class="plain">(4, &</span><span class="identifier">quoted_col</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_wording</span><span class="plain">(5,</span>
|
|
<span class="identifier">Nouns::nominative</span><span class="plain">(</span><span class="identifier">table_being_examined</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">table_cell_col</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">-</span><span class="element">>name</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::quote_number</span><span class="plain">(6, &</span><span class="identifier">table_cell_row</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::Issue::table_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_NonconstantActionInTable</span><span class="plain">),</span>
|
|
<span class="identifier">table_being_examined</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">table_cell_node</span><span class="plain">,</span>
|
|
<span class="string">"In %1, I'm reading the text %3 in column %4 (%5) of row %6, but this is "</span>
|
|
<span class="string">"an action involving a variable, that is, a value that might vary in play. "</span>
|
|
<span class="string">"%PThis often happens if the action mentions 'the player', for example, "</span>
|
|
<span class="string">"because 'the player' is a variable. If 'the player' is the person "</span>
|
|
<span class="string">"carrying out the action, simply leave those words out; if 'the player' "</span>
|
|
<span class="string">"is involved in some other way, try using 'yourself' instead."</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP24">§24</a> (twice).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24_5"></a><b>§24.5. </b>The message PM_TablePlayerEntry is so called because by far the commonest
|
|
case of this is people writing "player" as a constant value in a column of
|
|
people — it needs to be "yourself" instead, since "player" is a variable.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Issue PM_TablePlayerEntry or C20TableVariableEntry problem</span> <span class="cwebmacronumber">24.5</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = </span><span class="constant">PROBLEMATIC_TABLE_ENTRY</span><span class="plain">;</span>
|
|
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">q</span><span class="plain"> = </span><span class="functiontext">Lvalues::get_nonlocal_variable_if_any</span><span class="plain">(</span><span class="identifier">RP</span><span class="plain">[1]);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">q</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">"no such variable"</span><span class="plain">);</span>
|
|
<span class="reserved">inference_subject</span><span class="plain"> *</span><span class="identifier">infs</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::get_alias</span><span class="plain">(</span><span class="identifier">q</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">infs</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">quoted_col</span><span class="plain"> = </span><span class="identifier">table_cell_col</span><span class="plain"> + 1; </span> <span class="comment">i.e., counting from 1</span>
|
|
<span class="identifier">Problems::quote_number</span><span class="plain">(4, &</span><span class="identifier">quoted_col</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_wording</span><span class="plain">(5,</span>
|
|
<span class="identifier">Nouns::nominative</span><span class="plain">(</span><span class="identifier">table_being_examined</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">table_cell_col</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">-</span><span class="element">>name</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::quote_number</span><span class="plain">(6, &</span><span class="identifier">table_cell_row</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_subject</span><span class="plain">(7, </span><span class="identifier">infs</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::Issue::table_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TablePlayerEntry</span><span class="plain">),</span>
|
|
<span class="identifier">table_being_examined</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">table_cell_node</span><span class="plain">,</span>
|
|
<span class="string">"In %1, the entry %3 in column %4 (%5) of row %6 is the name of a value "</span>
|
|
<span class="string">"which varies, not a constant, and can't be stored as a table entry. %P"</span>
|
|
<span class="string">"This variable is usually set to the constant value '%7', so you might "</span>
|
|
<span class="string">"want to write that instead."</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">quoted_col</span><span class="plain"> = </span><span class="identifier">table_cell_col</span><span class="plain"> + 1; </span> <span class="comment">i.e., counting from 1</span>
|
|
<span class="identifier">Problems::quote_number</span><span class="plain">(4, &</span><span class="identifier">quoted_col</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_wording</span><span class="plain">(5,</span>
|
|
<span class="identifier">Nouns::nominative</span><span class="plain">(</span><span class="identifier">table_being_examined</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">table_cell_col</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">-</span><span class="element">>name</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::quote_number</span><span class="plain">(6, &</span><span class="identifier">table_cell_row</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::Issue::table_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableVariableEntry</span><span class="plain">),</span>
|
|
<span class="identifier">table_being_examined</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">table_cell_node</span><span class="plain">,</span>
|
|
<span class="string">"In %1, the entry %3 in column %4 (%5) of row %6 is the name of a value "</span>
|
|
<span class="string">"which varies, not a constant, so it can't be stored as a table entry."</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP24">§24</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24_6"></a><b>§24.6. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Issue PM_TableUnknownEntry problem</span> <span class="cwebmacronumber">24.6</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = </span><span class="constant">PROBLEMATIC_TABLE_ENTRY</span><span class="plain">;</span>
|
|
<<span class="cwebmacro">Actually issue PM_TableUnknownEntry problem</span> <span class="cwebmacronumber">24.6.1</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP24">§24</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24_6_1"></a><b>§24.6.1. </b>(There are actually two ways this can happen, which is why it's set out like this.)
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Actually issue PM_TableUnknownEntry problem</span> <span class="cwebmacronumber">24.6.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">quoted_col</span><span class="plain"> = </span><span class="identifier">table_cell_col</span><span class="plain"> + 1; </span> <span class="comment">i.e., counting from 1</span>
|
|
<span class="identifier">Problems::quote_number</span><span class="plain">(4, &</span><span class="identifier">quoted_col</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_wording</span><span class="plain">(5,</span>
|
|
<span class="identifier">Nouns::nominative</span><span class="plain">(</span><span class="identifier">table_being_examined</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">table_cell_col</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">-</span><span class="element">>name</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::quote_number</span><span class="plain">(6, &</span><span class="identifier">table_cell_row</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::Issue::table_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableUnknownEntry</span><span class="plain">),</span>
|
|
<span class="identifier">table_being_examined</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">table_cell_node</span><span class="plain">,</span>
|
|
<span class="string">"In %1, I'm reading the text %3 in column %4 (%5) of row %6, but I don't "</span>
|
|
<span class="string">"know what this means. %PThis should usually be a value, like a number "</span>
|
|
<span class="string">"or a piece of text, or a blank entry marker '--', but in some circumstances "</span>
|
|
<span class="string">"it can also be an action (such as 'taking the box'), or a kind (such as "</span>
|
|
<span class="string">"'a number') to show what sort of values will go into an otherwise blank "</span>
|
|
<span class="string">"row."</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP24_6">§24.6</a>, <a href="#SP25_2">§25.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP25"></a><b>§25. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Tables::stock_table_cell</span><span class="plain">(</span><span class="reserved">table</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">cell</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">row_count</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">col_count</span><span class="plain">) {</span>
|
|
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">cell</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">topic_exception</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">table_cell_node</span><span class="plain"> = </span><span class="identifier">cell</span><span class="plain">;</span>
|
|
<span class="identifier">table_cell_row</span><span class="plain"> = </span><span class="identifier">row_count</span><span class="plain">;</span>
|
|
<span class="identifier">table_cell_col</span><span class="plain"> = </span><span class="identifier">col_count</span><span class="plain">;</span>
|
|
|
|
<<span class="cwebmacro">Parse the table cell and give it an evaluation as a noun</span> <span class="cwebmacronumber">25.1</span>><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">evaluation</span><span class="plain"> = </span><span class="identifier">ParseTree::get_evaluation</span><span class="plain">(</span><span class="identifier">cell</span><span class="plain">);</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TABLES</span><span class="plain">, </span><span class="string">"Cell evaluates to: $P\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">evaluation</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">topic_exception</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><<span class="cwebmacro">Require the cell to evaluate to an actual constant</span> <span class="cwebmacronumber">25.2</span>><span class="plain">;</span>
|
|
|
|
<span class="functiontext">Tables::Columns::note_kind</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">col_count</span><span class="plain">, &(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">col_count</span><span class="plain">]), </span><span class="identifier">cell</span><span class="plain">, </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">evaluation</span><span class="plain">), </span><span class="identifier">FALSE</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Tables::stock_table_cell is used in <a href="#SP22">§22</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP25_1"></a><b>§25.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Parse the table cell and give it an evaluation as a noun</span> <span class="cwebmacronumber">25.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="plain"><</span><span class="reserved">table</span><span class="plain">-</span><span class="identifier">cell</span><span class="plain">>(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">cell</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">rp</span><span class="plain">>>;</span>
|
|
<span class="reserved">switch</span><span class="plain"> (<<</span><span class="identifier">r</span><span class="plain">>>) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">BLANK_TABLE_ENTRY</span><span class="plain">:</span>
|
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">cell</span><span class="plain">, </span><span class="constant">table_cell_unspecified_ANNOT</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="reserved">case</span><span class="plain"> </span><span class="constant">SPEC_TABLE_ENTRY</span><span class="plain">:</span>
|
|
<span class="functiontext">Assertions::Refiner::noun_from_value</span><span class="plain">(</span><span class="identifier">cell</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">NAMED_CONSTANT_ENTRY</span><span class="plain">:</span>
|
|
<span class="identifier">topic_exception</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="functiontext">Assertions::Refiner::noun_from_value</span><span class="plain">(</span><span class="identifier">cell</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">INSTANCE_TABLE_ENTRY</span><span class="plain">:</span>
|
|
<span class="functiontext">Assertions::Refiner::noun_from_value</span><span class="plain">(</span><span class="identifier">cell</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">KIND_TABLE_ENTRY</span><span class="plain">:</span>
|
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">cell</span><span class="plain">, </span><span class="constant">table_cell_unspecified_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
|
|
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
|
|
<span class="functiontext">Tables::Columns::note_kind</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">col_count</span><span class="plain">, &(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">col_count</span><span class="plain">]), </span><span class="identifier">cell</span><span class="plain">,</span>
|
|
<span class="identifier">K</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="reserved">case</span><span class="plain"> </span><span class="constant">ACTION_TABLE_ENTRY</span><span class="plain">:</span>
|
|
<span class="functiontext">Assertions::Refiner::noun_from_value</span><span class="plain">(</span><span class="identifier">cell</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">TOPIC_TABLE_ENTRY</span><span class="plain">:</span>
|
|
<span class="functiontext">Assertions::Refiner::noun_from_value</span><span class="plain">(</span><span class="identifier">cell</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
|
|
<span class="identifier">topic_exception</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="reserved">case</span><span class="plain"> </span><span class="constant">PROBLEMATIC_TABLE_ENTRY</span><span class="plain">:</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP25">§25</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP25_2"></a><b>§25.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Require the cell to evaluate to an actual constant</span> <span class="cwebmacronumber">25.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Specifications::is_kind_like</span><span class="plain">(</span><span class="identifier">evaluation</span><span class="plain">)) ||</span>
|
|
<span class="plain">(</span><span class="functiontext">Specifications::is_description</span><span class="plain">(</span><span class="identifier">evaluation</span><span class="plain">))) {</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Evaluation is $P\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">evaluation</span><span class="plain">);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">quoted_col</span><span class="plain"> = </span><span class="identifier">table_cell_col</span><span class="plain"> + 1; </span> <span class="comment">i.e., counting from 1</span>
|
|
<span class="identifier">Problems::quote_number</span><span class="plain">(4, &</span><span class="identifier">quoted_col</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_wording</span><span class="plain">(5,</span>
|
|
<span class="identifier">Nouns::nominative</span><span class="plain">(</span><span class="identifier">table_being_examined</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">table_cell_col</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">-</span><span class="element">>name</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::quote_number</span><span class="plain">(6, &</span><span class="identifier">table_cell_row</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::Issue::table_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableDescriptionEntry</span><span class="plain">),</span>
|
|
<span class="identifier">t</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">cell</span><span class="plain">,</span>
|
|
<span class="string">"In %1, the entry %3 in column %4 (%5) of row %6 is a general description "</span>
|
|
<span class="string">"of things with no definite value, and can't be stored as a table entry."</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">ParseTree::is</span><span class="plain">(</span><span class="identifier">evaluation</span><span class="plain">, </span><span class="constant">CONSTANT_NT</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Evaluation is $P\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">evaluation</span><span class="plain">);</span>
|
|
<<span class="cwebmacro">Actually issue PM_TableUnknownEntry problem</span> <span class="cwebmacronumber">24.6.1</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP25">§25</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP26"></a><b>§26. Completing tables. </b>Later on in Inform's run, just before compiling the tables, we call this:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Tables::complete</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<<span class="cwebmacro">Finally make any table amendments which have been called for</span> <span class="cwebmacronumber">26.1</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Create blank rows described textually, if they were</span> <span class="cwebmacronumber">26.2</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Create blank rows for each instance of a kind, if requested</span> <span class="cwebmacronumber">26.3</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Tables::complete is used in 1/mr (<a href="1-mr.html#SP4_14">§4.14</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP26_1"></a><b>§26.1. </b>For the actual code, see below.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Finally make any table amendments which have been called for</span> <span class="cwebmacronumber">26.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">table</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>amendment_of</span><span class="plain">)</span>
|
|
<span class="functiontext">Tables::amend_table</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>amendment_of</span><span class="plain">, </span><span class="identifier">t</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="SP26_2"></a><b>§26.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Create blank rows described textually, if they were</span> <span class="cwebmacronumber">26.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">table</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>amendment_of</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
|
|
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_created_at</span><span class="plain">-</span><span class="element">>source_table</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">t</span><span class="plain">-</span><span class="element">>blank_rows_text</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = -1;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</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">s</span><span class="plain">-</span><span class="identifier">named</span><span class="plain">-</span><span class="identifier">constant</span><span class="plain">>(</span><span class="identifier">W</span><span class="plain">)) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::substitute_constants</span><span class="plain">(<<</span><span class="identifier">rp</span><span class="plain">>>);</span>
|
|
<span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_int</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> >= 0) </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows</span><span class="plain"> = </span><span class="identifier">N</span><span class="plain">;</span>
|
|
<span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">Problems::quote_wording</span><span class="plain">(4, </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows_text</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::Issue::table_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableUnknownBlanks</span><span class="plain">),</span>
|
|
<span class="identifier">t</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">current_sentence</span><span class="plain">,</span>
|
|
<span class="string">"%1 asked to have '%4' extra blank rows, but that would "</span>
|
|
<span class="string">"only make sense for a literal number like '15' or a "</span>
|
|
<span class="string">"name for a constant number. (The number must of course "</span>
|
|
<span class="string">"be 0 or more.)"</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">This code is used in <a href="#SP26">§26</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP26_3"></a><b>§26.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Create blank rows for each instance of a kind, if requested</span> <span class="cwebmacronumber">26.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">table</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>amendment_of</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
|
|
<span class="identifier">current_sentence</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_created_at</span><span class="plain">-</span><span class="element">>source_table</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">t</span><span class="plain">-</span><span class="element">>blank_rows_for_each_text</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">NULL</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">kind</span><span class="plain">>(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows_for_each_text</span><span class="plain">)) {</span>
|
|
<span class="identifier">K</span><span class="plain"> = <<</span><span class="identifier">rp</span><span class="plain">>>;</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows</span><span class="plain"> += </span><span class="functiontext">Instances::count</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">Problems::quote_wording</span><span class="plain">(4, </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows_for_each_text</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::Issue::table_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableKindlessBlanks</span><span class="plain">),</span>
|
|
<span class="identifier">t</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">current_sentence</span><span class="plain">,</span>
|
|
<span class="string">"%1 asked to have extra blank rows for each '%4', but that "</span>
|
|
<span class="string">"isn't a kind, so I can't see how many blank rows to make."</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">This code is used in <a href="#SP26">§26</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP27"></a><b>§27. Amending tables. </b>Unlike continuations and replacements, table amendments depend on actual values
|
|
written into the cells, which means they can't be performed early in the run.
|
|
So for quite a long time two table structures exist: the "main table", the
|
|
actual one which will exist in play; and the "amendments" table, which is a
|
|
structure holding the amendment lines, but which won't actually exist
|
|
independently at run-time. The following routine is where the rows from the
|
|
amendments table are used to modify the main table, after which the amendments
|
|
table has no further use.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">As might be expected, we work down the amendments table and apply them one
|
|
at a time:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Tables::amend_table</span><span class="plain">(</span><span class="reserved">table</span><span class="plain"> *</span><span class="identifier">main_table</span><span class="plain">, </span><span class="reserved">table</span><span class="plain"> *</span><span class="identifier">amendments</span><span class="plain">) {</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TABLES</span><span class="plain">, </span><span class="string">"Amending table $B according to $B\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">main_table</span><span class="plain">, </span><span class="identifier">amendments</span><span class="plain">);</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">leftmost_amend_cell</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">amend_row</span><span class="plain"> = 1, </span><span class="identifier">amendment_problem_opened</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="identifier">amend_row</span><span class="plain"> = 1, </span><span class="identifier">leftmost_amend_cell</span><span class="plain"> = </span><span class="identifier">amendments</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[0]</span><span class="element">.entries</span><span class="plain">-</span><span class="element">>down</span><span class="plain">;</span>
|
|
<span class="identifier">leftmost_amend_cell</span><span class="plain">;</span>
|
|
<span class="identifier">amend_row</span><span class="plain">++, </span><span class="identifier">leftmost_amend_cell</span><span class="plain"> = </span><span class="identifier">leftmost_amend_cell</span><span class="plain">-</span><span class="element">>next</span><span class="plain">)</span>
|
|
<<span class="cwebmacro">Apply the amendment in this row to the main table</span> <span class="cwebmacronumber">27.1</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Tables::amend_table is used in <a href="#SP26_1">§26.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP27_1"></a><b>§27.1. </b>The following is not so obvious. The amendment row is intended to replace a
|
|
row in the main table, and we need to decide which one. Suppose the amendment
|
|
reads:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">62 "lampstand" 10:30 AM</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">If the main table has exactly one row with 62 in the first column, we choose
|
|
that; if it contains more than one, we look for rows which begin with
|
|
<code class="display"><span class="extract">62</span></code> and then <code class="display"><span class="extract">"lampstand"</span></code>; and so on. (Recall that amendment tables have
|
|
exactly the same columns as their originals, and in the same order.)
|
|
</p>
|
|
|
|
<p class="inwebparagraph">In the following, <code class="display"><span class="extract">col</span></code> is the rightmost column used in the initial string
|
|
being tried: so when it's 0, we're just trying to match <code class="display"><span class="extract">62</span></code>, when it's 1
|
|
we're trying to match <code class="display"><span class="extract">62</span></code> and <code class="display"><span class="extract">"lampstand"</span></code>; and so on. But of course each
|
|
such search is narrower than the one before, so we only need to look at the
|
|
rows which passed last time, and test their values in column <code class="display"><span class="extract">col</span></code>.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">In fact, we do this in reverse: we start with every row in the main table
|
|
marked as a possible match, and then exclude rows as they fail to match.
|
|
Eventually this should leave only a single row, and that's the winner.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Apply the amendment in this row to the main table</span> <span class="cwebmacronumber">27.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">col</span><span class="plain">, </span><span class="identifier">matches_in_last_round</span><span class="plain"> = 0;</span>
|
|
<<span class="cwebmacro">Mark every row in the main table as a possible match</span> <span class="cwebmacronumber">27.1.1</span>><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">col</span><span class="plain"> = 0; </span><span class="identifier">col</span><span class="plain"> < </span><span class="identifier">main_table</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">; </span><span class="identifier">col</span><span class="plain">++) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">amend_cell</span><span class="plain">;</span>
|
|
<<span class="cwebmacro">Set the amend-cell to this column's cell in the current amendment row</span> <span class="cwebmacronumber">27.1.2</span>><span class="character">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">amend_cell</span><span class="plain">, </span><span class="constant">table_cell_unspecified_ANNOT</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">only_row_left</span><span class="plain"> = -1;</span>
|
|
<<span class="cwebmacro">Use the key value in the amend-cell to make an amendment</span> <span class="cwebmacronumber">27.1.3</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">only_row_left</span><span class="plain"> >= 0) {</span>
|
|
<span class="functiontext">Tables::splice_table_row</span><span class="plain">(</span><span class="identifier">main_table</span><span class="plain">, </span><span class="identifier">amendments</span><span class="plain">, </span><span class="identifier">only_row_left</span><span class="plain">, </span><span class="identifier">amend_row</span><span class="plain">);</span>
|
|
<span class="reserved">break</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">This code is used in <a href="#SP27">§27</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP27_1_1"></a><b>§27.1.1. </b>We need one flag for each row in the main table; we do this with the "row
|
|
amendable" annotation for the cell nodes in the first column. (There's nothing
|
|
special about the first column, but it's guaranteed to exist, i.e., there is
|
|
always at least one column.)
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Mark every row in the main table as a possible match</span> <span class="cwebmacronumber">27.1.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">leftmost_cell</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">leftmost_cell</span><span class="plain"> = </span><span class="identifier">main_table</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[0]</span><span class="element">.entries</span><span class="plain">-</span><span class="element">>down</span><span class="plain">;</span>
|
|
<span class="identifier">leftmost_cell</span><span class="plain">;</span>
|
|
<span class="identifier">leftmost_cell</span><span class="plain"> = </span><span class="identifier">leftmost_cell</span><span class="plain">-</span><span class="element">>next</span><span class="plain">) {</span>
|
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">leftmost_cell</span><span class="plain">, </span><span class="constant">row_amendable_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
|
|
<span class="identifier">matches_in_last_round</span><span class="plain">++;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP27_1">§27.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP27_1_2"></a><b>§27.1.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Set the amend-cell to this column's cell in the current amendment row</span> <span class="cwebmacronumber">27.1.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> = 1, </span><span class="identifier">amend_cell</span><span class="plain"> = </span><span class="identifier">amendments</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">col</span><span class="plain">]</span><span class="element">.entries</span><span class="plain">-</span><span class="element">>down</span><span class="plain">;</span>
|
|
<span class="identifier">amend_cell</span><span class="plain"> && (</span><span class="identifier">i</span><span class="plain"> < </span><span class="identifier">amend_row</span><span class="plain">); </span><span class="identifier">i</span><span class="plain">++, </span><span class="identifier">amend_cell</span><span class="plain"> = </span><span class="identifier">amend_cell</span><span class="plain">-</span><span class="element">>next</span><span class="plain">) ;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">amend_cell</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">"columns in amendments aren't equal in length"</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP27_1">§27.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP27_1_3"></a><b>§27.1.3. </b>When we get here, then, we look at the key value in the amend-cell: suppose
|
|
this is the number 17. If there's no row in the main table having 17 in this
|
|
column, we're stuck. But if there are two or more, we allow the loop to move
|
|
us along to the next column, hoping that the key value there will find a
|
|
unique match. If we're in the last column and there are still multiple
|
|
possibilities, the amendment row must be identical to more than one row
|
|
of the main table — in this case the amendment will have no effect, but
|
|
put another way, it can do no harm.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Use the key value in the amend-cell to make an amendment</span> <span class="cwebmacronumber">27.1.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">amend_key</span><span class="plain"> = </span><span class="identifier">ParseTree::get_evaluation</span><span class="plain">(</span><span class="identifier">amend_cell</span><span class="plain">);</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">TABLES</span><span class="plain">, </span><span class="string">"Amend row %d, col %d, key $P: $T\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">amend_row</span><span class="plain">, </span><span class="identifier">col</span><span class="plain">, </span><span class="identifier">amend_key</span><span class="plain">, </span><span class="identifier">amend_cell</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">amend_key</span><span class="plain">, </span><span class="constant">CONSTANT_NT</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"bad key in amendments table"</span><span class="plain">); </span> <span class="comment">code above should make this impossible</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">matches</span><span class="plain"> = 0;</span>
|
|
<<span class="cwebmacro">Find the number of possible-match rows in the main table with this key value in the same column</span> <span class="cwebmacronumber">27.1.3.1</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">matches</span><span class="plain"> == 0) </span><<span class="cwebmacro">Issue problem to say that no row in the main table matches</span> <span class="cwebmacronumber">27.1.3.2</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">matches</span><span class="plain"> > 1) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">col</span><span class="plain"> < </span><span class="identifier">main_table</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain"> - 1) </span> <span class="comment">i.e., if we haven't reached the final column</span>
|
|
<span class="identifier">only_row_left</span><span class="plain"> = -1; </span> <span class="comment">because there's no single row left</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">matches_in_last_round</span><span class="plain"> = </span><span class="identifier">matches</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP27_1">§27.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP27_1_3_1"></a><b>§27.1.3.1. </b>The loop below and its inner conditional look pretty forbidding, but they
|
|
come down to this: loop through each row of the main table which is still a
|
|
possible match.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Find the number of possible-match rows in the main table with this key value in the same column</span> <span class="cwebmacronumber">27.1.3.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">row</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">leftmost_cell</span><span class="plain">;</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">main_cell</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">row</span><span class="plain"> = 1,</span>
|
|
<span class="identifier">main_cell</span><span class="plain"> = </span><span class="identifier">main_table</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">col</span><span class="plain">]</span><span class="element">.entries</span><span class="plain">-</span><span class="element">>down</span><span class="plain">,</span>
|
|
<span class="identifier">leftmost_cell</span><span class="plain"> = </span><span class="identifier">main_table</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[0]</span><span class="element">.entries</span><span class="plain">-</span><span class="element">>down</span><span class="plain">;</span>
|
|
<span class="identifier">main_cell</span><span class="plain">;</span>
|
|
<span class="identifier">row</span><span class="plain">++,</span>
|
|
<span class="identifier">main_cell</span><span class="plain"> = </span><span class="identifier">main_cell</span><span class="plain">-</span><span class="element">>next</span><span class="plain">,</span>
|
|
<span class="identifier">leftmost_cell</span><span class="plain"> = </span><span class="identifier">leftmost_cell</span><span class="plain">-</span><span class="element">>next</span><span class="plain">) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">main_value</span><span class="plain"> = </span><span class="identifier">ParseTree::get_evaluation</span><span class="plain">(</span><span class="identifier">main_cell</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">leftmost_cell</span><span class="plain">, </span><span class="constant">row_amendable_ANNOT</span><span class="plain">))</span>
|
|
<<span class="cwebmacro">See if this possible-match row has the right key value in the new column</span> <span class="cwebmacronumber">27.1.3.1.1</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP27_1_3">§27.1.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP27_1_3_1_1"></a><b>§27.1.3.1.1. </b>We not only record the result if there's a match; we kick the row out of the
|
|
possible-match set if there isn't.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">See if this possible-match row has the right key value in the new column</span> <span class="cwebmacronumber">27.1.3.1.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Key in row %d is $P\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">row</span><span class="plain">, </span><span class="identifier">main_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">main_value</span><span class="plain">, </span><span class="constant">CONSTANT_NT</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">Rvalues::compare_CONSTANT</span><span class="plain">(</span><span class="identifier">amend_key</span><span class="plain">, </span><span class="identifier">main_value</span><span class="plain">))) {</span>
|
|
<span class="identifier">matches</span><span class="plain">++;</span>
|
|
<span class="identifier">only_row_left</span><span class="plain"> = </span><span class="identifier">row</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">leftmost_cell</span><span class="plain">, </span><span class="constant">row_amendable_ANNOT</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP27_1_3_1">§27.1.3.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP27_1_3_2"></a><b>§27.1.3.2. </b>That just leaves the problem message, a very subtle one which took a long
|
|
time to find a clear wording for:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Issue problem to say that no row in the main table matches</span> <span class="cwebmacronumber">27.1.3.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<<span class="cwebmacro">Begin an amendment problem message</span> <span class="cwebmacronumber">27.1.3.2.1</span>><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">quoted_col</span><span class="plain"> = </span><span class="identifier">col</span><span class="plain"> + 1; </span> <span class="comment">i.e., counting from 1, not 0</span>
|
|
<span class="identifier">Problems::quote_number</span><span class="plain">(1, &</span><span class="identifier">amend_row</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_number</span><span class="plain">(2, &</span><span class="identifier">quoted_col</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_source</span><span class="plain">(3, </span><span class="identifier">amend_cell</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_wording</span><span class="plain">(4, </span><span class="identifier">Nouns::nominative</span><span class="plain">(</span><span class="identifier">main_table</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">col</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">-</span><span class="element">>name</span><span class="plain">));</span>
|
|
<span class="functiontext">Problems::quote_table</span><span class="plain">(5, </span><span class="identifier">main_table</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::quote_number</span><span class="plain">(6, &</span><span class="identifier">matches_in_last_round</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">matches_in_last_round</span><span class="plain"> > 2) </span><span class="identifier">Problems::quote_text</span><span class="plain">(7, </span><span class="string">"any"</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Problems::quote_text</span><span class="plain">(7, </span><span class="string">"either"</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_begin</span><span class="plain">(</span><span class="string">"****"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">col</span><span class="plain"> == 0)</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"(Amendment %1). I can't match this to any row - there's nothing with "</span>
|
|
<span class="string">"an entry of %3 in the lefthand column (%4)."</span><span class="plain">);</span>
|
|
<span class="reserved">else</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"(Amendment %1). I can't decide which row this should replace. "</span>
|
|
<span class="string">"It matches %6 rows until I get up to column %2 (%4), but then "</span>
|
|
<span class="string">"it reads %3, which is different from %7 of them."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="reserved">break</span><span class="plain">; </span> <span class="comment">to move on to the next row in the amendments</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP27_1_3">§27.1.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP27_1_3_2_1"></a><b>§27.1.3.2.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Begin an amendment problem message</span> <span class="cwebmacronumber">27.1.3.2.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">amendment_problem_opened</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
|
|
<span class="identifier">amendment_problem_opened</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">amendments</span><span class="plain">-</span><span class="element">>table_created_at</span><span class="plain">-</span><span class="element">>source_table</span><span class="plain">;</span>
|
|
<span class="functiontext">Problems::quote_table</span><span class="plain">(1, </span><span class="identifier">main_table</span><span class="plain">);</span>
|
|
<span class="functiontext">Problems::quote_table</span><span class="plain">(2, </span><span class="identifier">amendments</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_TableAmendmentMismatch</span><span class="plain">));</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
|
|
<span class="string">"I'm currently trying to amend rows in %1 according to the instructions "</span>
|
|
<span class="string">"in %2. To do that, I have to match each amendment row in turn, which "</span>
|
|
<span class="string">"I do by trying to match up entries in the leftmost column(s)."</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="identifier">Problems::issue_problem_begin</span><span class="plain">(</span><span class="string">"****"</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span><span class="string">"But I ran into problems:"</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP27_1_3_2">§27.1.3.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP28"></a><b>§28. </b>And, of course, the actual splicing of the amendment row in place of the
|
|
original:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Tables::splice_table_row</span><span class="plain">(</span><span class="reserved">table</span><span class="plain"> *</span><span class="identifier">table_to</span><span class="plain">, </span><span class="reserved">table</span><span class="plain"> *</span><span class="identifier">table_from</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">row_to</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">row_from</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">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="identifier">table_to</span><span class="plain">-</span><span class="element">>no_columns</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">cell_to</span><span class="plain">, *</span><span class="identifier">cell_from</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">row</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">row</span><span class="plain"> = 1, </span><span class="identifier">cell_to</span><span class="plain"> = </span><span class="identifier">table_to</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.entries</span><span class="plain">-</span><span class="element">>down</span><span class="plain">;</span>
|
|
<span class="identifier">cell_to</span><span class="plain"> && (</span><span class="identifier">row</span><span class="plain"> < </span><span class="identifier">row_to</span><span class="plain">); </span><span class="identifier">cell_to</span><span class="plain"> = </span><span class="identifier">cell_to</span><span class="plain">-</span><span class="element">>next</span><span class="plain">, </span><span class="identifier">row</span><span class="plain">++) ;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">row</span><span class="plain"> = 1, </span><span class="identifier">cell_from</span><span class="plain"> = </span><span class="identifier">table_from</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.entries</span><span class="plain">-</span><span class="element">>down</span><span class="plain">;</span>
|
|
<span class="identifier">cell_from</span><span class="plain"> && (</span><span class="identifier">row</span><span class="plain"> < </span><span class="identifier">row_from</span><span class="plain">); </span><span class="identifier">cell_from</span><span class="plain"> = </span><span class="identifier">cell_from</span><span class="plain">-</span><span class="element">>next</span><span class="plain">, </span><span class="identifier">row</span><span class="plain">++) ;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">cell_to</span><span class="plain">) && (</span><span class="identifier">cell_from</span><span class="plain">)) {</span>
|
|
<span class="functiontext">Assertions::Refiner::copy_noun_details</span><span class="plain">(</span><span class="identifier">cell_to</span><span class="plain">, </span><span class="identifier">cell_from</span><span class="plain">);</span>
|
|
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">cell_to</span><span class="plain">, </span><span class="constant">table_cell_unspecified_ANNOT</span><span class="plain">,</span>
|
|
<span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">cell_from</span><span class="plain">, </span><span class="constant">table_cell_unspecified_ANNOT</span><span class="plain">));</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"bad table row splice"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Tables::splice_table_row is used in <a href="#SP27_1">§27.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP29"></a><b>§29. Indexing. </b>Tables inside extensions are often used just for the storage needed to manage
|
|
back-of-house algorithms, so to speak, and they aren't intended for the end
|
|
user to poke around with; that's certainly true of the tables in the Standard
|
|
Rules, which of course are always present. So these are hidden by default.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Tables::index</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">) {</span>
|
|
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">m</span><span class="plain"> = </span><span class="functiontext">Tables::index_tables_in</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, 0);</span>
|
|
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
|
|
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
|
|
<span class="identifier">Index::extra_link</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 2);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">m</span><span class="plain"> > 0) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Show tables inside extensions too"</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Show tables inside extensions (there are none in the main text)"</span><span class="plain">);</span>
|
|
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
|
|
<span class="identifier">Index::extra_div_open</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 2, 1, </span><span class="string">"e0e0e0"</span><span class="plain">);</span>
|
|
<span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">; </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">efc</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ef</span><span class="plain">, </span><span class="reserved">extension_file</span><span class="plain">) </span><span class="functiontext">Tables::index_tables_in</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">, </span><span class="identifier">efc</span><span class="plain">++);</span>
|
|
<span class="identifier">Index::extra_div_close</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="string">"e0e0e0"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Tables::index appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP30"></a><b>§30. </b>This tabulates tables within a given extension, returning the number listed,
|
|
and does nothing at all if that number is 0.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Tables::index_tables_in</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">efc</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">tc</span><span class="plain"> = 0; </span><span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">table</span><span class="plain">) </span><span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Tables::table_within</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">)) </span><span class="identifier">tc</span><span class="plain">++;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tc</span><span class="plain"> > 0) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ef</span><span class="plain">) {</span>
|
|
<span class="identifier">HTML_OPEN</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"<i>%+W</i>"</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">-</span><span class="element">>title_text</span><span class="plain">);</span>
|
|
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"p"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">HTML::begin_plain_html_table</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">table</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Tables::table_within</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">, </span><span class="identifier">ef</span><span class="plain">))</span>
|
|
<<span class="cwebmacro">Index this table</span> <span class="cwebmacronumber">30.1</span>><span class="plain">;</span>
|
|
<span class="identifier">HTML::end_html_table</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">tc</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Tables::index_tables_in is used in <a href="#SP29">§29</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP30_1"></a><b>§30.1. </b>The following probably ought to use a multiplication sign rather than a
|
|
Helvetica-style lower case "x", but life is full of compromises.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Index this table</span> <span class="cwebmacronumber">30.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">HTML::first_html_column_spaced</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"<b>%+W</b>"</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>headline_fragment</span><span class="plain">));</span>
|
|
<span class="reserved">table_contribution</span><span class="plain"> *</span><span class="identifier">tc</span><span class="plain">; </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">ntc</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">tc</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_created_at</span><span class="plain">; </span><span class="identifier">tc</span><span class="plain">; </span><span class="identifier">tc</span><span class="plain"> = </span><span class="identifier">tc</span><span class="plain">-</span><span class="element">>next</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ntc</span><span class="plain">++ > 0) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" +"</span><span class="plain">);</span>
|
|
<span class="identifier">Index::link</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">tc</span><span class="plain">-</span><span class="element">>source_table</span><span class="plain">)));</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">HTML::next_html_column_spaced</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rc</span><span class="plain"> = </span><span class="functiontext">Tables::get_no_rows</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"<i>"</span><span class="plain">);</span>
|
|
<span class="identifier">HTML_OPEN_WITH</span><span class="plain">(</span><span class="string">"span"</span><span class="plain">, </span><span class="string">"class=\</span><span class="plain">"</span><span class="string">smaller\</span><span class="plain">"</span><span class="string">"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>first_column_by_definition</span><span class="plain">) {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%d definition%s"</span><span class="plain">, </span><span class="identifier">rc</span><span class="plain">,</span>
|
|
<span class="plain">(</span><span class="identifier">rc</span><span class="plain"> == 1)?</span><span class="string">""</span><span class="plain">:</span><span class="string">"s"</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%d column%s x %d row%s"</span><span class="plain">,</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">, (</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain"> == 1)?</span><span class="string">""</span><span class="plain">:</span><span class="string">"s"</span><span class="plain">,</span>
|
|
<span class="identifier">rc</span><span class="plain">, (</span><span class="identifier">rc</span><span class="plain"> == 1)?</span><span class="string">""</span><span class="plain">:</span><span class="string">"s"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows</span><span class="plain"> > 0) {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" (%d blank"</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows</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">t</span><span class="plain">-</span><span class="element">>blank_rows_for_each_text</span><span class="plain">))</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">", one for each %+W"</span><span class="plain">, </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>blank_rows_for_each_text</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">")"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">HTML_CLOSE</span><span class="plain">(</span><span class="string">"span"</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"</i>"</span><span class="plain">);</span>
|
|
<span class="identifier">HTML::end_html_row</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">col</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">col</span><span class="plain"> = 0; </span><span class="identifier">col</span><span class="plain"> < </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>no_columns</span><span class="plain">; </span><span class="identifier">col</span><span class="plain">++) {</span>
|
|
<span class="identifier">HTML::first_html_column</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&nbsp;&nbsp;col %d:&nbsp;&nbsp;"</span><span class="plain">, </span><span class="identifier">col</span><span class="plain">+1);</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">CW</span><span class="plain"> = </span><span class="identifier">Nouns::nominative</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">col</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">-</span><span class="element">>name</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>first_column_by_definition</span><span class="plain">) && (</span><span class="identifier">col</span><span class="plain"> == 0)) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">PN</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>where_used_to_define</span><span class="plain">;</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">PN</span><span class="plain">));</span>
|
|
<span class="identifier">Index::link</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">PN</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">t</span><span class="plain">-</span><span class="element">>first_column_by_definition</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"<i>sets</i> "</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%+W&nbsp;"</span><span class="plain">, </span><span class="identifier">CW</span><span class="plain">);</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">, </span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">CW</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>first_column_by_definition</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">, </span><span class="string">" entry"</span><span class="plain">);</span>
|
|
<span class="identifier">HTML::Javascript::paste_stream</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">TEMP</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">TEMP</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">HTML::next_html_column</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, 0);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>first_column_by_definition</span><span class="plain">) && (</span><span class="identifier">col</span><span class="plain"> == 0)) {</span>
|
|
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">cell</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">row</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">row</span><span class="plain"> = 1, </span><span class="identifier">cell</span><span class="plain"> = </span><span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[0]</span><span class="element">.entries</span><span class="plain">-</span><span class="element">>down</span><span class="plain">; </span><span class="identifier">cell</span><span class="plain">; </span><span class="identifier">cell</span><span class="plain"> = </span><span class="identifier">cell</span><span class="plain">-</span><span class="element">>next</span><span class="plain">, </span><span class="identifier">row</span><span class="plain">++) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">row</span><span class="plain"> > 1) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">", "</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">cell</span><span class="plain">));</span>
|
|
<span class="identifier">Index::link</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">cell</span><span class="plain">)));</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">t</span><span class="plain">-</span><span class="element">>first_column_by_definition</span><span class="plain">) {</span>
|
|
<span class="identifier">Kinds::Textual::write</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">,</span>
|
|
<span class="functiontext">Tables::Columns::get_kind</span><span class="plain">(</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">col</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">));</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" property"</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"of "</span><span class="plain">);</span>
|
|
<span class="identifier">Kinds::Textual::write_plural</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">,</span>
|
|
<span class="functiontext">Tables::Columns::get_kind</span><span class="plain">(</span>
|
|
<span class="identifier">t</span><span class="plain">-</span><span class="element">>columns</span><span class="plain">[</span><span class="identifier">col</span><span class="plain">]</span><span class="element">.column_identity</span><span class="plain">));</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">HTML::end_html_row</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP30">§30</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP31"></a><b>§31. </b>The following laboriously tests whether a table is defined within a
|
|
given extension:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Tables::table_within</span><span class="plain">(</span><span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain">, </span><span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">ef</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>amendment_of</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">heading</span><span class="plain"> *</span><span class="identifier">at_heading</span><span class="plain"> = </span><span class="functiontext">Sentences::Headings::of_wording</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">-</span><span class="element">>table_created_at</span><span class="plain">-</span><span class="element">>source_table</span><span class="plain">));</span>
|
|
<span class="reserved">extension_file</span><span class="plain"> *</span><span class="identifier">at_ef</span><span class="plain"> = </span><span class="functiontext">Sentences::Headings::get_extension_containing</span><span class="plain">(</span><span class="identifier">at_heading</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ef</span><span class="plain"> == </span><span class="identifier">at_ef</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Tables::table_within is used in <a href="#SP30">§30</a>.</p>
|
|
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><a href="19-tc.html">Back to 'Table Columns'</a></li><li><a href="19-rsft.html">Continue with 'Runtime Support for Tables'</a></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</body>
|
|
</html>
|
|
|