mirror of
https://github.com/ganelson/inform.git
synced 2024-07-08 18:14:21 +03:00
1436 lines
163 KiB
HTML
1436 lines
163 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>2/kc2</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 '2/ki' generated by 7-->
|
|
<ul class="crumbs"><li><a href="../webs.html">★</a></li><li><a href="index.html">kinds</a></li><li><a href="index.html#2">Chapter 2: Kinds</a></li><li><b>Kind Interpreter</b></li></ul><p class="purpose">To read in details of the built-in kinds from template files, setting them up ready for use.</p>
|
|
|
|
<ul class="toc"><li><a href="#SP1">§1. Definitions</a></li><li><a href="#SP12">§12. Errors and limitations</a></li><li><a href="#SP13">§13. Setting up the interpreter</a></li><li><a href="#SP14">§14. The kind command despatcher</a></li><li><a href="#SP15">§15. Parsing single kind commands</a></li><li><a href="#SP16">§16. Source text templates</a></li><li><a href="#SP22">§22. Type macros</a></li><li><a href="#SP25">§25. The kind text archiver</a></li><li><a href="#SP27">§27. Error messages</a></li><li><a href="#SP28">§28. Applying kind commands</a></li><li><a href="#SP29">§29. Completing a batch</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>Everyone loves a mini-language, so here is one. At the top level:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<ul class="items"><li>(a) Lines consisting of white space or whose first non-white space character is
|
|
<code class="display"><span class="extract">!</span></code> are ignored as comments.
|
|
</li></ul>
|
|
<ul class="items"><li>(b) A line ending with a colon <code class="display"><span class="extract">:</span></code> opens a new block. The text before the colon
|
|
is the title of the block, except that the first character indicates its type:
|
|
<ul class="items"><li>(1) An asterisk means that the block is a template definition: for instance,
|
|
<code class="display"><span class="extract">*PRINTING-ROUTINE:</span></code> says the block defines a template called <code class="display"><span class="extract">PRINTING-ROUTINE</span></code>.
|
|
A template consists of Inform 7 source text which extends as far as the next
|
|
<code class="display"><span class="extract">*END</span></code> line.
|
|
</li><li>(2) A sharp sign <code class="display"><span class="extract">#</span></code> means that the block is a macro definition. For
|
|
instance, <code class="display"><span class="extract">#UNIT:</span></code> says the block defines a template called <code class="display"><span class="extract">UNIT</span></code>. A macro
|
|
is just a sequence of lines holding kind commands which continues to
|
|
the beginning of the next block, or the end of the file.
|
|
</li><li>(3) And otherwise the block is a kind definition, but the optional opening
|
|
character <code class="display"><span class="extract">+</span></code> marks the kind as one which Inform requires the existence of.
|
|
Thus <code class="display"><span class="extract">+NUMBER_TY:</span></code>, since Inform will crash if the template doesn't set this
|
|
kind up, but <code class="display"><span class="extract">BOOJUMS_TY:</span></code> would validly declare a new kind called
|
|
<code class="display"><span class="extract">BOOJUMS_TY</span></code> which isn't special to any of Inform's internals. The <code class="display"><span class="extract">+</span></code> signs
|
|
are there as a help for hackers looking at the I6 template and wondering what
|
|
they can safely monkey with.
|
|
</li></ul>
|
|
</li></ul>
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b>The body of a kind definition is a sequence of one-line commands setting
|
|
what properties the kind has. These commands take the form of a name, a colon,
|
|
and an operand; for instance,
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">i6-printing-routine-actions:DA_Number</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">The operands have different types, and the possibilities are given here:
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">NO_KCA</span><span class="plain"> -1 </span> <span class="comment">there's no operand</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">BOOLEAN_KCA</span><span class="plain"> 1 </span> <span class="comment">must be <code class="display"><span class="extract">yes</span></code> or <code class="display"><span class="extract">no</span></code></span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">CCM_KCA</span><span class="plain"> 2 </span> <span class="comment">a constant compilation method</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">TEXT_KCA</span><span class="plain"> 3 </span> <span class="comment">any text (no quotation marks or other delimiters are used)</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">VOCABULARY_KCA</span><span class="plain"> 4 </span> <span class="comment">any single word</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">NUMERIC_KCA</span><span class="plain"> 5 </span> <span class="comment">any decimal number</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">CONSTRUCTOR_KCA</span><span class="plain"> 6 </span> <span class="comment">any valid kind number, such as "number"</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">TEMPLATE_KCA</span><span class="plain"> 7 </span> <span class="comment">the name of a template whose definition is given in the file</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">MACRO_KCA</span><span class="plain"> 8 </span> <span class="comment">the name of a macro whose definition is given in the file</span>
|
|
</pre>
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. </b>When processing a command, we parse it into one of the following structures:
|
|
</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">single_kind_command</span><span class="plain"> {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind_command_definition</span><span class="plain"> *</span><span class="identifier">which_kind_command</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">boolean_argument</span><span class="plain">; </span> <span class="comment">where appropriate</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">numeric_argument</span><span class="plain">; </span> <span class="comment">where appropriate</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">textual_argument</span><span class="plain">; </span> <span class="comment">where appropriate</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">ccm_argument</span><span class="plain">; </span> <span class="comment">where appropriate</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">word_assemblage</span><span class="plain"> </span><span class="identifier">vocabulary_argument</span><span class="plain">; </span> <span class="comment">where appropriate</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">constructor_argument</span><span class="plain">; </span> <span class="comment">where appropriate</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind_template_definition</span><span class="plain"> *</span><span class="identifier">template_argument</span><span class="plain">; </span> <span class="comment">where appropriate</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind_macro_definition</span><span class="plain"> *</span><span class="identifier">macro_argument</span><span class="plain">; </span> <span class="comment">where appropriate</span>
|
|
<span class="plain">} </span><span class="reserved">single_kind_command</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure single_kind_command is private to this section.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§5. </b>A few of the commands connect pairs of kinds together: for instance,
|
|
when we write
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">cast:RULEBOOK_TY</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">in the definition block for <code class="display"><span class="extract">RULE_TY</span></code>, we're saying that every rulebook
|
|
can always be cast implicitly to a rule. There can be any number of these
|
|
in the definition block, so we need somewhere to store details, and the
|
|
following structure provides an entry in a linked list.
|
|
</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">kind_constructor_casting_rule</span><span class="plain"> {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">cast_from_kind_unparsed</span><span class="plain">; </span> <span class="comment">to the one which has the rule</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">cast_from_kind</span><span class="plain">; </span> <span class="comment">to the one which has the rule</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind_constructor_casting_rule</span><span class="plain"> *</span><span class="identifier">next_casting_rule</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">kind_constructor_casting_rule</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure kind_constructor_casting_rule is accessed in 2/kc2 and here.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§6. </b>And this is the analogous structure for giving I6 schemas to compare
|
|
data of two different kinds:
|
|
</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">kind_constructor_comparison_schema</span><span class="plain"> {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">comparator_unparsed</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">comparator</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">comparison_schema</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind_constructor_comparison_schema</span><span class="plain"> *</span><span class="identifier">next_comparison_schema</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">kind_constructor_comparison_schema</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure kind_constructor_comparison_schema is private to this section.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§7. </b>And this is the analogous structure for giving I6 schemas to compare
|
|
data of two different kinds:
|
|
</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">kind_constructor_instance</span><span class="plain"> {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">instance_of_this_unparsed</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">instance_of_this</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind_constructor_instance</span><span class="plain"> *</span><span class="identifier">next_instance_rule</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">kind_constructor_instance</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure kind_constructor_instance is accessed in 2/kc2 and here.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. </b>And, to cut to the chase, here is the complete table of commands:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind_command_definition</span><span class="plain"> </span><span class="identifier">table_of_kind_commands</span><span class="plain">[] = {</span>
|
|
<span class="plain">{ </span><span class="string">"can-coincide-with-property"</span><span class="plain">, </span><span class="constant">can_coincide_with_property_KCC</span><span class="plain">, </span><span class="constant">BOOLEAN_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"can-exchange"</span><span class="plain">, </span><span class="constant">can_exchange_KCC</span><span class="plain">, </span><span class="constant">BOOLEAN_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"defined-in-source-text"</span><span class="plain">, </span><span class="constant">defined_in_source_text_KCC</span><span class="plain">, </span><span class="constant">BOOLEAN_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"has-i6-GPR"</span><span class="plain">, </span><span class="constant">has_i6_GPR_KCC</span><span class="plain">, </span><span class="constant">BOOLEAN_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"indexed-grey-if-empty"</span><span class="plain">, </span><span class="constant">indexed_grey_if_empty_KCC</span><span class="plain">, </span><span class="constant">BOOLEAN_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"is-incompletely-defined"</span><span class="plain">, </span><span class="constant">is_incompletely_defined_KCC</span><span class="plain">, </span><span class="constant">BOOLEAN_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"is-template-variable"</span><span class="plain">, </span><span class="constant">is_template_variable_KCC</span><span class="plain">, </span><span class="constant">BOOLEAN_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"multiple-block"</span><span class="plain">, </span><span class="constant">multiple_block_KCC</span><span class="plain">, </span><span class="constant">BOOLEAN_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"named-values-created-with-assertions"</span><span class="plain">,</span>
|
|
<span class="constant">named_values_created_with_assertions_KCC</span><span class="plain">, </span><span class="constant">BOOLEAN_KCA</span><span class="plain"> },</span>
|
|
|
|
<span class="plain">{ </span><span class="string">"constant-compilation-method"</span><span class="plain">, </span><span class="constant">constant_compilation_method_KCC</span><span class="plain">, </span><span class="constant">CCM_KCA</span><span class="plain"> },</span>
|
|
|
|
<span class="plain">{ </span><span class="string">"comparison-routine"</span><span class="plain">, </span><span class="constant">comparison_routine_KCC</span><span class="plain">, </span><span class="constant">TEXT_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"default-value"</span><span class="plain">, </span><span class="constant">default_value_KCC</span><span class="plain">, </span><span class="constant">TEXT_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"description"</span><span class="plain">, </span><span class="constant">description_KCC</span><span class="plain">, </span><span class="constant">TEXT_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"distinguisher"</span><span class="plain">, </span><span class="constant">distinguisher_KCC</span><span class="plain">, </span><span class="constant">TEXT_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"documentation-reference"</span><span class="plain">, </span><span class="constant">documentation_reference_KCC</span><span class="plain">, </span><span class="constant">TEXT_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"explicit-i6-GPR"</span><span class="plain">, </span><span class="constant">explicit_i6_GPR_KCC</span><span class="plain">, </span><span class="constant">TEXT_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"i6-printing-routine"</span><span class="plain">, </span><span class="constant">i6_printing_routine_KCC</span><span class="plain">, </span><span class="constant">TEXT_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"i6-printing-routine-actions"</span><span class="plain">, </span><span class="constant">i6_printing_routine_actions_KCC</span><span class="plain">, </span><span class="constant">TEXT_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"index-default-value"</span><span class="plain">, </span><span class="constant">index_default_value_KCC</span><span class="plain">, </span><span class="constant">TEXT_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"index-maximum-value"</span><span class="plain">, </span><span class="constant">index_maximum_value_KCC</span><span class="plain">, </span><span class="constant">TEXT_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"index-minimum-value"</span><span class="plain">, </span><span class="constant">index_minimum_value_KCC</span><span class="plain">, </span><span class="constant">TEXT_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"loop-domain-schema"</span><span class="plain">, </span><span class="constant">loop_domain_schema_KCC</span><span class="plain">, </span><span class="constant">TEXT_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"recognition-only-GPR"</span><span class="plain">, </span><span class="constant">recognition_only_GPR_KCC</span><span class="plain">, </span><span class="constant">TEXT_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"specification-text"</span><span class="plain">, </span><span class="constant">specification_text_KCC</span><span class="plain">, </span><span class="constant">TEXT_KCA</span><span class="plain"> },</span>
|
|
|
|
<span class="plain">{ </span><span class="string">"cast"</span><span class="plain">, </span><span class="constant">cast_KCC</span><span class="plain">, </span><span class="constant">CONSTRUCTOR_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"comparison-schema"</span><span class="plain">, </span><span class="constant">comparison_schema_KCC</span><span class="plain">, </span><span class="constant">CONSTRUCTOR_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"instance-of"</span><span class="plain">, </span><span class="constant">instance_of_KCC</span><span class="plain">, </span><span class="constant">CONSTRUCTOR_KCA</span><span class="plain"> },</span>
|
|
|
|
<span class="plain">{ </span><span class="string">"modifying-adjective"</span><span class="plain">, </span><span class="constant">modifying_adjective_KCC</span><span class="plain">, </span><span class="constant">VOCABULARY_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"plural"</span><span class="plain">, </span><span class="constant">plural_KCC</span><span class="plain">, </span><span class="constant">VOCABULARY_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"singular"</span><span class="plain">, </span><span class="constant">singular_KCC</span><span class="plain">, </span><span class="constant">VOCABULARY_KCA</span><span class="plain"> },</span>
|
|
|
|
<span class="plain">{ </span><span class="string">"constructor-arity"</span><span class="plain">, </span><span class="constant">constructor_arity_KCC</span><span class="plain">, </span><span class="constant">TEXT_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"group"</span><span class="plain">, </span><span class="constant">group_KCC</span><span class="plain">, </span><span class="constant">NUMERIC_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"heap-size-estimate"</span><span class="plain">, </span><span class="constant">heap_size_estimate_KCC</span><span class="plain">, </span><span class="constant">NUMERIC_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"index-priority"</span><span class="plain">, </span><span class="constant">index_priority_KCC</span><span class="plain">, </span><span class="constant">NUMERIC_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"small-block-size"</span><span class="plain">, </span><span class="constant">small_block_size_KCC</span><span class="plain">, </span><span class="constant">NUMERIC_KCA</span><span class="plain"> },</span>
|
|
<span class="plain">{ </span><span class="string">"template-variable-number"</span><span class="plain">, </span><span class="constant">template_variable_number_KCC</span><span class="plain">, </span><span class="constant">NUMERIC_KCA</span><span class="plain"> },</span>
|
|
|
|
<span class="plain">{ </span><span class="string">"apply-template"</span><span class="plain">, </span><span class="constant">apply_template_KCC</span><span class="plain">, </span><span class="constant">TEMPLATE_KCA</span><span class="plain"> },</span>
|
|
|
|
<span class="plain">{ </span><span class="string">"apply-macro"</span><span class="plain">, </span><span class="constant">apply_macro_KCC</span><span class="plain">, </span><span class="constant">MACRO_KCA</span><span class="plain"> },</span>
|
|
|
|
<span class="plain">{ </span><span class="identifier">NULL</span><span class="plain">, -1, </span><span class="constant">NO_KCA</span><span class="plain"> }</span>
|
|
<span class="plain">};</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9"></a><b>§9. </b>Where each legal command is defined with a block like so:
|
|
</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">kind_command_definition</span><span class="plain"> {</span>
|
|
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">text_of_command</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">opcode_number</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">operand_type</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">kind_command_definition</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure kind_command_definition is private to this section.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10"></a><b>§10. </b>Macros and templates have their definitions stored in structures thus:
|
|
</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">kind_template_definition</span><span class="plain"> {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">template_name</span><span class="plain">; </span> <span class="comment">including the asterisk, e.g., <code class="display"><span class="extract">"*PRINTING-ROUTINE"</span></code></span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">template_text</span><span class="plain">;</span>
|
|
<span class="identifier">MEMORY_MANAGEMENT</span>
|
|
<span class="plain">} </span><span class="reserved">kind_template_definition</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind_macro_definition</span><span class="plain"> {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">kind_macro_name</span><span class="plain">; </span> <span class="comment">including the sharp, e.g., <code class="display"><span class="extract">"#UNIT"</span></code></span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">kind_macro_line_count</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">single_kind_command</span><span class="plain"> </span><span class="identifier">kind_macro_line</span><span class="plain">[</span><span class="constant">MAX_KIND_MACRO_LENGTH</span><span class="plain">];</span>
|
|
<span class="identifier">MEMORY_MANAGEMENT</span>
|
|
<span class="plain">} </span><span class="reserved">kind_macro_definition</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure kind_template_definition is private to this section.</p>
|
|
|
|
<p class="endnote">The structure kind_macro_definition is private to this section.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11"></a><b>§11. </b>And this makes a note to insert the relevant chunk of I7 source text
|
|
later on. (We do this because kind definitions are read very early on
|
|
in Inform's run, whereas I7 source text can only be lexed later.)
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind_template_obligation</span><span class="plain"> {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind_template_definition</span><span class="plain"> *</span><span class="identifier">remembered_template</span><span class="plain">; </span> <span class="comment">I7 source to insert...</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">remembered_constructor</span><span class="plain">; </span> <span class="comment">...concerning this kind</span>
|
|
<span class="identifier">MEMORY_MANAGEMENT</span>
|
|
<span class="plain">} </span><span class="reserved">kind_template_obligation</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure kind_template_obligation is private to this section.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12"></a><b>§12. Errors and limitations. </b>In implementing the interpreter, we have to ask: who is it for? It occupies
|
|
a strange position in being not quite for end users — the average Inform
|
|
user will never know what the template is — and yet not quite for internal
|
|
use only, either. The main motivation for moving properties of kinds out of
|
|
Inform's program logic and into an external text file was to make it easier
|
|
to verify that they were correctly described; but it was certainly also
|
|
meant to give future Inform hackers — users who like to burrow into
|
|
internals — scope for play.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The I6 template files supplied with Inform's standard distribution are,
|
|
of course, correct. So how forgiving should we be, if errors are found in it?
|
|
(These must result from mistakes by hackers.) To what extent should we allow
|
|
arbitrarily complex constructions, as we would if it were a feature intended
|
|
for end users?
|
|
</p>
|
|
|
|
<p class="inwebparagraph">We strike a sort of middle position. Inform will probably not crash if an
|
|
incorrect kind command is supplied, but it is free to throw internal
|
|
errors or generate I6 code which fails to compile through I6.
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">MAX_KIND_MACRO_LENGTH</span><span class="plain"> 20 </span> <span class="comment">maximum number of commands in any one macro</span>
|
|
</pre>
|
|
<p class="inwebparagraph"><a id="SP13"></a><b>§13. Setting up the interpreter. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::start</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::start appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14"></a><b>§14. The kind command despatcher. </b>And this is where textual commands are received. (They come in from the
|
|
template interpreter.) Comments and blank lines have already been stripped out.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">A template absorbs the raw text of its definition, and ends with <code class="display"><span class="extract">*END</span></code>;
|
|
whereas a macro absorbs the parsed form of its commands, and continues to
|
|
the next new heading. (Templates can't use the same end syntax because
|
|
they often need to contain I7 phrase definitions, where lines end with
|
|
colons.)
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">constructor_described</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::despatch_kind_command</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">command</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Interpreter::recording_a_kind_template</span><span class="plain">()) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"*END"</span><span class="plain">)) </span><span class="functiontext">Kinds::Interpreter::end_kind_template</span><span class="plain">();</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::record_into_kind_template</span><span class="plain">(</span><span class="identifier">command</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">Str::get_last_char</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">) == </span><span class="character">':'</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Interpreter::recording_a_kind_macro</span><span class="plain">()) </span><span class="functiontext">Kinds::Interpreter::end_kind_macro</span><span class="plain">();</span>
|
|
<span class="identifier">Str::delete_last_character</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">); </span> <span class="comment">remove the terminal colon</span>
|
|
<<span class="cwebmacro">Deal with the heading at the top of a kind command block</span> <span class="cwebmacronumber">14.1</span>><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">single_kind_command</span><span class="plain"> </span><span class="identifier">stc</span><span class="plain"> = </span><span class="functiontext">Kinds::Interpreter::parse_kind_command</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Interpreter::recording_a_kind_macro</span><span class="plain">()) </span><span class="functiontext">Kinds::Interpreter::record_into_kind_macro</span><span class="plain">(</span><span class="identifier">stc</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">constructor_described</span><span class="plain">) </span><span class="functiontext">Kinds::Interpreter::apply_kind_command</span><span class="plain">(</span><span class="identifier">stc</span><span class="plain">, </span><span class="identifier">constructor_described</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">"kind command describes unspecified kind"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::despatch_kind_command appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14_1"></a><b>§14.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Deal with the heading at the top of a kind command block</span> <span class="cwebmacronumber">14.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::get_first_char</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">) == </span><span class="character">'#'</span><span class="plain">) </span><span class="functiontext">Kinds::Interpreter::begin_kind_macro</span><span class="plain">(</span><span class="identifier">command</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">Str::get_first_char</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">) == </span><span class="character">'*'</span><span class="plain">) </span><span class="functiontext">Kinds::Interpreter::begin_kind_template</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">);</span>
|
|
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">command</span><span class="plain">);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">should_know</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">Str::get_first_char</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">) == </span><span class="character">'+'</span><span class="plain">) { </span><span class="identifier">Str::delete_first_character</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">); </span><span class="identifier">should_know</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">do_know</span><span class="plain"> = </span><span class="functiontext">Kinds::known_name</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">do_know</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) && (</span><span class="identifier">should_know</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">))</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"kind command describes kind with no known name"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">do_know</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">) && (</span><span class="identifier">should_know</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">"kind command describes already-known kind"</span><span class="plain">);</span>
|
|
<span class="identifier">constructor_described</span><span class="plain"> =</span>
|
|
<span class="functiontext">Kinds::Constructors::new</span><span class="plain">(</span><span class="functiontext">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">), </span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">NEW_BASE_KIND_NOTIFY</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">constructor_described</span><span class="plain"> != </span><span class="identifier">CON_KIND_VARIABLE</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="identifier">constructor_described</span><span class="plain"> != </span><span class="identifier">CON_INTERMEDIATE</span><span class="plain">)) {</span>
|
|
<span class="identifier">NEW_BASE_KIND_NOTIFY</span><span class="plain">(</span>
|
|
<span class="functiontext">Kinds::base_construction</span><span class="plain">(</span><span class="identifier">constructor_described</span><span class="plain">), </span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">EMPTY_WORDING</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP14">§14</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15"></a><b>§15. Parsing single kind commands. </b>Each command is read in as text, parsed and stored into a modest structure.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">single_kind_command</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::parse_kind_command</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">whole_command</span><span class="plain">) {</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">argument</span><span class="plain">);</span>
|
|
<span class="reserved">single_kind_command</span><span class="plain"> </span><span class="identifier">stc</span><span class="plain">;</span>
|
|
|
|
<<span class="cwebmacro">Parse line into command and argument, divided by a colon</span> <span class="cwebmacronumber">15.2</span>><span class="plain">;</span>
|
|
|
|
<<span class="cwebmacro">Initialise the STC to a blank command</span> <span class="cwebmacronumber">15.1</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Identify the command being used</span> <span class="cwebmacronumber">15.3</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">stc</span><span class="element">.which_kind_command</span><span class="plain">-</span><span class="element">>operand_type</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">BOOLEAN_KCA</span><span class="plain">: </span><<span class="cwebmacro">Parse a boolean argument for a kind command</span> <span class="cwebmacronumber">15.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">CCM_KCA</span><span class="plain">: </span><<span class="cwebmacro">Parse a CCM argument for a kind command</span> <span class="cwebmacronumber">15.5</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">CONSTRUCTOR_KCA</span><span class="plain">: </span><<span class="cwebmacro">Parse a constructor-name argument for a kind command</span> <span class="cwebmacronumber">15.9</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">MACRO_KCA</span><span class="plain">: </span><<span class="cwebmacro">Parse a macro name argument for a kind command</span> <span class="cwebmacronumber">15.11</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">NUMERIC_KCA</span><span class="plain">: </span><<span class="cwebmacro">Parse a numeric argument for a kind command</span> <span class="cwebmacronumber">15.8</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">TEMPLATE_KCA</span><span class="plain">: </span><<span class="cwebmacro">Parse a template name argument for a kind command</span> <span class="cwebmacronumber">15.10</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">TEXT_KCA</span><span class="plain">: </span><<span class="cwebmacro">Parse a textual argument for a kind command</span> <span class="cwebmacronumber">15.6</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">VOCABULARY_KCA</span><span class="plain">: </span><<span class="cwebmacro">Parse a vocabulary argument for a kind command</span> <span class="cwebmacronumber">15.7</span>><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">argument</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">stc</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::parse_kind_command is used in <a href="#SP14">§14</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15_1"></a><b>§15.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Initialise the STC to a blank command</span> <span class="cwebmacronumber">15.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">stc</span><span class="element">.which_kind_command</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">stc</span><span class="element">.boolean_argument</span><span class="plain"> = </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">;</span>
|
|
<span class="identifier">stc</span><span class="element">.numeric_argument</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">stc</span><span class="element">.textual_argument</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
|
|
<span class="identifier">stc</span><span class="element">.ccm_argument</span><span class="plain"> = -1;</span>
|
|
<span class="identifier">stc</span><span class="element">.vocabulary_argument</span><span class="plain"> = </span><span class="identifier">WordAssemblages::lit_0</span><span class="plain">();</span>
|
|
<span class="identifier">stc</span><span class="element">.constructor_argument</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
|
|
<span class="identifier">stc</span><span class="element">.macro_argument</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">stc</span><span class="element">.template_argument</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP15">§15</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15_2"></a><b>§15.2. </b>Spaces and tabs after the colon are skipped; so a textual argument cannot
|
|
begin with those characters, but that doesn't matter for the things we need.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Parse line into command and argument, divided by a colon</span> <span class="cwebmacronumber">15.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="identifier">Regexp::create_mr</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Regexp::match</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">whole_command</span><span class="plain">, </span><span class="identifier">L</span><span class="string">" *(%c+?) *: *(%c+?) *"</span><span class="plain">)) {</span>
|
|
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">mr</span><span class="plain">.</span><span class="identifier">exp</span><span class="plain">[0]);</span>
|
|
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">argument</span><span class="plain">, </span><span class="identifier">mr</span><span class="plain">.</span><span class="identifier">exp</span><span class="plain">[1]);</span>
|
|
<span class="identifier">Regexp::dispose_of</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="functiontext">Kinds::Interpreter::kind_command_error</span><span class="plain">(</span><span class="identifier">whole_command</span><span class="plain">, </span><span class="string">"kind command without argument"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP15">§15</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15_3"></a><b>§15.3. </b>The following is clearly inefficient, but is not worth optimising. It makes
|
|
about 20 string comparisons per command, and there are about 600 commands in a
|
|
typical run of Inform, so the total cost is about 12,000 comparisons with
|
|
quite small strings as arguments — which is negligible for our purposes,
|
|
so we neglect it.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Identify the command being used</span> <span class="cwebmacronumber">15.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">table_of_kind_commands</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.text_of_command</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">Str::eq_narrow_string</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="identifier">table_of_kind_commands</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]</span><span class="element">.text_of_command</span><span class="plain">))</span>
|
|
<span class="identifier">stc</span><span class="element">.which_kind_command</span><span class="plain"> = &(</span><span class="identifier">table_of_kind_commands</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">stc</span><span class="element">.which_kind_command</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
|
|
<span class="functiontext">Kinds::Interpreter::kind_command_error</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"no such kind command"</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP15">§15</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15_4"></a><b>§15.4. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Parse a boolean argument for a kind command</span> <span class="cwebmacronumber">15.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">argument</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"yes"</span><span class="plain">)) </span><span class="identifier">stc</span><span class="element">.boolean_argument</span><span class="plain"> = </span><span class="identifier">TRUE</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">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">argument</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"no"</span><span class="plain">)) </span><span class="identifier">stc</span><span class="element">.boolean_argument</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::kind_command_error</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"boolean kind command takes yes/no argument"</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP15">§15</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15_5"></a><b>§15.5. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Parse a CCM argument for a kind command</span> <span class="cwebmacronumber">15.5</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">argument</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"none"</span><span class="plain">)) </span><span class="identifier">stc</span><span class="element">.ccm_argument</span><span class="plain"> = </span><span class="constant">NONE_CCM</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">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">argument</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"literal"</span><span class="plain">)) </span><span class="identifier">stc</span><span class="element">.ccm_argument</span><span class="plain"> = </span><span class="constant">LITERAL_CCM</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">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">argument</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"quantitative"</span><span class="plain">)) </span><span class="identifier">stc</span><span class="element">.ccm_argument</span><span class="plain"> = </span><span class="constant">NAMED_CONSTANT_CCM</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">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">argument</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"special"</span><span class="plain">)) </span><span class="identifier">stc</span><span class="element">.ccm_argument</span><span class="plain"> = </span><span class="constant">SPECIAL_CCM</span><span class="plain">;</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::kind_command_error</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"kind command with unknown constant-compilation-method"</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP15">§15</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15_6"></a><b>§15.6. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Parse a textual argument for a kind command</span> <span class="cwebmacronumber">15.6</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">stc</span><span class="element">.textual_argument</span><span class="plain">, </span><span class="identifier">argument</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP15">§15</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15_7"></a><b>§15.7. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Parse a vocabulary argument for a kind command</span> <span class="cwebmacronumber">15.7</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">stc</span><span class="element">.vocabulary_argument</span><span class="plain"> = </span><span class="identifier">WordAssemblages::lit_0</span><span class="plain">();</span>
|
|
<span class="identifier">feed_t</span><span class="plain"> </span><span class="identifier">id</span><span class="plain"> = </span><span class="identifier">Feeds::begin</span><span class="plain">();</span>
|
|
<span class="identifier">Feeds::feed_stream</span><span class="plain">(</span><span class="identifier">argument</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">Feeds::end</span><span class="plain">(</span><span class="identifier">id</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">W</span><span class="plain">) >= 30)</span>
|
|
<span class="functiontext">Kinds::Interpreter::kind_command_error</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"too many words in kind command"</span><span class="plain">);</span>
|
|
<span class="reserved">else</span>
|
|
<span class="identifier">stc</span><span class="element">.vocabulary_argument</span><span class="plain"> = </span><span class="identifier">WordAssemblages::from_wording</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="#SP15">§15</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15_8"></a><b>§15.8. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Parse a numeric argument for a kind command</span> <span class="cwebmacronumber">15.8</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">stc</span><span class="element">.numeric_argument</span><span class="plain"> = </span><span class="identifier">Str::atoi</span><span class="plain">(</span><span class="identifier">argument</span><span class="plain">, 0);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP15">§15</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15_9"></a><b>§15.9. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Parse a constructor-name argument for a kind command</span> <span class="cwebmacronumber">15.9</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="identifier">Regexp::create_mr</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Regexp::match</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">argument</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%c*?)>>>(%c+)"</span><span class="plain">)) {</span>
|
|
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">argument</span><span class="plain">, </span><span class="identifier">mr</span><span class="plain">.</span><span class="identifier">exp</span><span class="plain">[0]);</span>
|
|
<span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">stc</span><span class="element">.textual_argument</span><span class="plain">, </span><span class="identifier">mr</span><span class="plain">.</span><span class="identifier">exp</span><span class="plain">[1]);</span>
|
|
<span class="identifier">Regexp::dispose_of</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">stc</span><span class="element">.constructor_argument</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">argument</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP15">§15</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15_10"></a><b>§15.10. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Parse a template name argument for a kind command</span> <span class="cwebmacronumber">15.10</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">stc</span><span class="element">.template_argument</span><span class="plain"> = </span><span class="functiontext">Kinds::Interpreter::parse_kind_template_name</span><span class="plain">(</span><span class="identifier">argument</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">stc</span><span class="element">.template_argument</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
|
|
<span class="functiontext">Kinds::Interpreter::kind_command_error</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"unknown template name in kind command"</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP15">§15</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15_11"></a><b>§15.11. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Parse a macro name argument for a kind command</span> <span class="cwebmacronumber">15.11</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">stc</span><span class="element">.macro_argument</span><span class="plain"> = </span><span class="functiontext">Kinds::Interpreter::parse_kind_macro_name</span><span class="plain">(</span><span class="identifier">argument</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">stc</span><span class="element">.macro_argument</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)</span>
|
|
<span class="functiontext">Kinds::Interpreter::kind_command_error</span><span class="plain">(</span><span class="identifier">command</span><span class="plain">, </span><span class="string">"unknown template name in kind command"</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP15">§15</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP16"></a><b>§16. Source text templates. </b>These are passages of I7 source text which can be inserted into the main
|
|
source text at the request of any kind. An example would be:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">*UNDERSTOOD-VARIABLE:</span>
|
|
<span class="plain"><kind> understood is a <kind> which varies.</span>
|
|
<span class="plain">*END</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">The template <code class="display"><span class="extract">*UNDERSTOOD-VARIABLE</span></code> contains only a single sentence of source
|
|
text, and the idea is to make a new global variable associated with a given
|
|
kind. Note that the text is not quite literal, because it can contain
|
|
wildcards like <code class="display"><span class="extract"><kind></span></code>, which expands to the name of the kind of value in
|
|
question: for instance, we might get
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>number understood is a number which varies.</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">There are a few limitations on what template text can include. Firstly,
|
|
nothing with angle brackets in, except where a wildcard appears. Secondly,
|
|
each sentence must end at the end of a line, and similarly the colon for
|
|
any rule or other definition. Thus this template would fail:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">*UNDERSTOOD-VARIABLE:</span>
|
|
<span class="plain"><kind> understood is a <kind> which</span>
|
|
<span class="plain">varies. To judge <kind>: say "I judge [<kind> understood]."</span>
|
|
<span class="plain">*END</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">because the first sentence ends in the middle of the second line, and the
|
|
colon dividing the phrase header from its definition is also mid-line. The
|
|
template must be reformatted thus to work:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">*UNDERSTOOD-VARIABLE:</span>
|
|
<span class="plain"><kind> understood is a <kind> which varies.</span>
|
|
<span class="plain">To judge <kind>:</span>
|
|
<span class="plain"> say "I judge [<kind> understood]."</span>
|
|
<span class="plain">*END</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP17"></a><b>§17. </b>So, to begin:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind_template_definition</span><span class="plain"> *</span><span class="functiontext">Kinds::Interpreter::new_kind_template</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">) {</span>
|
|
<span class="reserved">kind_template_definition</span><span class="plain"> *</span><span class="identifier">ttd</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">kind_template_definition</span><span class="plain">);</span>
|
|
<span class="identifier">ttd</span><span class="plain">-</span><span class="element">>template_name</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ttd</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">kind_template_definition</span><span class="plain"> *</span><span class="functiontext">Kinds::Interpreter::parse_kind_template_name</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">) {</span>
|
|
<span class="reserved">kind_template_definition</span><span class="plain"> *</span><span class="identifier">ttd</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">ttd</span><span class="plain">, </span><span class="reserved">kind_template_definition</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">ttd</span><span class="plain">-</span><span class="element">>template_name</span><span class="plain">))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ttd</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::new_kind_template is used in <a href="#SP18">§18</a>.</p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::parse_kind_template_name is used in <a href="#SP15_10">§15.10</a>, <a href="#SP18">§18</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP18"></a><b>§18. </b>Here is the code which records templates, reading them as one line of plain
|
|
text at a time. (In the above example, <code class="display"><span class="extract">Kinds::Interpreter::record_into_kind_template</span></code> would be
|
|
called just once, with the single source text line.)
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind_template_definition</span><span class="plain"> *</span><span class="identifier">current_kind_template</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">the one now being recorded</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::recording_a_kind_template</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_kind_template</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>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::begin_kind_template</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_kind_template</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"first stt still recording"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Interpreter::parse_kind_template_name</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">))</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"duplicate definition of source text template"</span><span class="plain">);</span>
|
|
<span class="identifier">current_kind_template</span><span class="plain"> = </span><span class="functiontext">Kinds::Interpreter::new_kind_template</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">);</span>
|
|
<span class="identifier">current_kind_template</span><span class="plain">-</span><span class="element">>template_text</span><span class="plain"> = </span><span class="functiontext">Kinds::Interpreter::begin_recording_kind_text</span><span class="plain">();</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::record_into_kind_template</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">line</span><span class="plain">) {</span>
|
|
<span class="functiontext">Kinds::Interpreter::record_kind_text</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::end_kind_template</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_kind_template</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 stt currently recording"</span><span class="plain">);</span>
|
|
<span class="functiontext">Kinds::Interpreter::end_recording_kind_text</span><span class="plain">();</span>
|
|
<span class="identifier">current_kind_template</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::recording_a_kind_template is used in <a href="#SP14">§14</a>.</p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::begin_kind_template is used in <a href="#SP14_1">§14.1</a>.</p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::record_into_kind_template is used in <a href="#SP14">§14</a>.</p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::end_kind_template is used in <a href="#SP14">§14</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP19"></a><b>§19. </b>So much for recording a template. To "play back", we need to take its text
|
|
and squeeze it into the main source text, but there's a timing issue: when
|
|
we read kind commands it is very early in Inform's run, and the lexer may not
|
|
even have started yet. So we simply remember our intention to insert the text:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">era_of_kind_template_transcription</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::remember_to_transcribe_spec_template</span><span class="plain">(</span><span class="reserved">kind_template_definition</span><span class="plain"> *</span><span class="identifier">ttd</span><span class="plain">, </span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">era_of_kind_template_transcription</span><span class="plain">) {</span>
|
|
<span class="functiontext">Kinds::Interpreter::transcribe_kind_template</span><span class="plain">(</span><span class="identifier">ttd</span><span class="plain">, </span><span class="identifier">C</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="reserved">kind_template_obligation</span><span class="plain"> *</span><span class="identifier">tto</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">kind_template_obligation</span><span class="plain">);</span>
|
|
<span class="identifier">tto</span><span class="plain">-</span><span class="element">>remembered_template</span><span class="plain"> = </span><span class="identifier">ttd</span><span class="plain">;</span>
|
|
<span class="identifier">tto</span><span class="plain">-</span><span class="element">>remembered_constructor</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::remember_to_transcribe_spec_template is used in <a href="#SP28_1">§28.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20"></a><b>§20. </b>...until now, when it's later on and the source text does indeed exist.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::include_templates_for_kinds</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="identifier">era_of_kind_template_transcription</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">kind_template_obligation</span><span class="plain"> *</span><span class="identifier">tto</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">tto</span><span class="plain">, </span><span class="reserved">kind_template_obligation</span><span class="plain">)</span>
|
|
<span class="functiontext">Kinds::Interpreter::transcribe_kind_template</span><span class="plain">(</span>
|
|
<span class="identifier">tto</span><span class="plain">-</span><span class="element">>remembered_template</span><span class="plain">, </span><span class="identifier">tto</span><span class="plain">-</span><span class="element">>remembered_constructor</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::transcribe_kind_template</span><span class="plain">(</span><span class="reserved">kind_template_definition</span><span class="plain"> *</span><span class="identifier">ttd</span><span class="plain">, </span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">con</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ttd</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"tried to transcribe missing source text template"</span><span class="plain">);</span>
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Plugins::Manage::plugged_in</span><span class="plain">(</span><span class="identifier">parsing_plugin</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) && (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">ttd</span><span class="plain">-</span><span class="element">>template_name</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"*UNDERSTOOD-VARIABLE"</span><span class="plain">)))</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span>
|
|
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain"> = </span><span class="identifier">ttd</span><span class="plain">-</span><span class="element">>template_text</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">while</span><span class="plain"> (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">p</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">Str::get_at</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">) == </span><span class="character">'\</span><span class="plain">n</span><span class="character">'</span><span class="plain">) || (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">) == </span><span class="character">' '</span><span class="plain">)) { </span><span class="identifier">i</span><span class="plain">++; </span><span class="reserved">continue</span><span class="plain">; }</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">template_line_buffer</span><span class="plain">);</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">terminator</span><span class="plain"> = 0;</span>
|
|
<<span class="cwebmacro">Transcribe one line of the template into the line buffer</span> <span class="cwebmacronumber">20.1</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">template_line_buffer</span><span class="plain">) > 0) {</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">XW</span><span class="plain"> = </span><span class="identifier">Feeds::feed_stream</span><span class="plain">(</span><span class="identifier">template_line_buffer</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">terminator</span><span class="plain"> != 0) </span><span class="identifier">Sentences::make_node</span><span class="plain">(</span><span class="identifier">XW</span><span class="plain">, </span><span class="identifier">terminator</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">template_line_buffer</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
|
|
<span class="identifier">Sentences::Rearrangement::further_material</span><span class="plain">();</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::include_templates_for_kinds appears nowhere else.</p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::transcribe_kind_template is used in <a href="#SP19">§19</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_1"></a><b>§20.1. </b>Inside template text, anything in angle brackets <...> is a wildcard.
|
|
These cannot be nested and cannot include newlines. All other material is
|
|
copied verbatim into the line buffer.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The only sentence terminators we recognise are full stop and colon; in
|
|
particular we wouldn't recognise a stop inside quoted matter. This does
|
|
not matter, since such things never come into kind definitions.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Transcribe one line of the template into the line buffer</span> <span class="cwebmacronumber">20.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">) != 0) && (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">) != </span><span class="character">'\</span><span class="plain">n</span><span class="character">'</span><span class="plain">)) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">) == </span><span class="character">'<'</span><span class="plain">) {</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">template_wildcard_buffer</span><span class="plain">);</span>
|
|
<span class="identifier">i</span><span class="plain">++;</span>
|
|
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">) != 0) && (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">) != </span><span class="character">'\</span><span class="plain">n</span><span class="character">'</span><span class="plain">) && (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">) != </span><span class="character">'>'</span><span class="plain">))</span>
|
|
<span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">template_wildcard_buffer</span><span class="plain">, </span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">p</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="cwebmacro">Transcribe the template wildcard</span> <span class="cwebmacronumber">20.1.1</span>><span class="plain">;</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">template_wildcard_buffer</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">template_line_buffer</span><span class="plain">, </span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">++));</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::get_last_char</span><span class="plain">(</span><span class="identifier">template_line_buffer</span><span class="plain">) == </span><span class="character">'.'</span><span class="plain">) {</span>
|
|
<span class="identifier">Str::delete_last_character</span><span class="plain">(</span><span class="identifier">template_line_buffer</span><span class="plain">); </span><span class="identifier">terminator</span><span class="plain"> = </span><span class="character">'.'</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::get_last_char</span><span class="plain">(</span><span class="identifier">template_line_buffer</span><span class="plain">) == </span><span class="character">':'</span><span class="plain">) {</span>
|
|
<span class="identifier">Str::delete_last_character</span><span class="plain">(</span><span class="identifier">template_line_buffer</span><span class="plain">); </span><span class="identifier">terminator</span><span class="plain"> = </span><span class="character">':'</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_1_1"></a><b>§20.1.1. </b>Only five wildcards are recognised:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Transcribe the template wildcard</span> <span class="cwebmacronumber">20.1.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">template_wildcard_buffer</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"kind"</span><span class="plain">))</span>
|
|
<<span class="cwebmacro">Transcribe the kind's name</span> <span class="cwebmacronumber">20.1.1.1</span>>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">template_wildcard_buffer</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"lower-case-kind"</span><span class="plain">))</span>
|
|
<<span class="cwebmacro">Transcribe the kind's name in lower case</span> <span class="cwebmacronumber">20.1.1.2</span>>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">template_wildcard_buffer</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"kind-weak-ID"</span><span class="plain">))</span>
|
|
<<span class="cwebmacro">Transcribe the kind's weak ID</span> <span class="cwebmacronumber">20.1.1.3</span>>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">template_wildcard_buffer</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"printing-routine"</span><span class="plain">))</span>
|
|
<<span class="cwebmacro">Transcribe the kind's I6 printing routine</span> <span class="cwebmacronumber">20.1.1.4</span>>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">template_wildcard_buffer</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"comparison-routine"</span><span class="plain">))</span>
|
|
<<span class="cwebmacro">Transcribe the kind's I6 comparison routine</span> <span class="cwebmacronumber">20.1.1.5</span>>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no such source text template wildcard"</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20_1">§20.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_1_1_1"></a><b>§20.1.1.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Transcribe the kind's name</span> <span class="cwebmacronumber">20.1.1.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="functiontext">Kinds::Interpreter::transcribe_constructor_name</span><span class="plain">(</span><span class="identifier">template_line_buffer</span><span class="plain">, </span><span class="identifier">con</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20_1_1">§20.1.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_1_1_2"></a><b>§20.1.1.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Transcribe the kind's name in lower case</span> <span class="cwebmacronumber">20.1.1.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="functiontext">Kinds::Interpreter::transcribe_constructor_name</span><span class="plain">(</span><span class="identifier">template_line_buffer</span><span class="plain">, </span><span class="identifier">con</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20_1_1">§20.1.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_1_1_3"></a><b>§20.1.1.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Transcribe the kind's weak ID</span> <span class="cwebmacronumber">20.1.1.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">template_line_buffer</span><span class="plain">, </span><span class="string">"%d"</span><span class="plain">, </span><span class="identifier">con</span><span class="plain">-</span><span class="element">>weak_kind_ID</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20_1_1">§20.1.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_1_1_4"></a><b>§20.1.1.4. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Transcribe the kind's I6 printing routine</span> <span class="cwebmacronumber">20.1.1.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">template_line_buffer</span><span class="plain">, </span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">con</span><span class="plain">-</span><span class="element">>dt_I6_identifier</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20_1_1">§20.1.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20_1_1_5"></a><b>§20.1.1.5. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Transcribe the kind's I6 comparison routine</span> <span class="cwebmacronumber">20.1.1.5</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">template_line_buffer</span><span class="plain">, </span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">con</span><span class="plain">-</span><span class="element">>comparison_routine</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP20_1_1">§20.1.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP21"></a><b>§21. </b>Where:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::transcribe_constructor_name</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">con</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">lower_case</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">EMPTY_WORDING</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">con</span><span class="plain">-</span><span class="element">>dt_tag</span><span class="plain">) </span><span class="identifier">W</span><span class="plain"> = </span><span class="functiontext">Kinds::Constructors::get_name</span><span class="plain">(</span><span class="identifier">con</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::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="functiontext">Kinds::Constructors::arity</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">) > 0) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">full_length</span><span class="plain"> = </span><span class="identifier">Wordings::length</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">i</span><span class="plain">, </span><span class="identifier">w1</span><span class="plain"> = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
|
|
<span class="reserved">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">full_length</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">PUT</span><span class="plain">(</span><span class="character">' '</span><span class="plain">);</span>
|
|
<span class="identifier">vocabulary_entry</span><span class="plain"> *</span><span class="identifier">ve</span><span class="plain"> = </span><span class="identifier">Lexer::word</span><span class="plain">(</span><span class="identifier">w1</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">ve</span><span class="plain"> == </span><span class="identifier">STROKE_V</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ve</span><span class="plain"> == </span><span class="identifier">CAPITAL_K_V</span><span class="plain">) || (</span><span class="identifier">ve</span><span class="plain"> == </span><span class="identifier">CAPITAL_L_V</span><span class="plain">)) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"value"</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">"%V"</span><span class="plain">, </span><span class="identifier">ve</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">lower_case</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">W</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">"%W"</span><span class="plain">, </span><span class="identifier">W</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 Kinds::Interpreter::transcribe_constructor_name is used in <a href="#SP20_1_1_1">§20.1.1.1</a>, <a href="#SP20_1_1_2">§20.1.1.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP22"></a><b>§22. Type macros. </b>These are much simpler, and are just lists of kind commands grouped together
|
|
under names.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind_macro_definition</span><span class="plain"> *</span><span class="identifier">current_kind_macro</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">the one now being recorded</span>
|
|
|
|
<span class="reserved">kind_macro_definition</span><span class="plain"> *</span><span class="functiontext">Kinds::Interpreter::new_kind_macro</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">) {</span>
|
|
<span class="reserved">kind_macro_definition</span><span class="plain"> *</span><span class="identifier">tmd</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">kind_macro_definition</span><span class="plain">);</span>
|
|
<span class="identifier">tmd</span><span class="plain">-</span><span class="element">>kind_macro_line_count</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">tmd</span><span class="plain">-</span><span class="element">>kind_macro_name</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">tmd</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">kind_macro_definition</span><span class="plain"> *</span><span class="functiontext">Kinds::Interpreter::parse_kind_macro_name</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">) {</span>
|
|
<span class="reserved">kind_macro_definition</span><span class="plain"> *</span><span class="identifier">tmd</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">tmd</span><span class="plain">, </span><span class="reserved">kind_macro_definition</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">tmd</span><span class="plain">-</span><span class="element">>kind_macro_name</span><span class="plain">))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">tmd</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::new_kind_macro is used in <a href="#SP23">§23</a>.</p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::parse_kind_macro_name is used in <a href="#SP15_11">§15.11</a>, <a href="#SP23">§23</a>, 2/kc2 (<a href="2-kc2.html#SP7_1">§7.1</a>, <a href="2-kc2.html#SP11">§11</a>, <a href="2-kc2.html#SP12">§12</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP23"></a><b>§23. </b>And here once again is the code to record macros:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::recording_a_kind_macro</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_kind_macro</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>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::begin_kind_macro</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Interpreter::parse_kind_macro_name</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">))</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"duplicate definition of kind command macro"</span><span class="plain">);</span>
|
|
<span class="identifier">current_kind_macro</span><span class="plain"> = </span><span class="functiontext">Kinds::Interpreter::new_kind_macro</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::record_into_kind_macro</span><span class="plain">(</span><span class="reserved">single_kind_command</span><span class="plain"> </span><span class="identifier">stc</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_kind_macro</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">"kind macro not being recorded"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_kind_macro</span><span class="plain">-</span><span class="element">>kind_macro_line_count</span><span class="plain"> >= </span><span class="constant">MAX_KIND_MACRO_LENGTH</span><span class="plain">)</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"kind macro contains too many lines"</span><span class="plain">);</span>
|
|
<span class="identifier">current_kind_macro</span><span class="plain">-</span><span class="element">>kind_macro_line</span><span class="plain">[</span><span class="identifier">current_kind_macro</span><span class="plain">-</span><span class="element">>kind_macro_line_count</span><span class="plain">++] = </span><span class="identifier">stc</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::end_kind_macro</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_kind_macro</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">"ended kind macro outside one"</span><span class="plain">);</span>
|
|
<span class="identifier">current_kind_macro</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::recording_a_kind_macro is used in <a href="#SP14">§14</a>.</p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::begin_kind_macro is used in <a href="#SP14_1">§14.1</a>.</p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::record_into_kind_macro is used in <a href="#SP14">§14</a>.</p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::end_kind_macro is used in <a href="#SP14">§14</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24"></a><b>§24. </b>Playing back is easier, since it's just a matter of despatching the stored
|
|
commands in sequence to the relevant kind.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::play_back_kind_macro</span><span class="plain">(</span><span class="reserved">kind_macro_definition</span><span class="plain"> *</span><span class="identifier">macro</span><span class="plain">, </span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">con</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">macro</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 kind macro to play back"</span><span class="plain">);</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">KIND_CREATIONS</span><span class="plain">, </span><span class="string">"Macro %S on %S (%d lines)\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
|
|
<span class="identifier">macro</span><span class="plain">-</span><span class="element">>kind_macro_name</span><span class="plain">, </span><span class="identifier">con</span><span class="plain">-</span><span class="element">>name_in_template_code</span><span class="plain">, </span><span class="identifier">macro</span><span class="plain">-</span><span class="element">>kind_macro_line_count</span><span class="plain">);</span>
|
|
<span class="identifier">LOG_INDENT</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"><</span><span class="identifier">macro</span><span class="plain">-</span><span class="element">>kind_macro_line_count</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
|
|
<span class="functiontext">Kinds::Interpreter::apply_kind_command</span><span class="plain">(</span><span class="identifier">macro</span><span class="plain">-</span><span class="element">>kind_macro_line</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">], </span><span class="identifier">con</span><span class="plain">);</span>
|
|
<span class="identifier">LOG_OUTDENT</span><span class="plain">;</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">KIND_CREATIONS</span><span class="plain">, </span><span class="string">"Macro %S ended\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">macro</span><span class="plain">-</span><span class="element">>kind_macro_name</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::play_back_kind_macro is used in <a href="#SP28_1">§28.1</a>, 2/kc2 (<a href="2-kc2.html#SP7_1">§7.1</a>, <a href="2-kc2.html#SP11">§11</a>, <a href="2-kc2.html#SP12">§12</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP25"></a><b>§25. The kind text archiver. </b>Large chunks of the text in the template will need to exist permanently in
|
|
memory, and we go into recording mode to accept a series of them,
|
|
concatenated with newlines dividing them, in a text stream.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">kind_recording</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP26"></a><b>§26. </b>And here is recording mode:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">Kinds::Interpreter::begin_recording_kind_text</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="identifier">kind_recording</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">kind_recording</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::record_kind_text</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">line</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">kind_recording</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">"can't record outside recording"</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">kind_recording</span><span class="plain">, </span><span class="string">"%S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">line</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::end_recording_kind_text</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="identifier">kind_recording</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::begin_recording_kind_text is used in <a href="#SP18">§18</a>.</p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::record_kind_text is used in <a href="#SP18">§18</a>.</p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::end_recording_kind_text is used in <a href="#SP18">§18</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP27"></a><b>§27. Error messages. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::kind_command_error</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">command</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> *</span><span class="identifier">error</span><span class="plain">) {</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Kind command error found at: %S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">command</span><span class="plain">);</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="identifier">error</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::kind_command_error is used in <a href="#SP15_2">§15.2</a>, <a href="#SP15_3">§15.3</a>, <a href="#SP15_4">§15.4</a>, <a href="#SP15_5">§15.5</a>, <a href="#SP15_7">§15.7</a>, <a href="#SP15_10">§15.10</a>, <a href="#SP15_11">§15.11</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP28"></a><b>§28. Applying kind commands. </b>We take a single kind command and apply it to a given kind.
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">apply_macro_KCC</span><span class="plain"> 1</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">apply_template_KCC</span><span class="plain"> 2</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">can_coincide_with_property_KCC</span><span class="plain"> 5</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">can_exchange_KCC</span><span class="plain"> 6</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">cast_KCC</span><span class="plain"> 7</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">comparison_routine_KCC</span><span class="plain"> 8</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">comparison_schema_KCC</span><span class="plain"> 9</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">constant_compilation_method_KCC</span><span class="plain"> 10</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">constructor_arity_KCC</span><span class="plain"> 11</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">default_value_KCC</span><span class="plain"> 12</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">defined_in_source_text_KCC</span><span class="plain"> 13</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">description_KCC</span><span class="plain"> 14</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">distinguisher_KCC</span><span class="plain"> 15</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">documentation_reference_KCC</span><span class="plain"> 16</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">explicit_i6_GPR_KCC</span><span class="plain"> 17</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">group_KCC</span><span class="plain"> 18</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">has_i6_GPR_KCC</span><span class="plain"> 19</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">heap_size_estimate_KCC</span><span class="plain"> 20</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">i6_printing_routine_actions_KCC</span><span class="plain"> 21</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">i6_printing_routine_KCC</span><span class="plain"> 22</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">index_default_value_KCC</span><span class="plain"> 23</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">index_maximum_value_KCC</span><span class="plain"> 24</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">index_minimum_value_KCC</span><span class="plain"> 25</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">indexed_grey_if_empty_KCC</span><span class="plain"> 26</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">index_priority_KCC</span><span class="plain"> 27</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">instance_of_KCC</span><span class="plain"> 28</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">is_incompletely_defined_KCC</span><span class="plain"> 29</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">is_template_variable_KCC</span><span class="plain"> 30</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">loop_domain_schema_KCC</span><span class="plain"> 31</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">modifying_adjective_KCC</span><span class="plain"> 32</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">multiple_block_KCC</span><span class="plain"> 33</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">named_values_created_with_assertions_KCC</span><span class="plain"> 34</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">plural_KCC</span><span class="plain"> 35</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">recognition_only_GPR_KCC</span><span class="plain"> 36</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">singular_KCC</span><span class="plain"> 37</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">specification_text_KCC</span><span class="plain"> 38</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">small_block_size_KCC</span><span class="plain"> 39</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">template_variable_number_KCC</span><span class="plain"> 40</span>
|
|
</pre>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::apply_kind_command</span><span class="plain">(</span><span class="reserved">single_kind_command</span><span class="plain"> </span><span class="identifier">stc</span><span class="plain">, </span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">con</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">stc</span><span class="element">.which_kind_command</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">"null STC command"</span><span class="plain">);</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">KIND_CREATIONS</span><span class="plain">, </span><span class="string">"apply: %s (%d/%d/%S/%S) to %d/%S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
|
|
<span class="identifier">stc</span><span class="element">.which_kind_command</span><span class="plain">-</span><span class="element">>text_of_command</span><span class="plain">,</span>
|
|
<span class="identifier">stc</span><span class="element">.boolean_argument</span><span class="plain">, </span><span class="identifier">stc</span><span class="element">.numeric_argument</span><span class="plain">,</span>
|
|
<span class="identifier">stc</span><span class="element">.textual_argument</span><span class="plain">, </span><span class="identifier">stc</span><span class="element">.constructor_argument</span><span class="plain">,</span>
|
|
<span class="identifier">con</span><span class="plain">-></span><span class="identifier">allocation_id</span><span class="plain">, </span><span class="identifier">con</span><span class="plain">-</span><span class="element">>name_in_template_code</span><span class="plain">);</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">tcc</span><span class="plain"> = </span><span class="identifier">stc</span><span class="element">.which_kind_command</span><span class="plain">-</span><span class="element">>opcode_number</span><span class="plain">;</span>
|
|
|
|
<<span class="cwebmacro">Apply kind macros or transcribe kind templates on request</span> <span class="cwebmacronumber">28.1</span>><span class="plain">;</span>
|
|
|
|
<<span class="cwebmacro">Most kind commands simply set a field in the constructor structure</span> <span class="cwebmacronumber">28.2</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">A few kind commands contribute to linked lists in the constructor structure</span> <span class="cwebmacronumber">28.3</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">And the rest fill in fields in the constructor structure in miscellaneous other ways</span> <span class="cwebmacronumber">28.4</span>><span class="plain">;</span>
|
|
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"unimplemented kind command"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::apply_kind_command is used in <a href="#SP14">§14</a>, <a href="#SP24">§24</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP28_1"></a><b>§28.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Apply kind macros or transcribe kind templates on request</span> <span class="cwebmacronumber">28.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">tcc</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">apply_template_KCC</span><span class="plain">:</span>
|
|
<span class="functiontext">Kinds::Interpreter::remember_to_transcribe_spec_template</span><span class="plain">(</span><span class="identifier">stc</span><span class="element">.template_argument</span><span class="plain">, </span><span class="identifier">con</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">apply_macro_KCC</span><span class="plain">:</span>
|
|
<span class="functiontext">Kinds::Interpreter::play_back_kind_macro</span><span class="plain">(</span><span class="identifier">stc</span><span class="element">.macro_argument</span><span class="plain">, </span><span class="identifier">con</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="#SP28">§28</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP28_2"></a><b>§28.2. </b></p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="identifier">SET_BOOLEAN_FIELD</span><span class="plain">(</span><span class="identifier">field</span><span class="plain">) </span><span class="reserved">case</span><span class="plain"> </span><span class="identifier">field</span><span class="plain">##</span><span class="identifier">_KCC</span><span class="plain">: </span><span class="identifier">con</span><span class="plain">-></span><span class="identifier">field</span><span class="plain"> = </span><span class="identifier">stc</span><span class="element">.boolean_argument</span><span class="plain">; </span><span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="definitionkeyword">define</span> <span class="identifier">SET_INTEGER_FIELD</span><span class="plain">(</span><span class="identifier">field</span><span class="plain">) </span><span class="reserved">case</span><span class="plain"> </span><span class="identifier">field</span><span class="plain">##</span><span class="identifier">_KCC</span><span class="plain">: </span><span class="identifier">con</span><span class="plain">-></span><span class="identifier">field</span><span class="plain"> = </span><span class="identifier">stc</span><span class="element">.numeric_argument</span><span class="plain">; </span><span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="definitionkeyword">define</span> <span class="identifier">SET_TEXTUAL_FIELD</span><span class="plain">(</span><span class="identifier">field</span><span class="plain">) </span><span class="reserved">case</span><span class="plain"> </span><span class="identifier">field</span><span class="plain">##</span><span class="identifier">_KCC</span><span class="plain">: </span><span class="identifier">con</span><span class="plain">-></span><span class="identifier">field</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">stc</span><span class="element">.textual_argument</span><span class="plain">); </span><span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="definitionkeyword">define</span> <span class="identifier">SET_CCM_FIELD</span><span class="plain">(</span><span class="identifier">field</span><span class="plain">) </span><span class="reserved">case</span><span class="plain"> </span><span class="identifier">field</span><span class="plain">##</span><span class="identifier">_KCC</span><span class="plain">: </span><span class="identifier">con</span><span class="plain">-></span><span class="identifier">field</span><span class="plain"> = </span><span class="identifier">stc</span><span class="element">.ccm_argument</span><span class="plain">; </span><span class="reserved">return</span><span class="plain">;</span>
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Most kind commands simply set a field in the constructor structure</span> <span class="cwebmacronumber">28.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">tcc</span><span class="plain">) {</span>
|
|
<span class="identifier">SET_BOOLEAN_FIELD</span><span class="plain">(</span><span class="identifier">can_coincide_with_property</span><span class="plain">)</span>
|
|
<span class="identifier">SET_BOOLEAN_FIELD</span><span class="plain">(</span><span class="identifier">can_exchange</span><span class="plain">)</span>
|
|
<span class="identifier">SET_BOOLEAN_FIELD</span><span class="plain">(</span><span class="identifier">defined_in_source_text</span><span class="plain">)</span>
|
|
<span class="identifier">SET_BOOLEAN_FIELD</span><span class="plain">(</span><span class="identifier">has_i6_GPR</span><span class="plain">)</span>
|
|
<span class="identifier">SET_BOOLEAN_FIELD</span><span class="plain">(</span><span class="identifier">indexed_grey_if_empty</span><span class="plain">)</span>
|
|
<span class="identifier">SET_BOOLEAN_FIELD</span><span class="plain">(</span><span class="identifier">is_incompletely_defined</span><span class="plain">)</span>
|
|
<span class="identifier">SET_BOOLEAN_FIELD</span><span class="plain">(</span><span class="identifier">multiple_block</span><span class="plain">)</span>
|
|
<span class="identifier">SET_BOOLEAN_FIELD</span><span class="plain">(</span><span class="identifier">named_values_created_with_assertions</span><span class="plain">)</span>
|
|
|
|
<span class="identifier">SET_INTEGER_FIELD</span><span class="plain">(</span><span class="identifier">group</span><span class="plain">)</span>
|
|
<span class="identifier">SET_INTEGER_FIELD</span><span class="plain">(</span><span class="identifier">heap_size_estimate</span><span class="plain">)</span>
|
|
<span class="identifier">SET_INTEGER_FIELD</span><span class="plain">(</span><span class="identifier">index_priority</span><span class="plain">)</span>
|
|
<span class="identifier">SET_INTEGER_FIELD</span><span class="plain">(</span><span class="identifier">small_block_size</span><span class="plain">)</span>
|
|
|
|
<span class="identifier">SET_CCM_FIELD</span><span class="plain">(</span><span class="identifier">constant_compilation_method</span><span class="plain">)</span>
|
|
|
|
<span class="identifier">SET_TEXTUAL_FIELD</span><span class="plain">(</span><span class="identifier">default_value</span><span class="plain">)</span>
|
|
<span class="identifier">SET_TEXTUAL_FIELD</span><span class="plain">(</span><span class="identifier">distinguisher</span><span class="plain">)</span>
|
|
<span class="identifier">SET_TEXTUAL_FIELD</span><span class="plain">(</span><span class="identifier">documentation_reference</span><span class="plain">)</span>
|
|
<span class="identifier">SET_TEXTUAL_FIELD</span><span class="plain">(</span><span class="identifier">explicit_i6_GPR</span><span class="plain">)</span>
|
|
<span class="identifier">SET_TEXTUAL_FIELD</span><span class="plain">(</span><span class="identifier">index_default_value</span><span class="plain">)</span>
|
|
<span class="identifier">SET_TEXTUAL_FIELD</span><span class="plain">(</span><span class="identifier">index_maximum_value</span><span class="plain">)</span>
|
|
<span class="identifier">SET_TEXTUAL_FIELD</span><span class="plain">(</span><span class="identifier">index_minimum_value</span><span class="plain">)</span>
|
|
<span class="identifier">SET_TEXTUAL_FIELD</span><span class="plain">(</span><span class="identifier">loop_domain_schema</span><span class="plain">)</span>
|
|
<span class="identifier">SET_TEXTUAL_FIELD</span><span class="plain">(</span><span class="identifier">recognition_only_GPR</span><span class="plain">)</span>
|
|
<span class="identifier">SET_TEXTUAL_FIELD</span><span class="plain">(</span><span class="identifier">specification_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="#SP28">§28</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP28_3"></a><b>§28.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">A few kind commands contribute to linked lists in the constructor structure</span> <span class="cwebmacronumber">28.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tcc</span><span class="plain"> == </span><span class="constant">cast_KCC</span><span class="plain">) {</span>
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="identifier">stc</span><span class="element">.constructor_argument</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"SNIPPET_TY"</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Plugins::Manage::plugged_in</span><span class="plain">(</span><span class="identifier">parsing_plugin</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="plain">#</span><span class="identifier">endif</span>
|
|
<span class="reserved">kind_constructor_casting_rule</span><span class="plain"> *</span><span class="identifier">dtcr</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">kind_constructor_casting_rule</span><span class="plain">);</span>
|
|
<span class="identifier">dtcr</span><span class="plain">-</span><span class="element">>next_casting_rule</span><span class="plain"> = </span><span class="identifier">con</span><span class="plain">-</span><span class="element">>first_casting_rule</span><span class="plain">;</span>
|
|
<span class="identifier">con</span><span class="plain">-</span><span class="element">>first_casting_rule</span><span class="plain"> = </span><span class="identifier">dtcr</span><span class="plain">;</span>
|
|
<span class="identifier">dtcr</span><span class="plain">-</span><span class="element">>cast_from_kind_unparsed</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">stc</span><span class="element">.constructor_argument</span><span class="plain">);</span>
|
|
<span class="identifier">dtcr</span><span class="plain">-</span><span class="element">>cast_from_kind</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tcc</span><span class="plain"> == </span><span class="constant">instance_of_KCC</span><span class="plain">) {</span>
|
|
<span class="reserved">kind_constructor_instance</span><span class="plain"> *</span><span class="identifier">dti</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">kind_constructor_instance</span><span class="plain">);</span>
|
|
<span class="identifier">dti</span><span class="plain">-</span><span class="element">>next_instance_rule</span><span class="plain"> = </span><span class="identifier">con</span><span class="plain">-</span><span class="element">>first_instance_rule</span><span class="plain">;</span>
|
|
<span class="identifier">con</span><span class="plain">-</span><span class="element">>first_instance_rule</span><span class="plain"> = </span><span class="identifier">dti</span><span class="plain">;</span>
|
|
<span class="identifier">dti</span><span class="plain">-</span><span class="element">>instance_of_this_unparsed</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">stc</span><span class="element">.constructor_argument</span><span class="plain">);</span>
|
|
<span class="identifier">dti</span><span class="plain">-</span><span class="element">>instance_of_this</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tcc</span><span class="plain"> == </span><span class="constant">comparison_schema_KCC</span><span class="plain">) {</span>
|
|
<span class="reserved">kind_constructor_comparison_schema</span><span class="plain"> *</span><span class="identifier">dtcs</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">kind_constructor_comparison_schema</span><span class="plain">);</span>
|
|
<span class="identifier">dtcs</span><span class="plain">-</span><span class="element">>next_comparison_schema</span><span class="plain"> = </span><span class="identifier">con</span><span class="plain">-</span><span class="element">>first_comparison_schema</span><span class="plain">;</span>
|
|
<span class="identifier">con</span><span class="plain">-</span><span class="element">>first_comparison_schema</span><span class="plain"> = </span><span class="identifier">dtcs</span><span class="plain">;</span>
|
|
<span class="identifier">dtcs</span><span class="plain">-</span><span class="element">>comparator_unparsed</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">stc</span><span class="element">.constructor_argument</span><span class="plain">);</span>
|
|
<span class="identifier">dtcs</span><span class="plain">-</span><span class="element">>comparator</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">dtcs</span><span class="plain">-</span><span class="element">>comparison_schema</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">stc</span><span class="element">.textual_argument</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="#SP28">§28</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP28_4"></a><b>§28.4. </b><code class="display">
|
|
<<span class="cwebmacrodefn">And the rest fill in fields in the constructor structure in miscellaneous other ways</span> <span class="cwebmacronumber">28.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">tcc</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">constructor_arity_KCC</span><span class="plain">:</span>
|
|
<<span class="cwebmacro">Parse the constructor arity text</span> <span class="cwebmacronumber">28.4.1</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">description_KCC</span><span class="plain">:</span>
|
|
<span class="identifier">con</span><span class="plain">-</span><span class="element">>constructor_description</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">stc</span><span class="element">.textual_argument</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">comparison_routine_KCC</span><span class="plain">:</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">stc</span><span class="element">.textual_argument</span><span class="plain">) > 31) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"overlong I6 identifier"</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">con</span><span class="plain">-</span><span class="element">>comparison_routine</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">stc</span><span class="element">.textual_argument</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">i6_printing_routine_KCC</span><span class="plain">:</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">stc</span><span class="element">.textual_argument</span><span class="plain">) > 31) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"overlong I6 identifier"</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">con</span><span class="plain">-</span><span class="element">>dt_I6_identifier</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">stc</span><span class="element">.textual_argument</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">i6_printing_routine_actions_KCC</span><span class="plain">:</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">stc</span><span class="element">.textual_argument</span><span class="plain">) > 31) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"overlong I6 identifier"</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">con</span><span class="plain">-</span><span class="element">>name_of_printing_rule_ACTIONS</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">stc</span><span class="element">.textual_argument</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">singular_KCC</span><span class="plain">: </span><span class="reserved">case</span><span class="plain"> </span><span class="constant">plural_KCC</span><span class="plain">: {</span>
|
|
<span class="identifier">vocabulary_entry</span><span class="plain"> **</span><span class="identifier">array</span><span class="plain">; </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">length</span><span class="plain">;</span>
|
|
<span class="identifier">WordAssemblages::as_array</span><span class="plain">(&(</span><span class="identifier">stc</span><span class="element">.vocabulary_argument</span><span class="plain">), &</span><span class="identifier">array</span><span class="plain">, &</span><span class="identifier">length</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">length</span><span class="plain"> == 1) {</span>
|
|
<span class="functiontext">Kinds::mark_vocabulary_as_kind</span><span class="plain">(</span><span class="identifier">array</span><span class="plain">[0], </span><span class="functiontext">Kinds::base_construction</span><span class="plain">(</span><span class="identifier">con</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">=0; </span><span class="identifier">i</span><span class="plain"><</span><span class="identifier">length</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
|
|
<span class="identifier">Vocabulary::set_flags</span><span class="plain">(</span><span class="identifier">array</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">], </span><span class="constant">KIND_SLOW_MC</span><span class="plain">);</span>
|
|
<span class="identifier">Preform::mark_vocabulary</span><span class="plain">(</span><span class="identifier">array</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">], <</span><span class="identifier">k</span><span class="plain">-</span><span class="reserved">kind</span><span class="plain">>);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">con</span><span class="plain">-</span><span class="element">>group</span><span class="plain"> != </span><span class="constant">PROPER_CONSTRUCTOR_GRP</span><span class="plain">) {</span>
|
|
<span class="identifier">vocabulary_entry</span><span class="plain"> *</span><span class="identifier">ve</span><span class="plain"> = </span><span class="identifier">WordAssemblages::hyphenated</span><span class="plain">(&(</span><span class="identifier">stc</span><span class="element">.vocabulary_argument</span><span class="plain">));</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ve</span><span class="plain">) </span><span class="functiontext">Kinds::mark_vocabulary_as_kind</span><span class="plain">(</span><span class="identifier">ve</span><span class="plain">, </span><span class="functiontext">Kinds::base_construction</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">));</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">feed_t</span><span class="plain"> </span><span class="identifier">id</span><span class="plain"> = </span><span class="identifier">Feeds::begin</span><span class="plain">();</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"><</span><span class="identifier">length</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
|
|
<span class="identifier">Feeds::feed_text</span><span class="plain">(</span><span class="identifier">Vocabulary::get_exemplar</span><span class="plain">(</span><span class="identifier">array</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">], </span><span class="identifier">FALSE</span><span class="plain">));</span>
|
|
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">LW</span><span class="plain"> = </span><span class="identifier">Feeds::end</span><span class="plain">(</span><span class="identifier">id</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tcc</span><span class="plain"> == </span><span class="constant">singular_KCC</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">ro</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">con</span><span class="plain">-</span><span class="element">>group</span><span class="plain"> != </span><span class="constant">PROPER_CONSTRUCTOR_GRP</span><span class="plain">) </span><span class="identifier">ro</span><span class="plain"> = </span><span class="identifier">REGISTER_SINGULAR_NTOPT</span><span class="plain"> + </span><span class="identifier">REGISTER_PLURAL_NTOPT</span><span class="plain">;</span>
|
|
<span class="identifier">noun</span><span class="plain"> *</span><span class="identifier">nt</span><span class="plain"> =</span>
|
|
<span class="identifier">Nouns::new_common_noun</span><span class="plain">(</span><span class="identifier">LW</span><span class="plain">, </span><span class="identifier">NEUTER_GENDER</span><span class="plain">, </span><span class="identifier">PARSE_EXACTLY_NTOPT</span><span class="plain"> + </span><span class="identifier">ro</span><span class="plain">,</span>
|
|
<span class="constant">KIND_SLOW_MC</span><span class="plain">, </span><span class="identifier">STORE_POINTER_kind_constructor</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">));</span>
|
|
<span class="identifier">con</span><span class="plain">-</span><span class="element">>dt_tag</span><span class="plain"> = </span><span class="identifier">nt</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">Nouns::set_plural_name</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">-</span><span class="element">>dt_tag</span><span class="plain">, </span><span class="identifier">LW</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">modifying_adjective_KCC</span><span class="plain">:</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"the modifying-adjective syntax has been withdrawn"</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="#SP28">§28</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP28_4_1"></a><b>§28.4.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Parse the constructor arity text</span> <span class="cwebmacronumber">28.4.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">string_position</span><span class="plain"> </span><span class="identifier">pos</span><span class="plain"> = </span><span class="identifier">Str::start</span><span class="plain">(</span><span class="identifier">stc</span><span class="element">.textual_argument</span><span class="plain">);</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">TRUE</span><span class="plain">) {</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">Characters::is_space_or_tab</span><span class="plain">(</span><span class="identifier">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">))) </span><span class="identifier">pos</span><span class="plain"> = </span><span class="identifier">Str::forward</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">) == 0) </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">) == </span><span class="character">','</span><span class="plain">) { </span><span class="identifier">c</span><span class="plain">++; </span><span class="identifier">pos</span><span class="plain"> = </span><span class="identifier">Str::forward</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">); </span><span class="reserved">continue</span><span class="plain">; }</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> >= 2) { </span><span class="identifier">c</span><span class="plain">=1; </span><span class="reserved">break</span><span class="plain">; }</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">wd</span><span class="plain">);</span>
|
|
<span class="reserved">while</span><span class="plain"> ((!</span><span class="identifier">Characters::is_space_or_tab</span><span class="plain">(</span><span class="identifier">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">))) && (</span><span class="identifier">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">) != </span><span class="character">','</span><span class="plain">) && (</span><span class="identifier">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">) != 0)) {</span>
|
|
<span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">wd</span><span class="plain">, </span><span class="identifier">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">)); </span><span class="identifier">pos</span><span class="plain"> = </span><span class="identifier">Str::forward</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">wd</span><span class="plain">) > 0) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">wd</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"covariant"</span><span class="plain">)) </span><span class="identifier">con</span><span class="plain">-</span><span class="element">>variance</span><span class="plain">[</span><span class="identifier">c</span><span class="plain">] = </span><span class="constant">COVARIANT</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">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">wd</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"contravariant"</span><span class="plain">)) </span><span class="identifier">con</span><span class="plain">-</span><span class="element">>variance</span><span class="plain">[</span><span class="identifier">c</span><span class="plain">] = </span><span class="constant">CONTRAVARIANT</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">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">wd</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"optional"</span><span class="plain">)) </span><span class="identifier">con</span><span class="plain">-</span><span class="element">>tupling</span><span class="plain">[</span><span class="identifier">c</span><span class="plain">] = </span><span class="constant">ALLOW_NOTHING_TUPLING</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">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">wd</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"list"</span><span class="plain">)) </span><span class="identifier">con</span><span class="plain">-</span><span class="element">>tupling</span><span class="plain">[</span><span class="identifier">c</span><span class="plain">] = </span><span class="constant">ARBITRARY_TUPLING</span><span class="plain">;</span>
|
|
<span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Word: <%S>\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">wd</span><span class="plain">);</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"illegal constructor-arity keyword"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">wd</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">con</span><span class="plain">-</span><span class="element">>constructor_arity</span><span class="plain"> = </span><span class="identifier">c</span><span class="plain">+1;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP28_4">§28.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP29"></a><b>§29. Completing a batch. </b>At one time it was useful to do some mopping-up work after a round of kind
|
|
commands, so the following hook was devised; but at present it's not needed.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Interpreter::batch_done</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::Interpreter::batch_done appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP30"></a><b>§30. </b>And that completes the kind interpreter.
|
|
</p>
|
|
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><a href="2-kc2.html">Back to 'Kind Constructors'</a></li><li><a href="2-uk.html">Continue with 'Using Kinds'</a></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</body>
|
|
</html>
|
|
|