1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 08:34:22 +03:00
inform7/docs/kinds-module/2-uk.html
2020-04-07 01:06:09 +01:00

1033 lines
135 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/ki</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 tools</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/uk' 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>Using Kinds</b></li></ul><p class="purpose">To determine the characteristics of different kinds, enabling them to be used in practice.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Names of kinds</a></li><li><a href="#SP2">&#167;2. Definiteness</a></li><li><a href="#SP4">&#167;4. (A) How this came into being</a></li><li><a href="#SP12">&#167;12. (B) Constructing kinds</a></li><li><a href="#SP13">&#167;13. (C) Compatibility with other kinds</a></li><li><a href="#SP14">&#167;14. (D) How constant values of this kind are expressed</a></li><li><a href="#SP17">&#167;17. (E) Knowledge about values of this kind</a></li><li><a href="#SP18">&#167;18. (G) Performing arithmetic</a></li><li><a href="#SP21">&#167;21. (H) Representing this kind at run-time</a></li><li><a href="#SP23">&#167;23. (I) Storing values at run-time</a></li><li><a href="#SP32">&#167;32. (J) Printing and parsing values at run-time</a></li><li><a href="#SP38">&#167;38. (K) Indexing and documentation</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Names of kinds. </b></p>
<pre class="display">
<span class="identifier">wording</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::get_name</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">plural_form</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::get_name</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">, </span><span class="identifier">plural_form</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::get_name_in_play</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">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">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">EMPTY_WORDING</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::get_name_in_play</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</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="identifier">noun</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_noun</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">dt_tag</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::get_name is used in 2/dk (<a href="2-dk.html#SP24_2">&#167;24.2</a>, <a href="2-dk.html#SP24_3">&#167;24.3</a>), 2/dmn (<a href="2-dmn.html#SP28">&#167;28</a>).</p>
<p class="endnote">The function Kinds::Behaviour::get_name_in_play appears nowhere else.</p>
<p class="endnote">The function Kinds::Behaviour::get_noun appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. Definiteness. </b>A kind like "number" is definite. One way to be indefinite is to be a
kind of kind, like "arithmetic value":
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::is_kind_of_kind</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">group</span><span class="plain"> == </span><span class="constant">KIND_OF_KIND_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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::is_kind_of_kind is used in 2/dk (<a href="2-dk.html#SP15">&#167;15</a>).</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Another way is to be a kind variable, like "Q", or to be a construction
made from something indefinite, like "list of values". So the following
checks that we aren't doing that:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::definite</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Constructors::is_definite</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</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">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">arity</span><span class="plain"> = </span><span class="functiontext">Kinds::Constructors::arity</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</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="identifier">arity</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Behaviour::definite</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">kc_args</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::semidefinite</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain"> == </span><span class="identifier">CON_KIND_VARIABLE</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::is_definite</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</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">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">arity</span><span class="plain"> = </span><span class="functiontext">Kinds::Constructors::arity</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</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="identifier">arity</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Behaviour::semidefinite</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">kc_args</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::involves_var</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">v</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain"> == </span><span class="identifier">CON_KIND_VARIABLE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">v</span><span class="plain"> == </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">kind_variable_number</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">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">arity</span><span class="plain"> = </span><span class="functiontext">Kinds::Constructors::arity</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</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="identifier">arity</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Behaviour::involves_var</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">kc_args</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">], </span><span class="identifier">v</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::Behaviour::definite is used in <a href="#SP26">&#167;26</a>, 2/kc (<a href="2-kc.html#SP13">&#167;13</a>).</p>
<p class="endnote">The function Kinds::Behaviour::semidefinite appears nowhere else.</p>
<p class="endnote">The function Kinds::Behaviour::involves_var appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. (A) How this came into being. </b>Some kinds are built in (in that the I6 template files create them, using
the kind interpreter), while others arise from "X is a kind of value"
sentences in the source text.
</p>
<p class="inwebparagraph">Note that a kind of object counts as built-in by this test, even though it
might be a kind of object created in the source text, because at the end of
the day "object" is built in.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::is_built_in</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">defined_in_source_text</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_creating_sentence</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">where_defined_in_source_text</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::is_built_in appears nowhere else.</p>
<p class="endnote">The function Kinds::Behaviour::get_creating_sentence appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>When we read "Colour is a kind of value.", "colour" is uncertainly
defined at first. Later we read either "The colours are blue and pink.",
say, and then "colour" becomes an enumeration; or "450 nanometers
specifies a colour.", say, and then it becomes a unit. Initially, then,
it has an incompletely defined flag set: once one of the conversion routines
has been used, the matter is settled and there is no going back.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::is_uncertainly_defined</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">is_incompletely_defined</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::is_uncertainly_defined appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>Here we test for being an enumeration:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::is_an_enumeration</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">return</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::is_enumeration</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::is_an_enumeration is used in <a href="#SP17">&#167;17</a>, <a href="#SP29">&#167;29</a>, <a href="#SP30">&#167;30</a>, <a href="#SP32">&#167;32</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>And here we perform the conversion to a unit. The return value is <code class="display"><span class="extract">TRUE</span></code>
if the kind was already a unit or was successfully converted into one,
<code class="display"><span class="extract">FALSE</span></code> if it's now too late.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::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</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">return</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::convert_to_unit</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::convert_to_unit appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>And similarly:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::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</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">) </span><span class="functiontext">Kinds::Constructors::convert_to_enumeration</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::convert_to_enumeration is used in <a href="#SP10">&#167;10</a>.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>And similarly to switch from integer to real arithmetic.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::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</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">) </span><span class="functiontext">Kinds::Constructors::convert_to_real</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::convert_to_real appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>The instances of an enumeration have the values 1, 2, 3, ..., N at
run-time; the following returns N+1, that is, a value which can be held
by the next instance to be created.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::new_enumerated_value</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</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="functiontext">Kinds::Behaviour::convert_to_enumeration</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">next_free_value</span><span class="plain">++;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::new_enumerated_value appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>At present we aren't using named aliases for kinds, but we may in future.
</p>
<pre class="display">
<span class="reserved">kind</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::stored_as</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">stored_as</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::stored_as appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. (B) Constructing kinds. </b></p>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. (C) Compatibility with other kinds. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::set_superkind_set_at</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"set_superkind_set_at for null kind"</span><span class="plain">);</span>
<span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">superkind_set_at</span><span class="plain"> = </span><span class="identifier">S</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_superkind_set_at</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">superkind_set_at</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::set_superkind_set_at is used in 2/kc (<a href="2-kc.html#SP17">&#167;17</a>).</p>
<p class="endnote">The function Kinds::Behaviour::get_superkind_set_at is used in 2/kc (<a href="2-kc.html#SP17">&#167;17</a>).</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. (D) How constant values of this kind are expressed. </b>Some kinds have named constants, others use a quasi-numerical notation: for
instance "maroon" might be an instance of kind "colour", while "234
kilopascals" might be a notation for a kind where constants are not named.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::has_named_constant_values</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">named_values_created_with_assertions</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::Behaviour::has_named_constant_values appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. </b>The following returns the compilation method (a constant in the form <code class="display"><span class="extract">*_CCM</span></code>,
defined in "Data Types.w") used when compiling an actual constant value
specification of this kind: in other words, when compiling an I6
value for a constant of this kind.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::get_constant_compilation_method</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">NONE_CCM</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">constant_compilation_method</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::get_constant_compilation_method appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. </b>The following is used only when the kind has named instances.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::get_highest_valid_value_as_integer</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</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">K</span><span class="plain">-&gt;</span><span class="element">construct</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_activity</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NUMBER_CREATED</span><span class="plain">(</span><span class="identifier">activity</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="functiontext">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">K_equation</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NUMBER_CREATED</span><span class="plain">(</span><span class="identifier">equation</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_rule</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NUMBER_CREATED</span><span class="plain">(</span><span class="identifier">booking</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_rulebook</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NUMBER_CREATED</span><span class="plain">(</span><span class="identifier">rulebook</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="functiontext">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">K_table</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NUMBER_CREATED</span><span class="plain">(</span><span class="identifier">table</span><span class="plain">) + </span><span class="constant">1</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="functiontext">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">K_use_option</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NUMBER_CREATED</span><span class="plain">(</span><span class="identifier">use_option</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="functiontext">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">K_response</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NUMBER_CREATED</span><span class="plain">(</span><span class="identifier">response_message</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">con</span><span class="plain">-&gt;</span><span class="element">next_free_value</span><span class="plain"> - </span><span class="constant">1</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::get_highest_valid_value_as_integer appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. (E) Knowledge about values of this kind. </b>Some values can have properties attached &mdash; scenes, for instance &mdash; while
others can't &mdash; numbers or times, for instance. In general v can have
properties only if its kind passes this test:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::has_properties</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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::Behaviour::is_an_enumeration</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_object</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::Behaviour::has_properties appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. (G) Performing arithmetic. </b>Comparisons made by calling an I6 routine are slower in the VM than using the
standard <code class="display"><span class="extract">&lt;</span></code> or <code class="display"><span class="extract">&gt;</span></code> operators for signed comparison, so we use them only if
we have to.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::uses_signed_comparisons</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">comparison_routine</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"signed"</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="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_comparison_routine</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">if</span><span class="plain"> (</span><span class="functiontext">Kinds::FloatingPoint::uses_floating_point</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K_real_number</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="identifier">comparison_routine</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">comparison_routine</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"signed"</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">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">comparison_routine</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_comparison_routine_as_iname</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Produce::find_by_name</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Kinds::Behaviour::get_comparison_routine</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::uses_signed_comparisons appears nowhere else.</p>
<p class="endnote">The function Kinds::Behaviour::get_comparison_routine appears nowhere else.</p>
<p class="endnote">The function Kinds::Behaviour::get_comparison_routine_as_iname appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. </b>See "Dimensions.w" for a full account of these ideas. In theory, our
polymorphic system of arithmetic allows us to add or multiply any kinds
according to rules provided in the source text. In practice we have to keep
track of dimensions, and the following routines connect the code in the
"Dimensions" section to kind structures.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::is_quasinumerical</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">return</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::is_arithmetic</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">unit_sequence</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_dimensional_form</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Behaviour::is_quasinumerical</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain"> == </span><span class="identifier">CON_INTERMEDIATE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">intermediate_result</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> &amp;(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">dimensional_form</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::test_if_derived</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">dimensional_form_fixed</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::now_derived</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"can't derive null kind"</span><span class="plain">);</span>
<span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">dimensional_form_fixed</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::scale_factor</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">intermediate_result</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Kinds::Dimensions::us_get_scaling_factor</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">intermediate_result</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">LITERAL_PATTERNS</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">LiteralPatterns::scale_factor</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="plain">#</span><span class="reserved">else</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">1</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::is_quasinumerical is used in <a href="#SP32">&#167;32</a>, 2/dmn (<a href="2-dmn.html#SP18">&#167;18</a>, <a href="2-dmn.html#SP30_3">&#167;30.3</a>, <a href="2-dmn.html#SP31">&#167;31</a>, <a href="2-dmn.html#SP32_2">&#167;32.2</a>, <a href="2-dmn.html#SP33">&#167;33</a>).</p>
<p class="endnote">The function Kinds::Behaviour::get_dimensional_form is used in 2/dk (<a href="2-dk.html#SP24_1">&#167;24.1</a>), 2/dmn (<a href="2-dmn.html#SP30_2">&#167;30.2</a>, <a href="2-dmn.html#SP30_3">&#167;30.3</a>, <a href="2-dmn.html#SP30_4">&#167;30.4</a>, <a href="2-dmn.html#SP31">&#167;31</a>, <a href="2-dmn.html#SP32_2">&#167;32.2</a>, <a href="2-dmn.html#SP33">&#167;33</a>, <a href="2-dmn.html#SP40">&#167;40</a>, <a href="2-dmn.html#SP40_3">&#167;40.3</a>, <a href="2-dmn.html#SP41">&#167;41</a>).</p>
<p class="endnote">The function Kinds::Behaviour::test_if_derived is used in 2/dmn (<a href="2-dmn.html#SP30_1">&#167;30.1</a>, <a href="2-dmn.html#SP33">&#167;33</a>).</p>
<p class="endnote">The function Kinds::Behaviour::now_derived is used in 2/dmn (<a href="2-dmn.html#SP30_2">&#167;30.2</a>).</p>
<p class="endnote">The function Kinds::Behaviour::scale_factor is used in 2/dmn (<a href="2-dmn.html#SP35">&#167;35</a>, <a href="2-dmn.html#SP36">&#167;36</a>, <a href="2-dmn.html#SP37">&#167;37</a>, <a href="2-dmn.html#SP38">&#167;38</a>, <a href="2-dmn.html#SP39">&#167;39</a>, <a href="2-dmn.html#SP40_4">&#167;40.4</a>), 2/fv (<a href="2-fv.html#SP4">&#167;4</a>).</p>
<p class="inwebparagraph"><a id="SP20"></a><b>&#167;20. </b>The dimensional rules for K are the conventions on whether arithmetic
operations can be applied, and if so, what kind the result has.
</p>
<pre class="display">
<span class="reserved">dimensional_rules</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_dim_rules</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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"> &amp;(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">dim_rules</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::get_dim_rules is used in 2/dmn (<a href="2-dmn.html#SP16">&#167;16</a>, <a href="2-dmn.html#SP17">&#167;17</a>).</p>
<p class="inwebparagraph"><a id="SP21"></a><b>&#167;21. (H) Representing this kind at run-time. </b></p>
<pre class="display">
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_name_in_template_code</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">I</span><span class="string">"UNKNOWN_NT"</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">name_in_template_code</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::get_name_in_template_code is used in 2/knd (<a href="2-knd.html#SP33">&#167;33</a>).</p>
<p class="inwebparagraph"><a id="SP22"></a><b>&#167;22. </b>Some kinds have a support routine:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::write_support_routine_name</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no support name for null kind"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">stored_as</span><span class="plain">) </span><span class="identifier">K</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">stored_as</span><span class="plain">;</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S_Support"</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">name_in_template_code</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_support_routine_as_iname</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">);</span>
<span class="functiontext">Kinds::Behaviour::write_support_routine_name</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">, </span><span class="identifier">K</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">Produce::find_by_name</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">N</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">N</span><span class="plain">);</span>
<span class="reserved">return</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>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::write_support_routine_name appears nowhere else.</p>
<p class="endnote">The function Kinds::Behaviour::get_support_routine_as_iname appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP23"></a><b>&#167;23. (I) Storing values at run-time. </b>Recall that values are stored at run-time either as "word values" &mdash; a
single I6 word &mdash; or "pointer values" (sometimes "block values"), where
the I6 word is a pointer to a block of data on the heap. Numbers and times
are word values, texts and lists are pointer values. Which form a value
takes depends on its kind:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::uses_pointer_values</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">return</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::uses_pointer_values</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::uses_pointer_values appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP24"></a><b>&#167;24. </b>Exactly how large the small block is:
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::get_small_block_size</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">small_block_size</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::get_small_block_size appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP25"></a><b>&#167;25. </b>A reasonable estimate of how large the (larger!) heap block needs to be,
for a pointer-value kind, in bytes.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::get_heap_size_estimate</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">heap_size_estimate</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::get_heap_size_estimate appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP26"></a><b>&#167;26. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::cast_possible</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">, </span><span class="reserved">kind</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="functiontext">Kinds::weaken</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="functiontext">Kinds::weaken</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">) &amp;&amp; (</span><span class="identifier">from</span><span class="plain">) &amp;&amp; (</span><span class="identifier">to</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain"> != </span><span class="identifier">from</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Kinds::Behaviour::definite</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">)) &amp;&amp; (</span><span class="functiontext">Kinds::Behaviour::definite</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="functiontext">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">to</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain"> != </span><span class="identifier">CON_property</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::Behaviour::cast_possible is used in <a href="#SP27">&#167;27</a>.</p>
<p class="inwebparagraph"><a id="SP27"></a><b>&#167;27. </b></p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::cast_constant</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">value</span><span class="plain">, </span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">to</span><span class="plain">) {</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">REAL_LITERALS</span>
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain"> = </span><span class="identifier">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">value</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Behaviour::cast_possible</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">if</span><span class="plain"> ((</span><span class="functiontext">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">, </span><span class="identifier">K_number</span><span class="plain">)) &amp;&amp; (</span><span class="functiontext">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">, </span><span class="identifier">K_real_number</span><span class="plain">))) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">value</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">literal</span><span class="plain">-</span><span class="identifier">real</span><span class="plain">-</span><span class="identifier">number</span><span class="plain">&gt;(</span><span class="identifier">W</span><span class="plain">)) </span><span class="identifier">value</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"can't parse integer as real"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">value</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::cast_constant appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP28"></a><b>&#167;28. </b>And the following returns the name of an I6 routine to determine if two
values of K are different from each other; or <code class="display"><span class="extract">NULL</span></code> to say that it's
sufficient to apply <code class="display"><span class="extract">~=</span></code> to the values.
</p>
<pre class="display">
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_distinguisher</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">distinguisher</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_distinguisher_as_iname</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Kinds::Behaviour::get_distinguisher</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</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">Produce::find_by_name</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">N</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::get_distinguisher appears nowhere else.</p>
<p class="endnote">The function Kinds::Behaviour::get_distinguisher_as_iname appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP29"></a><b>&#167;29. </b>Some kinds are such that all legal values can efficiently be looped through
at run-time, some are not: we can sensibly loop over all scenes, but not
over all texts. We use the term "domain" to mean the set of values which
a loop traverses.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::compile_domain_possible</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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::Compare::le</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_object</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::Behaviour::is_an_enumeration</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</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">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">loop_domain_schema</span><span class="plain">) &gt; </span><span class="constant">0</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::Behaviour::compile_domain_possible appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP30"></a><b>&#167;30. </b>See "Tables.i6t"; the issue is whether the value <code class="display"><span class="extract">IMPROBABLE_VALUE</span></code> can,
despite its improbability, be valid for this kind. If we can prove that it is
not, we should return <code class="display"><span class="extract">FALSE</span></code>; if in any doubt, we must return <code class="display"><span class="extract">TRUE</span></code>.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::requires_blanks_bitmap</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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::Compare::le</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_object</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::Behaviour::is_an_enumeration</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::requires_blanks_bitmap appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP31"></a><b>&#167;31. </b>Can values of this kind be serialised out to a file and read back in again
by some other Inform story file, or by this one running on a different day?
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::can_exchange</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">can_exchange</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::can_exchange appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP32"></a><b>&#167;32. (J) Printing and parsing values at run-time. </b>Each kind can provide its own I6 routine to print out a value onto screen,
in some human-readable format.
</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="functiontext">Kinds::Behaviour::get_iname</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K_number</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::get_iname</span><span class="plain">(</span><span class="identifier">K_number</span><span class="plain">);</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"null kind has no printing routine"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_use_option</span><span class="plain">)) {</span>
<span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain"> = </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">PRINT_USE_OPTION_HL</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">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_table</span><span class="plain">)) {</span>
<span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain"> = </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">PRINT_TABLE_HL</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">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_rulebook_outcome</span><span class="plain">)) {</span>
<span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain"> = </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">PRINT_RULEBOOK_OUTCOME_HL</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">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_response</span><span class="plain">)) {</span>
<span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain"> = </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">PRINT_RESPONSE_HL</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">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_figure_name</span><span class="plain">)) {</span>
<span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain"> = </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">PRINT_FIGURE_NAME_HL</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">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_sound_name</span><span class="plain">)) {</span>
<span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain"> = </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">PRINT_SOUND_NAME_HL</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">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_external_file</span><span class="plain">)) {</span>
<span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain"> = </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">PRINT_EXTERNAL_FILE_NAME_HL</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">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_scene</span><span class="plain">)) {</span>
<span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain"> = </span><span class="identifier">Hierarchy::find</span><span class="plain">(</span><span class="identifier">PRINT_SCENE_HL</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">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">external</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::get_construct</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">) == </span><span class="identifier">CON_rule</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="functiontext">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">) == </span><span class="identifier">CON_rulebook</span><span class="plain">)) </span><span class="identifier">external</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::Behaviour::is_an_enumeration</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)) {</span>
<span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">Kinds::Behaviour::package</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">); </span><span class="identifier">external</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">dt_I6_identifier</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Behaviour::is_quasinumerical</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)) {</span>
<span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">Kinds::Behaviour::package</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">); </span><span class="identifier">external</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_time</span><span class="plain">)) </span><span class="identifier">external</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::Compare::eq</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_number</span><span class="plain">)) </span><span class="identifier">external</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::Compare::eq</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_real_number</span><span class="plain">)) </span><span class="identifier">external</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">Str::len</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"DecimalNumber"</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">R</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">external</span><span class="plain">) {</span>
<span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain"> = </span><span class="identifier">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="identifier">PRINT_FN_HL</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">);</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">actual_iname</span><span class="plain"> = </span><span class="identifier">Produce::find_by_name</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">X</span><span class="plain">);</span>
<span class="identifier">Emit::named_iname_constant</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">actual_iname</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"internal but unknown kind printing routine"</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">external</span><span class="plain">) </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain"> = </span><span class="identifier">Produce::find_by_name</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">X</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"internal but unpackaged kind printing routine"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">pr_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::package</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::package</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_inc_iname</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"null kind has no inc routine"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">inc_iname</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">inc_iname</span><span class="plain">;</span>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">Kinds::Behaviour::package</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">inc_iname</span><span class="plain"> = </span><span class="identifier">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="identifier">DECREMENT_FN_HL</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">inc_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_dec_iname</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"null kind has no dec routine"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">dec_iname</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">dec_iname</span><span class="plain">;</span>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">Kinds::Behaviour::package</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">dec_iname</span><span class="plain"> = </span><span class="identifier">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="identifier">INCREMENT_FN_HL</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">dec_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_ranger_iname</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"null kind has no inc routine"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">ranger_iname</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">ranger_iname</span><span class="plain">;</span>
<span class="identifier">package_request</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">Kinds::Behaviour::package</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">ranger_iname</span><span class="plain"> = </span><span class="identifier">Hierarchy::make_iname_in</span><span class="plain">(</span><span class="identifier">RANGER_FN_HL</span><span class="plain">, </span><span class="identifier">R</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">ranger_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_name_of_printing_rule_ACTIONS</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">K</span><span class="plain"> = </span><span class="identifier">K_number</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">trace_iname</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">trace_iname</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">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">name_of_printing_rule_ACTIONS</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">)</span>
<span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">trace_iname</span><span class="plain"> = </span><span class="identifier">Produce::find_by_name</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">name_of_printing_rule_ACTIONS</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">trace_iname</span><span class="plain"> = </span><span class="identifier">Produce::find_by_name</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">I</span><span class="string">"DA_Name"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">trace_iname</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::get_iname appears nowhere else.</p>
<p class="endnote">The function Kinds::Behaviour::package appears nowhere else.</p>
<p class="endnote">The function Kinds::Behaviour::get_inc_iname appears nowhere else.</p>
<p class="endnote">The function Kinds::Behaviour::get_dec_iname appears nowhere else.</p>
<p class="endnote">The function Kinds::Behaviour::get_ranger_iname appears nowhere else.</p>
<p class="endnote">The function Kinds::Behaviour::get_name_of_printing_rule_ACTIONS appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP33"></a><b>&#167;33. </b>Moving on to understanding: some kinds can be used as tokens in Understand
sentences, others can't. Thus "[time]" is a valid Understand token, but
"[stored action]" is not.
</p>
<p class="inwebparagraph">Some kinds provide have a GPR ("general parsing routine", an I6 piece of
jargon) defined somewhere in the template: if so, this returns its name;
if not, it returns <code class="display"><span class="extract">NULL</span></code>.
</p>
<pre class="display">
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_explicit_I6_GPR</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Kinds::Behaviour::get_explicit_I6_GPR on null kind"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"wrong way to handle object grammar"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">explicit_i6_GPR</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_explicit_I6_GPR_iname</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Kinds::Behaviour::get_explicit_I6_GPR on null kind"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"wrong way to handle object grammar"</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">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">explicit_i6_GPR</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Produce::find_by_name</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">explicit_i6_GPR</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="plain">#</span><span class="identifier">endif</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::get_explicit_I6_GPR appears nowhere else.</p>
<p class="endnote">The function Kinds::Behaviour::get_explicit_I6_GPR_iname appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP34"></a><b>&#167;34. </b>Can the kind have a GPR of any kind in the final code?
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::offers_I6_GPR</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">has_i6_GPR</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::offers_I6_GPR appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP35"></a><b>&#167;35. </b>Request that a GPR be compiled for this kind; the return value tell us whether
this will be allowed or not.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::request_I6_GPR</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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::Compare::le</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"wrong way to handle object grammar"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">has_i6_GPR</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="comment">can't oblige</span>
<span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">I6_GPR_needed</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="comment">make note to oblige later</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::request_I6_GPR appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP36"></a><b>&#167;36. </b>Do we need to compile a GPR of our own for this kind?
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::needs_I6_GPR</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">I6_GPR_needed</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::needs_I6_GPR appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP37"></a><b>&#167;37. </b>For the following, see the explanation in "Texts.i6t" in the template: a
recognition-only GPR is used for matching specific data in the course of
parsing names of objects, but not as a grammar token in its own right.
</p>
<pre class="display">
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_recognition_only_GPR</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">recognition_only_GPR</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_recognition_only_GPR_as_iname</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Kinds::Behaviour::get_recognition_only_GPR</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</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">Produce::find_by_name</span><span class="plain">(</span><span class="identifier">Emit::tree</span><span class="plain">(), </span><span class="identifier">N</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::get_recognition_only_GPR appears nowhere else.</p>
<p class="endnote">The function Kinds::Behaviour::get_recognition_only_GPR_as_iname appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP38"></a><b>&#167;38. (K) Indexing and documentation. </b></p>
<pre class="display">
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_documentation_reference</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">documentation_reference</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::set_documentation_reference</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">dr</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">documentation_reference</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">dr</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::get_documentation_reference appears nowhere else.</p>
<p class="endnote">The function Kinds::Behaviour::set_documentation_reference appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP39"></a><b>&#167;39. </b>The following is used in the Kinds index, in the table showing the default
values for each kind:
</p>
<pre class="display">
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_index_default_value</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">index_default_value</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_index_minimum_value</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">index_minimum_value</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_index_maximum_value</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">index_maximum_value</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::get_index_priority</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">index_priority</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::indexed_grey_if_empty</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">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">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">indexed_grey_if_empty</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::get_index_default_value appears nowhere else.</p>
<p class="endnote">The function Kinds::Behaviour::get_index_minimum_value is used in 2/dmn (<a href="2-dmn.html#SP32_2_1">&#167;32.2.1</a>).</p>
<p class="endnote">The function Kinds::Behaviour::get_index_maximum_value is used in 2/dmn (<a href="2-dmn.html#SP32_2_2">&#167;32.2.2</a>).</p>
<p class="endnote">The function Kinds::Behaviour::get_index_priority appears nowhere else.</p>
<p class="endnote">The function Kinds::Behaviour::indexed_grey_if_empty appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP40"></a><b>&#167;40. </b>And every kind is allowed to have the specification pseudo-property &mdash; a little
text used only on the index pages, and not existing at run-time. This is
set explicitly in the source text, but initialised for built-in kinds from
the I6 template files.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::Behaviour::set_specification_text</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">desc</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"can't set specification for null kind"</span><span class="plain">);</span>
<span class="identifier">K</span><span class="plain">-&gt;</span><span class="element">construct</span><span class="plain">-&gt;</span><span class="element">specification_text</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">desc</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">Kinds::Behaviour::get_specification_text</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"can't get specification of null kind"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-&gt;</span><span class="identifier">construct</span><span class="plain">-&gt;</span><span class="element">specification_text</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Kinds::Behaviour::set_specification_text appears nowhere else.</p>
<p class="endnote">The function Kinds::Behaviour::get_specification_text appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="2-ki.html">Back to 'Kind Interpreter'</a></li><li><a href="2-dk.html">Continue with 'Describing Kinds'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>