1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 18:14:21 +03:00
inform7/docs/kinds-module/2-kc2.html
2020-03-22 10:50:19 +00:00

876 lines
111 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/kc</title>
<meta name="viewport" content="width=device-width initial-scale=1">
<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>
<nav role="navigation">
<h1><a href="../webs.html">Sources</a></h1>
<ul>
<li><a href="../compiler.html"><b>compiler</b></a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul>
<h2>Compiler Webs</h2>
<ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
</ul>
<h2>Inbuild Modules</h2>
<ul>
<li><a href="../inbuild-module/index.html">inbuild</a></li>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../html-module/index.html">html</a></li>
</ul>
<h2>Inform7 Modules</h2>
<ul>
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="../index-module/index.html">index</a></li>
</ul>
<h2>Inter Modules</h2>
<ul>
<li><a href="../inter-module/index.html">inter</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul>
<h2>Foundation</h2>
<ul>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of '2/kc2' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Modules</a></li><li><a href="index.html">kinds</a></li><li><a href="index.html#2">Chapter 2: Kinds</a></li><li><b>Kind Constructors</b></li></ul><p class="purpose">The mechanism by which Inform records the characteristics of different kinds.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li><li><a href="#SP7">&#167;7. Creation</a></li><li><a href="#SP8">&#167;8. The noun</a></li><li><a href="#SP9">&#167;9. Names in the I6 template</a></li><li><a href="#SP11">&#167;11. Transformations</a></li><li><a href="#SP14">&#167;14. For construction purposes</a></li><li><a href="#SP15">&#167;15. Questions about constructors</a></li><li><a href="#SP16">&#167;16. Cast and instance lists</a></li><li><a href="#SP18">&#167;18. Compatibility</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Constructors are divided into four:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">KIND_VARIABLE_GRP</span><span class="plain"> 1 </span> <span class="comment">just <code class="display"><span class="extract">CON_KIND_VARIABLE</span></code> on its own</span>
<span class="definitionkeyword">define</span> <span class="constant">KIND_OF_KIND_GRP</span><span class="plain"> 2 </span> <span class="comment">an indefinite base constructor such as "arithmetic value"</span>
<span class="definitionkeyword">define</span> <span class="constant">BASE_CONSTRUCTOR_GRP</span><span class="plain"> 3 </span> <span class="comment">a definite one such as "number"</span>
<span class="definitionkeyword">define</span> <span class="constant">PROPER_CONSTRUCTOR_GRP</span><span class="plain"> 4 </span> <span class="comment">with positive arity, such as "list of K"</span>
</pre>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Inform provides much more extensive facilities for kinds than most
programming languages do for their types. As far as possible, we want to
write this code in a generalised way, rather than writing hacky routines
which each apply to a fixed, named kind. This won't always be possible, it's
true, but we can try. The only way to achieve this is to store an enormous
rag-bag of properties for every kind constructor, showing exactly how it
behaves.
</p>
<p class="inwebparagraph">All of which is by way of apology for the enormous size of the <code class="display"><span class="extract">kind_constructor</span></code>
structure. It looks impossibly large to fill out, and this is why we have the
kind interpreter (see next section) to give the I6 template the ability to
forge new kind constructors.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">LOWEST_INDEX_PRIORITY</span><span class="plain"> 100</span>
</pre>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind_constructor</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">noun</span><span class="plain"> *</span><span class="identifier">dt_tag</span><span class="plain">; </span> <span class="comment">text of name</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">group</span><span class="plain">; </span> <span class="comment">one of the four values above</span>
<span class="comment">A: how this came into being</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">defined_in_source_text</span><span class="plain">; </span> <span class="comment">rather than by I6 template files, i.e., by being built-in</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">is_incompletely_defined</span><span class="plain">; </span> <span class="comment">newly defined and ambiguous as yet</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">where_defined_in_source_text</span><span class="plain">; </span> <span class="comment">if so</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">stored_as</span><span class="plain">; </span> <span class="comment">currently unused: if this is a typedef for some construction</span>
<span class="comment">B: constructing kinds</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">constructor_arity</span><span class="plain">; </span> <span class="comment">0 for base, 1 for unary, 2 for binary</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">variance</span><span class="plain">[</span><span class="constant">MAX_KIND_CONSTRUCTION_ARITY</span><span class="plain">]; </span> <span class="comment">must be <code class="display"><span class="extract">COVARIANT</span></code> or <code class="display"><span class="extract">CONTRAVARIANT</span></code></span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">tupling</span><span class="plain">[</span><span class="constant">MAX_KIND_CONSTRUCTION_ARITY</span><span class="plain">]; </span> <span class="comment">extent to which tupling is permitted</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">cached_kind</span><span class="plain">; </span> <span class="comment">cached result of <code class="display"><span class="extract">Kinds::base_construction</span></code></span>
<span class="comment">C: compatibility with other kinds</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">superkind_set_at</span><span class="plain">; </span> <span class="comment">where it says, e.g., "A rabbit is a kind of animal"</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">first_casting_rule</span><span class="plain">; </span> <span class="comment">list of these</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind_constructor_instance</span><span class="plain"> *</span><span class="identifier">first_instance_rule</span><span class="plain">; </span> <span class="comment">list of these</span>
<span class="comment">D: how constant values of this kind are expressed</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">literal_pattern</span><span class="plain"> *</span><span class="identifier">ways_to_write_literals</span><span class="plain">; </span> <span class="comment">list of ways to write this</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">named_values_created_with_assertions</span><span class="plain">; </span> <span class="comment">such as "Train Arrival is a scene."</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">table</span><span class="plain"> *</span><span class="identifier">named_values_created_with_table</span><span class="plain">; </span> <span class="comment">alternatively...</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">next_free_value</span><span class="plain">; </span> <span class="comment">to make distinguishable instances of this kind</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">constant_compilation_method</span><span class="plain">; </span> <span class="comment">one of the <code class="display"><span class="extract">*_CCM</span></code> values</span>
<span class="comment">E: knowledge about values of this kind</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">dt_knowledge</span><span class="plain">; </span> <span class="comment">inferences about properties</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">default_value</span><span class="plain">; </span> <span class="comment">used for built-in types only</span>
<span class="comment">F: behaviour as a property as well</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">can_coincide_with_property</span><span class="plain">; </span> <span class="comment">allowed to coincide in name with a property</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">property</span><span class="plain"> *</span><span class="identifier">coinciding_property</span><span class="plain">; </span> <span class="comment">property of the same name, if any</span>
<span class="comment">G: performing arithmetic</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">comparison_routine</span><span class="plain">; </span> <span class="comment">for instance, when sorting table or list entries</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">dimensional_rules</span><span class="plain"> </span><span class="identifier">dim_rules</span><span class="plain">; </span> <span class="comment">how arithmetic operations work here</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">unit_sequence</span><span class="plain"> </span><span class="identifier">dimensional_form</span><span class="plain">; </span> <span class="comment">dimensions of this kind</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">dimensional_form_fixed</span><span class="plain">; </span> <span class="comment">whether they are derived</span>
<span class="comment">H: representing this kind at run-time</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">weak_kind_ID</span><span class="plain">; </span> <span class="comment">as used at run-time by the I6 template</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name_in_template_code</span><span class="plain">; </span> <span class="comment">an I6 identifier</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">con_iname</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">kc_package</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">small_block_size</span><span class="plain">; </span> <span class="comment">if stored as a block value, size in words of the SB</span>
<span class="comment">I: storing values at run-time</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">multiple_block</span><span class="plain">; </span> <span class="comment">TRUE for flexible-size values stored on the heap</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">heap_size_estimate</span><span class="plain">; </span> <span class="comment">typical number of bytes used</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">can_exchange</span><span class="plain">; </span> <span class="comment">with external files and therefore other story files</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">distinguisher</span><span class="plain">; </span> <span class="comment">I6 routine to see if values distinguishable</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">first_comparison_schema</span><span class="plain">; </span> <span class="comment">list of these</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">loop_domain_schema</span><span class="plain">; </span> <span class="comment">how to compile an I6 loop over the instances</span>
<span class="comment">J: printing and parsing values at run-time</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">INTER_MODULE</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">kind_GPR_iname</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">instance_GPR_iname</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">first_instance_iname</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">next_instance_iname</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">pr_iname</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">inc_iname</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">dec_iname</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">ranger_iname</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">trace_iname</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">dt_I6_identifier</span><span class="plain">; </span> <span class="comment">an I6 identifier used for compiling printing rules</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">name_of_printing_rule_ACTIONS</span><span class="plain">; </span> <span class="comment">ditto but for ACTIONS testing command</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">grammar_verb</span><span class="plain"> *</span><span class="identifier">understand_as_values</span><span class="plain">; </span> <span class="comment">used when parsing such values</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">has_i6_GPR</span><span class="plain">; </span> <span class="comment">a general parsing routine exists in the I6 code for this</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">I6_GPR_needed</span><span class="plain">; </span> <span class="comment">and is actually required</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">explicit_i6_GPR</span><span class="plain">; </span> <span class="comment">routine name, when not compiled automatically</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">recognition_only_GPR</span><span class="plain">; </span> <span class="comment">for recognising an explicit value as preposition</span>
<span class="comment">K: indexing and documentation</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">specification_text</span><span class="plain">; </span> <span class="comment">text for parse_node</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">constructor_description</span><span class="plain">; </span> <span class="comment">text used in index pages</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">index_default_value</span><span class="plain">; </span> <span class="comment">and its description in the Kinds index</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">index_maximum_value</span><span class="plain">; </span> <span class="comment">ditto</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">index_minimum_value</span><span class="plain">; </span> <span class="comment">ditto</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">index_priority</span><span class="plain">; </span> <span class="comment">from 1 (highest) to <code class="display"><span class="extract">LOWEST_INDEX_PRIORITY</span></code> (lowest)</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">linguistic</span><span class="plain">; </span> <span class="comment">divide off as having linguistics content</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">indexed_grey_if_empty</span><span class="plain">; </span> <span class="comment">shaded grey in the Kinds index</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">documentation_reference</span><span class="plain">; </span> <span class="comment">documentation symbol, if any</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">kind_constructor</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure kind_constructor is accessed in 2/kc, 2/ki, 2/uk and here.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>The "tupling" of an argument is the extent to which an argument can be
allowed to hold a variable-length list of kinds, rather than a single one.
There aren't actually many possibilities.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">NO_TUPLING</span><span class="plain"> 0 </span> <span class="comment">a single kind</span>
<span class="definitionkeyword">define</span> <span class="constant">ALLOW_NOTHING_TUPLING</span><span class="plain"> 1 </span> <span class="comment">a single kind, or "nothing"</span>
<span class="definitionkeyword">define</span> <span class="constant">ARBITRARY_TUPLING</span><span class="plain"> 10000 </span> <span class="comment">a list of kinds of any length</span>
</pre>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>Constant compilation modes are:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">NONE_CCM</span><span class="plain"> 1 </span> <span class="comment">constant values of this kind cannot exist</span>
<span class="definitionkeyword">define</span> <span class="constant">LITERAL_CCM</span><span class="plain"> 2 </span> <span class="comment">a numerical annotation decides the value</span>
<span class="definitionkeyword">define</span> <span class="constant">NAMED_CONSTANT_CCM</span><span class="plain"> 3 </span> <span class="comment">an <code class="display"><span class="extract">instance</span></code> annotation decides the value</span>
<span class="definitionkeyword">define</span> <span class="constant">SPECIAL_CCM</span><span class="plain"> 4 </span> <span class="comment">special code specific to the kind of value is needed</span>
</pre>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>We keep track of the newest-created base kind of value (which isn't a kind
of object) here:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">next_free_data_type_ID</span><span class="plain"> = 2; </span> <span class="comment">i.e., leaving room for <code class="display"><span class="extract">UNKNOWN_TY</span></code> to be 1 at run-time</span>
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">latest_base_kind_of_value</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Creation. </b>Constructors come from two sources. Built-in ones like "number" or
"list of K" mainly come from the commands given in the "Load-Core.i6t"
template file, which consists almost entirely of commands for the kind
interpreter, which sets up most of the above. (Similar files for other
language plugins add the remainder.) Thus a great deal can be changed about
the interplay of kinds without altering the compiler itself.
</p>
<p class="inwebparagraph">New kinds created by the source text, by sentences like "Air pressure is a
kind of value", are always base constructors (i.e., they have arity 0); at
present there's no way to create new kinds of kinds, or new constructors, in
Inform source text. (So an extension wanting to make new constructors, say
to add new "collection classes" to Inform, will have to get its hands
dirty with Inform 6 insertions and use of the kind interpreter.)
</p>
<p class="inwebparagraph">Here <code class="display"><span class="extract">super</span></code> will be the super-constructor, the one which this will construct
subkinds of. In practice this will be <code class="display"><span class="extract">NULL</span></code> when <code class="display"><span class="extract">CON_VALUE</span></code> is created, and
then <code class="display"><span class="extract">CON_VALUE</span></code> for kinds like "number" or this one:
</p>
<blockquote>
<p>Weight is a kind of value.</p>
</blockquote>
<p class="inwebparagraph">but will be the constructor for "door" for kinds like this one:
</p>
<blockquote>
<p>Portal is a kind of door.</p>
</blockquote>
<pre class="display">
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="functiontext">Kinds::Constructors::new</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">, </span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">super</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">source_name</span><span class="plain">,</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">initialisation_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="identifier">CREATE</span><span class="plain">(</span><span class="reserved">kind_constructor</span><span class="plain">);</span>
<span class="reserved">kind_constructor</span><span class="plain"> **</span><span class="identifier">pC</span><span class="plain"> = </span><span class="functiontext">Kinds::known_constructor_name</span><span class="plain">(</span><span class="identifier">source_name</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pC</span><span class="plain">) *</span><span class="identifier">pC</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">super</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>&lt;<span class="cwebmacro">Fill in a new constructor</span> <span class="cwebmacronumber">7.1</span>&gt;
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Copy the new constructor from its superconstructor</span> <span class="cwebmacronumber">7.2</span>&gt;<span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;name_in_template_code</span><span class="plain"> = </span><span class="identifier">Str::new</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">con</span><span class="plain">-</span><span class="element">&gt;con_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;kc_package</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">source_name</span><span class="plain">) &gt; 0) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;name_in_template_code</span><span class="plain">, </span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">source_name</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">con</span><span class="plain"> != </span><span class="identifier">CON_KIND_VARIABLE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">con</span><span class="plain"> != </span><span class="identifier">CON_INTERMEDIATE</span><span class="plain">))</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;dt_knowledge</span><span class="plain"> = </span><span class="identifier">Kinds::Knowledge::create_for_constructor</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;where_defined_in_source_text</span><span class="plain"> = </span><span class="identifier">current_sentence</span><span class="plain">;</span>
<span class="reserved">kind</span><span class="plain"> **</span><span class="identifier">pK</span><span class="plain"> = </span><span class="functiontext">Kinds::known_kind_name</span><span class="plain">(</span><span class="identifier">source_name</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pK</span><span class="plain">) *</span><span class="identifier">pK</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="reserved">return</span><span class="plain"> </span><span class="identifier">con</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Constructors::new is used in 2/knd (<a href="2-knd.html#SP33">&#167;33</a>), 2/ki (<a href="2-ki.html#SP14_1">&#167;14.1</a>).</p>
<p class="inwebparagraph"><a id="SP7_1"></a><b>&#167;7.1. </b>If our new constructor is wholly new, and isn't a subkind of something else,
we need to initialise the entire data structure; but note that, having done so,
we ask the kind interpreter to load it up with any defaults set in the
I6 template files.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Fill in a new constructor</span> <span class="cwebmacronumber">7.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;dt_tag</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;group</span><span class="plain"> = 0; </span> <span class="comment">which is invalid, so the interpreter needs to set it</span>
<span class="comment">A: how this came into being</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;defined_in_source_text</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;is_incompletely_defined</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;where_defined_in_source_text</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">but will be filled in imminently</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;stored_as</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="comment">B: constructing kinds</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;constructor_arity</span><span class="plain"> = 0; </span> <span class="comment">by default a base constructor</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">&lt;</span><span class="constant">MAX_KIND_CONSTRUCTION_ARITY</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="element">&gt;variance</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="constant">COVARIANT</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;tupling</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="constant">NO_TUPLING</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;cached_kind</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="comment">C: compatibility with other kinds</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;superkind_set_at</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;first_casting_rule</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;first_instance_rule</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="comment">D: how constant values of this kind are expressed</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;ways_to_write_literals</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;named_values_created_with_assertions</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;named_values_created_with_table</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;next_free_value</span><span class="plain"> = 1;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;constant_compilation_method</span><span class="plain"> = </span><span class="constant">NONE_CCM</span><span class="plain">;</span>
<span class="comment">E: knowledge about values of this kind</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;dt_knowledge</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">but will be filled in imminently, in almost all cases</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;default_value</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="comment">F: behaviour as a property as well</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;can_coincide_with_property</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;coinciding_property</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="comment">G: performing arithmetic</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;comparison_routine</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;comparison_routine</span><span class="plain">, </span><span class="string">"UnsignedCompare"</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="identifier">CON_KIND_VARIABLE</span><span class="plain">) || (</span><span class="identifier">con</span><span class="plain"> == </span><span class="identifier">CON_INTERMEDIATE</span><span class="plain">) ||</span>
<span class="plain">((</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">source_name</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"NUMBER_TY"</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">source_name</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"REAL_NUMBER_TY"</span><span class="plain">))))</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;dimensional_form</span><span class="plain"> =</span>
<span class="functiontext">Kinds::Dimensions::fundamental_unit_sequence</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;dimensional_form</span><span class="plain"> =</span>
<span class="functiontext">Kinds::Dimensions::fundamental_unit_sequence</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="identifier">con</span><span class="plain">-</span><span class="element">&gt;dimensional_form_fixed</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="functiontext">Kinds::Dimensions::dim_initialise</span><span class="plain">(&amp;(</span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;dim_rules</span><span class="plain">));</span>
<span class="comment">H: representing this kind at run-time</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;weak_kind_ID</span><span class="plain"> = </span><span class="identifier">next_free_data_type_ID</span><span class="plain">++;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;name_in_template_code</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="comment">I: storing values at run-time</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;multiple_block</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;small_block_size</span><span class="plain"> = 1;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;heap_size_estimate</span><span class="plain"> = 0;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;can_exchange</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;first_comparison_schema</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;distinguisher</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;loop_domain_schema</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="comment">J: printing and parsing values at run-time</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;dt_I6_identifier</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;name_of_printing_rule_ACTIONS</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">INTER_MODULE</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;kind_GPR_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;instance_GPR_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;first_instance_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;next_instance_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;pr_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;inc_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;dec_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;ranger_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;trace_iname</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">source_name</span><span class="plain">) == 0) {</span>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">Kinds::Constructors::package</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">&gt;pr_iname</span><span class="plain"> = </span><span class="identifier">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="identifier">PRINT_DASH_FN_HL</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">);</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;trace_iname</span><span class="plain"> = </span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;pr_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;understand_as_values</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;has_i6_GPR</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;I6_GPR_needed</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;explicit_i6_GPR</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;recognition_only_GPR</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="comment">K: indexing and documentation</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;specification_text</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;constructor_description</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;index_default_value</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"--"</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;index_maximum_value</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"--"</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;index_minimum_value</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"--"</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;index_priority</span><span class="plain"> = </span><span class="constant">LOWEST_INDEX_PRIORITY</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;linguistic</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;indexed_grey_if_empty</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;documentation_reference</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="functiontext">Kinds::Interpreter::play_back_kind_macro</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">,</span>
<span class="functiontext">Kinds::Interpreter::parse_kind_macro_name</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"#DEFAULTS"</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">Str::len</span><span class="plain">(</span><span class="identifier">initialisation_macro</span><span class="plain">) &gt; 0)</span>
<span class="functiontext">Kinds::Interpreter::play_back_kind_macro</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">,</span>
<span class="functiontext">Kinds::Interpreter::parse_kind_macro_name</span><span class="plain">(</span><span class="identifier">initialisation_macro</span><span class="plain">), </span><span class="identifier">con</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP7_2"></a><b>&#167;7.2. </b>However, if we create our constructor as a subkind, like so:
</p>
<blockquote>
<p>A turtle is a kind of animal.</p>
</blockquote>
<p class="inwebparagraph">then we copy the entire "animal" constructor to initialise the "turtle" one.
</p>
<p class="inwebparagraph">Note that the weak ID number is one of the things copied; this is deliberate.
It means that all kinds of object share the same weak ID as "object".
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Copy the new constructor from its superconstructor</span> <span class="cwebmacronumber">7.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">I</span><span class="plain"> = </span><span class="identifier">con</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain"> = </span><span class="identifier">con</span><span class="plain">-&gt;</span><span class="identifier">next_structure</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">con</span><span class="plain">-&gt;</span><span class="identifier">prev_structure</span><span class="plain">;</span>
<span class="plain">*</span><span class="identifier">con</span><span class="plain"> = *</span><span class="identifier">super</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain"> = </span><span class="identifier">I</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-&gt;</span><span class="identifier">next_structure</span><span class="plain"> = </span><span class="identifier">N</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-&gt;</span><span class="identifier">prev_structure</span><span class="plain"> = </span><span class="identifier">P</span><span class="plain">;</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;cached_kind</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">otherwise the superkind's cache is used by mistake</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;name_in_template_code</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">(); </span> <span class="comment">otherwise this will be called <code class="display"><span class="extract">OBJECT_TY</span></code> by mistake</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. The noun. </b>It's a requirement that the following be called soon after the creation
of the constructor:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::attach_noun</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="identifier">noun</span><span class="plain"> *</span><span class="identifier">nt</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="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">nt</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">"bad noun attachment"</span><span class="plain">);</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;dt_tag</span><span class="plain"> = </span><span class="identifier">nt</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::get_name</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">plural_form</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">&gt;dt_tag</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">con</span><span class="plain">-</span><span class="element">&gt;dt_tag</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nt</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Nouns::get_name</span><span class="plain">(</span><span class="identifier">nt</span><span class="plain">, </span><span class="identifier">plural_form</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::get_name_in_play</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">plural_form</span><span class="plain">,</span>
<span class="identifier">PREFORM_LANGUAGE_TYPE</span><span class="plain"> *</span><span class="identifier">nl</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">&gt;dt_tag</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">con</span><span class="plain">-</span><span class="element">&gt;dt_tag</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nt</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Nouns::get_name_in_play</span><span class="plain">(</span><span class="identifier">nt</span><span class="plain">, </span><span class="identifier">plural_form</span><span class="plain">, </span><span class="identifier">nl</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">noun</span><span class="plain"> *</span><span class="functiontext">Kinds::Constructors::get_noun</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">con</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;dt_tag</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Constructors::attach_noun is used in 2/knd (<a href="2-knd.html#SP33_2">&#167;33.2</a>).</p>
<p class="endnote">The function Kinds::Constructors::get_name is used in <a href="#SP9">&#167;9</a>, 2/ki (<a href="2-ki.html#SP21">&#167;21</a>), 2/uk (<a href="2-uk.html#SP1">&#167;1</a>), 2/dk (<a href="2-dk.html#SP14">&#167;14</a>).</p>
<p class="endnote">The function Kinds::Constructors::get_name_in_play is used in 2/uk (<a href="2-uk.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Kinds::Constructors::get_noun appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Names in the I6 template. </b>An identifier like <code class="display"><span class="extract">WHATEVER_TY</span></code>, then, begins life in a definition inside an
I6 template file; becomes attached to a constructor here; and finally winds up
back in I6 code, because we define it as the constant for the weak kind ID
of the kind which the constructor makes:
</p>
<pre class="display">
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">UNKNOWN_TY_iname</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::Constructors::compile_I6_constants</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="identifier">UNKNOWN_TY_iname</span><span class="plain"> = </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">UNKNOWN_TY_HL</span><span class="plain">);</span>
<span class="identifier">Emit::named_numeric_constant</span><span class="plain">(</span><span class="identifier">UNKNOWN_TY_iname</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">UNKNOWN_NT</span><span class="plain">);</span>
<span class="identifier">Hierarchy::make_available</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">UNKNOWN_TY_iname</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="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">, </span><span class="reserved">kind_constructor</span><span class="plain">) {</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">tn</span><span class="plain"> = </span><span class="functiontext">Kinds::Constructors::name_in_template_code</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">Str::len</span><span class="plain">(</span><span class="identifier">tn</span><span class="plain">) &gt; 0) {</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;con_iname</span><span class="plain"> = </span><span class="identifier">Hierarchy::make_iname_with_specific_name</span><span class="plain">(</span><span class="identifier">WEAK_ID_HL</span><span class="plain">, </span><span class="identifier">tn</span><span class="plain">, </span><span class="functiontext">Kinds::Constructors::package</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">));</span>
<span class="identifier">Hierarchy::make_available</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;con_iname</span><span class="plain">);</span>
<span class="identifier">Emit::named_numeric_constant</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;con_iname</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;weak_kind_ID</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">hwm</span><span class="plain"> = </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">BASE_KIND_HWM_HL</span><span class="plain">);</span>
<span class="identifier">Emit::named_numeric_constant</span><span class="plain">(</span><span class="identifier">hwm</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">next_free_data_type_ID</span><span class="plain">);</span>
<span class="identifier">Hierarchy::make_available</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">hwm</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Kinds::Constructors::UNKNOWN_iname</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">UNKNOWN_TY_iname</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 unknown yet"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">UNKNOWN_TY_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="functiontext">Kinds::Constructors::package</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">con</span><span class="plain">-</span><span class="element">&gt;kc_package</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;defined_in_source_text</span><span class="plain">) {</span>
<span class="identifier">compilation_module</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain"> = </span><span class="identifier">Modules::find</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;where_defined_in_source_text</span><span class="plain">);</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;kc_package</span><span class="plain"> = </span><span class="identifier">Hierarchy::package</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">KIND_HAP</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">con</span><span class="plain">-</span><span class="element">&gt;superkind_set_at</span><span class="plain">) {</span>
<span class="identifier">compilation_module</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain"> = </span><span class="identifier">Modules::find</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;superkind_set_at</span><span class="plain">);</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;kc_package</span><span class="plain"> = </span><span class="identifier">Hierarchy::package</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">KIND_HAP</span><span class="plain">);</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">&gt;kc_package</span><span class="plain"> = </span><span class="identifier">Hierarchy::synoptic_package</span><span class="plain">(</span><span class="identifier">KIND_HAP</span><span class="plain">);</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="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="identifier">Hierarchy::markup_wording</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;kc_package</span><span class="plain">, </span><span class="identifier">KIND_NAME_HMD</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="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;name_in_template_code</span><span class="plain">) &gt; 0)</span>
<span class="identifier">Hierarchy::markup</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;kc_package</span><span class="plain">, </span><span class="identifier">KIND_NAME_HMD</span><span class="plain">, </span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;name_in_template_code</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">Hierarchy::markup</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;kc_package</span><span class="plain">, </span><span class="identifier">KIND_NAME_HMD</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"(anonymous kind)"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;kc_package</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Kinds::Constructors::iname</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">UNKNOWN_TY_iname</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 con symbols yet"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;con_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Kinds::Constructors::first_instance_iname</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">return</span><span class="plain"> </span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;first_instance_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::set_first_instance_iname</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="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain">) {</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;first_instance_iname</span><span class="plain"> = </span><span class="identifier">iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Kinds::Constructors::next_instance_iname</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">return</span><span class="plain"> </span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;next_instance_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::set_next_instance_iname</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="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain">) {</span>
<span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;next_instance_iname</span><span class="plain"> = </span><span class="identifier">iname</span><span class="plain">;</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="functiontext">Kinds::Constructors::name_in_template_code</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">return</span><span class="plain"> </span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;name_in_template_code</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Constructors::compile_I6_constants appears nowhere else.</p>
<p class="endnote">The function Kinds::Constructors::UNKNOWN_iname appears nowhere else.</p>
<p class="endnote">The function Kinds::Constructors::package is used in <a href="#SP7_1">&#167;7.1</a>, 2/uk (<a href="2-uk.html#SP32">&#167;32</a>).</p>
<p class="endnote">The function Kinds::Constructors::iname appears nowhere else.</p>
<p class="endnote">The function Kinds::Constructors::first_instance_iname appears nowhere else.</p>
<p class="endnote">The function Kinds::Constructors::set_first_instance_iname appears nowhere else.</p>
<p class="endnote">The function Kinds::Constructors::next_instance_iname appears nowhere else.</p>
<p class="endnote">The function Kinds::Constructors::set_next_instance_iname appears nowhere else.</p>
<p class="endnote">The function Kinds::Constructors::name_in_template_code appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>We also need to parse this, occasionally (if we needed this more than a
small and bounded number of times we'd want a faster method, but we don't):
</p>
<pre class="display">
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="functiontext">Kinds::Constructors::parse</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">sn</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sn</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</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="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">, </span><span class="reserved">kind_constructor</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">sn</span><span class="plain">, </span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;name_in_template_code</span><span class="plain">))</span>
<span class="reserved">return</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="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Constructors::parse is used in <a href="#SP16">&#167;16</a>, <a href="#SP17">&#167;17</a>.</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. Transformations. </b>Conversions of an existing constructor to make it a unit or enumeration also
require running macros in the kind interpreter:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::convert_to_unit</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</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">con</span><span class="plain">-</span><span class="element">&gt;is_incompletely_defined</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">) {</span>
<span class="functiontext">Kinds::Interpreter::play_back_kind_macro</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">,</span>
<span class="functiontext">Kinds::Interpreter::parse_kind_macro_name</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"#UNIT"</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="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Constructors::is_arithmetic</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="identifier">TRUE</span><span class="plain">; </span> <span class="comment">i.e., if it succeeded</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">int</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::convert_to_enumeration</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</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">con</span><span class="plain">-</span><span class="element">&gt;is_incompletely_defined</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">) {</span>
<span class="functiontext">Kinds::Interpreter::play_back_kind_macro</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">,</span>
<span class="functiontext">Kinds::Interpreter::parse_kind_macro_name</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"#ENUMERATION"</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">con</span><span class="plain">-</span><span class="element">&gt;linguistic</span><span class="plain">)</span>
<span class="functiontext">Kinds::Interpreter::play_back_kind_macro</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">,</span>
<span class="functiontext">Kinds::Interpreter::parse_kind_macro_name</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"#LINGUISTIC"</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="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Constructors::is_enumeration</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="identifier">TRUE</span><span class="plain">; </span> <span class="comment">i.e., if it succeeded</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Constructors::convert_to_unit is used in 2/uk (<a href="2-uk.html#SP7">&#167;7</a>).</p>
<p class="endnote">The function Kinds::Constructors::convert_to_enumeration is used in 2/uk (<a href="2-uk.html#SP8">&#167;8</a>).</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>And similarly:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::convert_to_real</span><span class="plain">(</span><span class="identifier">parse_node_tree</span><span class="plain"> *</span><span class="identifier">T</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="functiontext">Kinds::Interpreter::play_back_kind_macro</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">,</span>
<span class="functiontext">Kinds::Interpreter::parse_kind_macro_name</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"#REAL"</span><span class="plain">), </span><span class="identifier">con</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Constructors::convert_to_real is used in 2/uk (<a href="2-uk.html#SP9">&#167;9</a>).</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>A few base kinds are marked as "linguistic", which simply enables us to fence
them tidily off in the index.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::mark_as_linguistic</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="identifier">con</span><span class="plain">-</span><span class="element">&gt;linguistic</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Constructors::mark_as_linguistic is used in 2/knd (<a href="2-knd.html#SP33">&#167;33</a>).</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. For construction purposes. </b></p>
<pre class="display">
<span class="reserved">kind</span><span class="plain"> **</span><span class="functiontext">Kinds::Constructors::cache_location</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">con</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> &amp;(</span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;cached_kind</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::arity</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">con</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> 0;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;group</span><span class="plain"> == </span><span class="constant">PROPER_CONSTRUCTOR_GRP</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;constructor_arity</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> 0;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::tupling</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">b</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;tupling</span><span class="plain">[</span><span class="identifier">b</span><span class="plain">];</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::variance</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">b</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;variance</span><span class="plain">[</span><span class="identifier">b</span><span class="plain">];</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Constructors::cache_location is used in 2/knd (<a href="2-knd.html#SP18">&#167;18</a>).</p>
<p class="endnote">The function Kinds::Constructors::arity is used in 2/knd (<a href="2-knd.html#SP18">&#167;18</a>, <a href="2-knd.html#SP18_3">&#167;18.3</a>, <a href="2-knd.html#SP25">&#167;25</a>), 2/kc (<a href="2-kc.html#SP12">&#167;12</a>, <a href="2-kc.html#SP15_5">&#167;15.5</a>), 2/ki (<a href="2-ki.html#SP21">&#167;21</a>), 2/uk (<a href="2-uk.html#SP3">&#167;3</a>), 2/dk (<a href="2-dk.html#SP12">&#167;12</a>, <a href="2-dk.html#SP12_1">&#167;12.1</a>, <a href="2-dk.html#SP24_3">&#167;24.3</a>, <a href="2-dk.html#SP24_3_2">&#167;24.3.2</a>).</p>
<p class="endnote">The function Kinds::Constructors::tupling is used in 2/dk (<a href="2-dk.html#SP12_1">&#167;12.1</a>, <a href="2-dk.html#SP25">&#167;25</a>).</p>
<p class="endnote">The function Kinds::Constructors::variance is used in 2/kc (<a href="2-kc.html#SP15_5">&#167;15.5</a>).</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. Questions about constructors. </b>The rest of Inform is not encouraged to poke at constructors directly; it
ought to ask questions about kinds instead (see "Using Kinds"). However:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::is_definite</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">con</span><span class="plain">-</span><span class="element">&gt;group</span><span class="plain"> == </span><span class="constant">BASE_CONSTRUCTOR_GRP</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;group</span><span class="plain"> == </span><span class="constant">PROPER_CONSTRUCTOR_GRP</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">int</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::get_weak_ID</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">con</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> 0;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">con</span><span class="plain">-</span><span class="element">&gt;weak_kind_ID</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::is_arithmetic</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">con</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Kinds::Constructors::is_definite</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Kinds::Constructors::compatible</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">,</span>
<span class="functiontext">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">K_arithmetic_value</span><span class="plain">), </span><span class="identifier">FALSE</span><span class="plain">))) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::is_arithmetic_and_real</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">con</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Kinds::Constructors::is_definite</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Kinds::Constructors::compatible</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">,</span>
<span class="functiontext">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">K_real_arithmetic_value</span><span class="plain">), </span><span class="identifier">FALSE</span><span class="plain">))) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::is_enumeration</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">con</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Kinds::Constructors::is_definite</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Kinds::Constructors::compatible</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">,</span>
<span class="functiontext">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">K_enumerated_value</span><span class="plain">), </span><span class="identifier">FALSE</span><span class="plain">))) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Constructors::is_definite is used in <a href="#SP19">&#167;19</a>, 2/uk (<a href="2-uk.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function Kinds::Constructors::get_weak_ID appears nowhere else.</p>
<p class="endnote">The function Kinds::Constructors::is_arithmetic is used in <a href="#SP11">&#167;11</a>, 2/uk (<a href="2-uk.html#SP19">&#167;19</a>).</p>
<p class="endnote">The function Kinds::Constructors::is_arithmetic_and_real is used in 2/fv (<a href="2-fv.html#SP4">&#167;4</a>).</p>
<p class="endnote">The function Kinds::Constructors::is_enumeration is used in <a href="#SP11">&#167;11</a>, 2/uk (<a href="2-uk.html#SP6">&#167;6</a>).</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. Cast and instance lists. </b>Each constructor has a list of other constructors (all of the <code class="display"><span class="extract">KIND_OF_KIND_GRP</span></code>
group) which it's an instance of: value, word value, arithmetic value, and so on.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::find_cast</span><span class="plain">(</span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">, </span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">to</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">to</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="reserved">for</span><span class="plain"> (</span><span class="identifier">dtcr</span><span class="plain"> = </span><span class="identifier">to</span><span class="plain">-</span><span class="element">&gt;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="identifier">dtcr</span><span class="plain">-</span><span class="element">&gt;next_casting_rule</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">dtcr</span><span class="plain">-</span><span class="element">&gt;cast_from_kind_unparsed</span><span class="plain">) &gt; 0) {</span>
<span class="identifier">dtcr</span><span class="plain">-</span><span class="element">&gt;cast_from_kind</span><span class="plain"> =</span>
<span class="functiontext">Kinds::Constructors::parse</span><span class="plain">(</span><span class="identifier">dtcr</span><span class="plain">-</span><span class="element">&gt;cast_from_kind_unparsed</span><span class="plain">);</span>
<span class="identifier">Str::clear</span><span class="plain">(</span><span class="identifier">dtcr</span><span class="plain">-</span><span class="element">&gt;cast_from_kind_unparsed</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> == </span><span class="identifier">dtcr</span><span class="plain">-</span><span class="element">&gt;cast_from_kind</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Constructors::find_cast is used in <a href="#SP18">&#167;18</a>.</p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. </b>Each constructor has a list of other constructors (all of the <code class="display"><span class="extract">BASE_CONSTRUCTOR_GRP</span></code>
group or <code class="display"><span class="extract">PROPER_CONSTRUCTOR_GRP</span></code>) which it can cast to.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::find_instance</span><span class="plain">(</span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">, </span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">to</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="reserved">for</span><span class="plain"> (</span><span class="identifier">dti</span><span class="plain"> = </span><span class="identifier">from</span><span class="plain">-</span><span class="element">&gt;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="identifier">dti</span><span class="plain">-</span><span class="element">&gt;next_instance_rule</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">dti</span><span class="plain">-</span><span class="element">&gt;instance_of_this_unparsed</span><span class="plain">) &gt; 0) {</span>
<span class="identifier">dti</span><span class="plain">-</span><span class="element">&gt;instance_of_this</span><span class="plain"> =</span>
<span class="functiontext">Kinds::Constructors::parse</span><span class="plain">(</span><span class="identifier">dti</span><span class="plain">-</span><span class="element">&gt;instance_of_this_unparsed</span><span class="plain">);</span>
<span class="identifier">Str::clear</span><span class="plain">(</span><span class="identifier">dti</span><span class="plain">-</span><span class="element">&gt;instance_of_this_unparsed</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dti</span><span class="plain">-</span><span class="element">&gt;instance_of_this</span><span class="plain"> == </span><span class="identifier">to</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Constructors::find_instance is used in <a href="#SP18">&#167;18</a>.</p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. Compatibility. </b>The following tests if <code class="display"><span class="extract">from</span></code> is compatible with <code class="display"><span class="extract">to</span></code>.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::compatible</span><span class="plain">(</span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">, </span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">to</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">allow_casts</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">to</span><span class="plain"> == </span><span class="identifier">from</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">to</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">from</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">allow_casts</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Kinds::Constructors::find_cast</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">, </span><span class="identifier">to</span><span class="plain">))) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Constructors::find_instance</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">, </span><span class="identifier">to</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Constructors::compatible is used in <a href="#SP15">&#167;15</a>, <a href="#SP19">&#167;19</a>, 2/kc (<a href="2-kc.html#SP15_5">&#167;15.5</a>).</p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. </b>And more elaborately:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::uses_pointer_values</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">con</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Kinds::Constructors::is_definite</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Kinds::Constructors::compatible</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">, </span><span class="functiontext">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">K_pointer_value</span><span class="plain">), </span><span class="identifier">FALSE</span><span class="plain">))) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::allow_word_as_pointer</span><span class="plain">(</span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">left</span><span class="plain">, </span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">right</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Constructors::uses_pointer_values</span><span class="plain">(</span><span class="identifier">left</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Constructors::uses_pointer_values</span><span class="plain">(</span><span class="identifier">right</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="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Constructors::compatible</span><span class="plain">(</span><span class="identifier">right</span><span class="plain">, </span><span class="identifier">left</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">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Constructors::uses_pointer_values is used in 2/uk (<a href="2-uk.html#SP23">&#167;23</a>).</p>
<p class="endnote">The function Kinds::Constructors::allow_word_as_pointer appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="2-kc.html">Back to 'Kind Checking'</a></li><li><a href="2-ki.html">Continue with 'Kind Interpreter'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>