mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 14:04:24 +03:00
1196 lines
120 KiB
HTML
1196 lines
120 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>2/itk</title>
|
|
<meta name="viewport" content="width=device-width initial-scale=1">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
</head>
|
|
<body>
|
|
<nav role="navigation">
|
|
<h1><a href="../webs.html">Sources</a></h1>
|
|
<ul>
|
|
<li><a href="../compiler.html"><b>compiler</b></a></li>
|
|
<li><a href="../other.html">other tools</a></li>
|
|
<li><a href="../extensions.html">extensions and kits</a></li>
|
|
<li><a href="../units.html">unit test tools</a></li>
|
|
</ul>
|
|
<h2>Compiler Webs</h2>
|
|
<ul>
|
|
<li><a href="../inbuild/index.html">inbuild</a></li>
|
|
<li><a href="../inform7/index.html">inform7</a></li>
|
|
<li><a href="../inter/index.html">inter</a></li>
|
|
</ul>
|
|
<h2>Inbuild Modules</h2>
|
|
<ul>
|
|
<li><a href="../inbuild-module/index.html">inbuild</a></li>
|
|
<li><a href="../arch-module/index.html">arch</a></li>
|
|
<li><a href="../words-module/index.html">words</a></li>
|
|
<li><a href="../syntax-module/index.html">syntax</a></li>
|
|
<li><a href="../html-module/index.html">html</a></li>
|
|
</ul>
|
|
<h2>Inform7 Modules</h2>
|
|
<ul>
|
|
<li><a href="../core-module/index.html">core</a></li>
|
|
<li><a href="../problems-module/index.html">problems</a></li>
|
|
<li><a href="../inflections-module/index.html">inflections</a></li>
|
|
<li><a href="../linguistics-module/index.html">linguistics</a></li>
|
|
<li><a href="../kinds-module/index.html">kinds</a></li>
|
|
<li><a href="../if-module/index.html">if</a></li>
|
|
<li><a href="../multimedia-module/index.html">multimedia</a></li>
|
|
<li><a href="../index-module/index.html">index</a></li>
|
|
</ul>
|
|
<h2>Inter Modules</h2>
|
|
<ul>
|
|
<li><a href="../inter-module/index.html">inter</a></li>
|
|
<li><a href="../building-module/index.html">building</a></li>
|
|
<li><a href="../codegen-module/index.html">codegen</a></li>
|
|
</ul>
|
|
<h2>Foundation</h2>
|
|
<ul>
|
|
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
|
|
</ul>
|
|
|
|
|
|
</nav>
|
|
<main role="main">
|
|
|
|
<!--Weave of '2/knd' generated by 7-->
|
|
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler</a></li><li><a href="index.html">kinds</a></li><li><a href="index.html#2">Chapter 2: Kinds</a></li><li><b>Kinds</b></li></ul><p class="purpose">To build tree structures which represent Inform's universe of kinds.</p>
|
|
|
|
<ul class="toc"><li><a href="#SP1">§1. Definitions</a></li><li><a href="#SP10">§10. </a></li><li><a href="#SP18">§18. Constructing kinds</a></li><li><a href="#SP19">§19. Constructing kinds for functions</a></li><li><a href="#SP20">§20. Constructing kinds for pairs</a></li><li><a href="#SP21">§21. Iterating through kinds</a></li><li><a href="#SP23">§23. Annotations of kinds</a></li><li><a href="#SP28">§28. Traversing the tree</a></li><li><a href="#SP29">§29. Kind variable substitution</a></li><li><a href="#SP30">§30. Weakening</a></li><li><a href="#SP31">§31. Property dereferencing</a></li><li><a href="#SP33">§33. Creating new base kind constructors</a></li><li><a href="#SP34">§34. Kind names in the I6 template</a></li><li><a href="#SP35">§35. Annotating vocabulary</a></li><li><a href="#SP36">§36. Errors</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. Definitions. </b></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP2"></a><b>§2. </b>Inform has a rich universe of kinds: "number", "list of texts",
|
|
"relation of texts to lists of times", and so on. We can regard
|
|
each valid kind as the outcome of a series of constructions performed on
|
|
existing kinds. Here, for example, we get to out destination with four
|
|
constructions in a row:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">(nothing) --> text</span>
|
|
<span class="plain">(nothing) --> time</span>
|
|
<span class="plain">time --> list of times</span>
|
|
<span class="plain">text, list of times --> relation of texts to lists of times</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">At each step there is only a finite choice of possible "kind constructions"
|
|
which can be made, but since there can in principle be an unlimited number
|
|
of steps, the set of all possible kinds is infinite. At each step we make
|
|
use of 0, 1 or 2 existing kinds to make a new one: this number (0, 1 or 2)
|
|
is the "arity" of the construction. These four steps have arities 0, 0, 1, 2.
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">MAX_KIND_CONSTRUCTION_ARITY</span><span class="plain"> 2</span>
|
|
</pre>
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. </b>Inform stores the possible constructions in <code class="display"><span class="extract">kind_constructor</span></code> structures;
|
|
about 40 of these are used to provide the built-in range of kinds, and come
|
|
in a mixture of arities. (The four constructions above all use built-in
|
|
constructors.) Further constructors are added each time the source text
|
|
creates a new kind. For example,
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>A weight is a kind of value. A mammal is a kind of animal.</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">creates two new constructors:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">(nothing) --> weight</span>
|
|
<span class="plain">(nothing) --> animal</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">At present these additional constructors all have arity 0. High-level Inform 7
|
|
source is not currently able to define new constructors of higher arity;
|
|
I6 template code can do this (and that's how the built-in set is defined),
|
|
and it may be that future developments of Inform will bring this ability up
|
|
to source text level.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. </b>A given kind is represented in Inform by a pointer to a <code class="display"><span class="extract">kind</span></code> tree.
|
|
A <code class="display"><span class="extract">NULL</span></code> pointer is a valid kind, and means "unknown".
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Each node in the tree has a pointer (<code class="display"><span class="extract">->construct</span></code>) to the kind constructor
|
|
used to make it; this is never null. In the case of two special
|
|
constructors, there are further annotations (see below). The number of
|
|
downward branches at the node is equal to the arity of the constructor
|
|
being used; so the kind "number" is represented by a single leaf node:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">number</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">whereas "relation of texts to lists of times" is represented by a tree of
|
|
four nodes like so:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">relation of K to L</span>
|
|
<span class="plain"> text</span>
|
|
<span class="plain"> list of K</span>
|
|
<span class="plain"> time</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§5. </b>We will often use the word "base" to refer to arity-0 constructors
|
|
(or to the kinds which use them): thus, "text" and "time" are bases,
|
|
but "list of K" is not. We call constructors of higher arity "proper".
|
|
</p>
|
|
|
|
<p class="inwebparagraph">It would be neat if there were exactly one <code class="display"><span class="extract">kind</span></code> structure somewhere in
|
|
memory for each different kind — if that were true then we could compare
|
|
two kinds for equality simply by comparing pointers, and by definition it
|
|
would use the least possible memory. But in practice we don't do this,
|
|
because (i) it's too slow and tricky to arrange, (ii) we want to abstract
|
|
the testing process with the <code class="display"><span class="extract">Kinds::Compare::eq</span></code> function in case of later changes,
|
|
and (iii) careful use of caches where access is fast enable us to reduce
|
|
memory waste, mostly through intermediates but sometimes constructors, to
|
|
only a very small percentage in typical Inform usage — say about 2K on a
|
|
medium-sized source text like "Bronze", which is not worth economising.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§6. </b>In principle we could imagine constructors needing arbitrarily large
|
|
arity, or needing different arity in different usages, so the scheme of
|
|
having fixed arities in the range 0 to 2 looks limited. In practice we get
|
|
around that by using "punctuation nodes" in the tree. For example,
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">function K -> L</span>
|
|
<span class="plain"> CON_TUPLE_ENTRY</span>
|
|
<span class="plain"> text</span>
|
|
<span class="plain"> CON_TUPLE_ENTRY</span>
|
|
<span class="plain"> text</span>
|
|
<span class="plain"> CON_NIL</span>
|
|
<span class="plain"> number</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">represents <code class="display"><span class="extract">function (text, text) -> number</span></code>. Note two special constructors
|
|
used here: <code class="display"><span class="extract">CON_TUPLE_ENTRY</span></code> and <code class="display"><span class="extract">CON_NIL</span></code>. These are called "punctuation";
|
|
they cannot appear in isolation — see below.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§7. </b>In the Inform source code, we're clearly going to need to refer to some
|
|
of these kinds. The compiler provides support for, say, parsing times of
|
|
day, or for indexing scenes, which go beyond the generic facilities it
|
|
provides for kinds created in source text. We adopt two naming conventions:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<ul class="items"><li>(i) Kinds are written as <code class="display"><span class="extract">K_source_text_name</span></code>, that is, <code class="display"><span class="extract">K_</span></code> followed by
|
|
the name of the kind in I7 source text, with spaces made into underscores.
|
|
For instance, <code class="display"><span class="extract">K_number</span></code>. These are all <code class="display"><span class="extract">kind *</span></code> global variables
|
|
which are initially <code class="display"><span class="extract">NULL</span></code>, but which, once set, are never changed.
|
|
</li></ul>
|
|
<ul class="items"><li>(ii) Constructors are likewise written as <code class="display"><span class="extract">CON_source_text_name</span></code> if they can
|
|
be created in source text; or by <code class="display"><span class="extract">CON_TEMPLATE_NAME</span></code>, that is, <code class="display"><span class="extract">CON_</span></code>
|
|
followed by the constructor's identifier as given in the I6 template file
|
|
which created it (but with the <code class="display"><span class="extract">_TY</span></code> suffix removed) if not. For instance,
|
|
<code class="display"><span class="extract">CON_list_of</span></code> means the constructor able to make, e.g., "list of texts";
|
|
<code class="display"><span class="extract">CON_TUPLE_ENTRY</span></code> refers to the constructor created by the <code class="display"><span class="extract">TUPLE_ENTRY_TY</span></code>
|
|
block in the <code class="display"><span class="extract">Load-Core.i6t</span></code> template file. These are all <code class="display"><span class="extract">kind_constructor
|
|
</span></code>*<code class="display"><span class="extract"> global variables which are initially </span></code>NULL<code class="display"><span class="extract">, but which, once set, are
|
|
</span></code>never changed.
|
|
</li></ul>
|
|
<p class="inwebparagraph">We will now define all of the <code class="display"><span class="extract">K_...</span></code> and <code class="display"><span class="extract">CON_...</span></code> used by the core of
|
|
Inform. (Others are created and used within specific plugins.)
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. </b>We begin with some base kinds which are "kinds of kinds" useful in
|
|
generic programming.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><code class="display"><span class="extract">K_value</span></code> is a superhero, or perhaps a supervillain: it matches values of
|
|
every kind. Not being a kind in its own right, it can't be the kind of a
|
|
variable — which is just as well, since no use of such a variable could
|
|
ever be safe.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The finer distinctions <code class="display"><span class="extract">K_word_value</span></code> and <code class="display"><span class="extract">K_pointer_value</span></code> are used to
|
|
divide all run-time data into two very different storage implementations:
|
|
</p>
|
|
|
|
<ul class="items"><li>(a) those where instances are stored as word-value data, where a single I6 value
|
|
holds the whole thing, like "number";
|
|
</li><li>(b) those where instances are stored as pointers to larger blocks of data on the
|
|
heap, like "stored action".
|
|
</li></ul>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_value</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_word_value</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_pointer_value</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_sayable_value</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9"></a><b>§9. </b>The following refer to values subject to arithmetic operations (drawn with a
|
|
little calculator icon in the Kinds index), and those which are implemented as
|
|
enumerations of named constants. (This includes, e.g., scenes and figure names
|
|
but not objects, whose run-time storage is not a simple numerical enumeration,
|
|
or truth states, which are stored as 0 and 1 not 1 and 2. In particular, it
|
|
isn't the same thing as having a finite range in the Kinds index.)
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_arithmetic_value</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_real_arithmetic_value</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">those using real, not integer, arithmetic</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_enumerated_value</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10"></a><b>§10. </b>Next, the two constructors used to punctuate tuples, that is, collections
|
|
(K_1, K_2, ..., K_n) of kinds of value. <code class="display"><span class="extract">CON_NIL</span></code> represents the empty
|
|
tuple, where n=0; while <code class="display"><span class="extract">CON_TUPLE_ENTRY</span></code> behaves like a kind constructor
|
|
with arity 2, its two bases being the first item and the rest, respectively.
|
|
Thus we store (A, B, C) as
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">CON_TUPLE_ENTRY(A, CON_TUPLE_ENTRY(B, CON_TUPLE_ENTRY(C, CON_NIL)))</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">This traditional LISP-like device enables us to store tuples of arbitrary
|
|
size without need for any constructor of arity greater than 2.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<ul class="items"><li>(a) Inform has no "nil" or "void" kind visible to the writer of source
|
|
text, though it does occasionally use a kind it calls <code class="display"><span class="extract">K_nil</span></code> internally
|
|
to represent this idea — for instance for a rulebook producing nothing;
|
|
<code class="display"><span class="extract">K_nil</span></code> is the kind constructed by <code class="display"><span class="extract">CON_NIL</span></code>.
|
|
</li></ul>
|
|
<ul class="items"><li>(b) Inform does allow combinations, but they're identified by trees headed
|
|
by the constructor <code class="display"><span class="extract">CON_combination</span></code>, which then uses punctuation in its own
|
|
subtree. You might guess that an ordered pair of a text and a time would be
|
|
represented by the <code class="display"><span class="extract">CON_TUPLE_ENTRY</span></code> constructor on its own, but it isn't.
|
|
</li></ul>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_nil</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">CON_NIL</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">CON_TUPLE_ENTRY</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11"></a><b>§11. </b>It was mentioned above that two special constructors carry additional
|
|
annotations with them. The first of these is <code class="display"><span class="extract">CON_INTERMEDIATE</span></code>, used to
|
|
represent kinds which are brought into being through uncompleted arithmetic
|
|
operations: see "Dimensions.w" for a full discussion. Such a node in a
|
|
kind tree might represent "area divided by time squared", say, and it must
|
|
be annotated to show exactly which intermediate kind is meant.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">CON_INTERMEDIATE</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12"></a><b>§12. </b>While that doesn't significantly change the kinds system, the second special
|
|
constructor certainly does. This is <code class="display"><span class="extract">CON_KIND_VARIABLE</span></code>, annotated to show
|
|
which of the 26 kind variables it represents in any given situation. These
|
|
variables are, in effect, wildcards; each is marked with a "kind of kind"
|
|
as its range of possible values. (Thus a typical use of this constructor
|
|
might result in a kind node labelled as L, which can be any kind matching
|
|
"arithmetic value".)
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">CON_KIND_VARIABLE</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP13"></a><b>§13. </b>So much for the exotica: back onto familiar ground for anyone who uses
|
|
Inform. Some standard kinds:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_action_name</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_equation</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_grammatical_gender</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_inform_language</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_number</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_object</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_real_number</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_response</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_snippet</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_stored_action</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_table</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_text</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_truth_state</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_unicode_character</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_use_option</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_verb</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14"></a><b>§14. </b>And here are two more standard kinds, but which most Inform uses don't
|
|
realise are there, because they are omitted from the Kinds index:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<ul class="items"><li>(a) <code class="display"><span class="extract">K_rulebook_outcome</span></code>. Rulebooks end in success, failure, no outcome, or
|
|
possibly one of a range of named alternative outcomes. These all share a
|
|
single namespace, and the names in question share a single kind of value.
|
|
It's not a very elegant system, and we really don't want people storing
|
|
these in variables; we want them to be used only as part of the process of
|
|
receiving the outcome back. So although there's no technical reason why this
|
|
kind shouldn't be used for storage, it's hidden from the user.
|
|
</li></ul>
|
|
<ul class="items"><li>(b) <code class="display"><span class="extract">K_understanding</span></code> is used to hold the result of a grammar token. An actual
|
|
constant value specification of this kind stores a <code class="display"><span class="extract">grammar_verb *</span></code> pointer.
|
|
It's an untidy internal device which may well be removed later.
|
|
</li></ul>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_rulebook_outcome</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K_understanding</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15"></a><b>§15. </b>Finally, the constructors used by Inform authors:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">CON_list_of</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">CON_description</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">CON_relation</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">CON_rule</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">CON_rulebook</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">CON_activity</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">CON_phrase</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">CON_property</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">CON_table_column</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">CON_combination</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">CON_variable</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP16"></a><b>§16. </b>Finally, then, it's time to define what a kind node looks like:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind</span><span class="plain"> {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">construct</span><span class="plain">; </span> <span class="comment">which can never be <code class="display"><span class="extract">NULL</span></code></span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">kind_variable_number</span><span class="plain">; </span> <span class="comment">only used if construct is <code class="display"><span class="extract">CON_KIND_VARIABLE</span></code></span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">unit_sequence</span><span class="plain"> *</span><span class="identifier">intermediate_result</span><span class="plain">; </span> <span class="comment">only used if construct is <code class="display"><span class="extract">CON_INTERMEDIATE</span></code></span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">kc_args</span><span class="plain">[</span><span class="constant">MAX_KIND_CONSTRUCTION_ARITY</span><span class="plain">]; </span> <span class="comment">used if arity positive, or for <code class="display"><span class="extract">CON_KIND_VARIABLE</span></code></span>
|
|
<span class="plain">} </span><span class="reserved">kind</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure kind is accessed in 2/kc, 2/uk, 2/fv and here.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP17"></a><b>§17. </b>We keep some statistics for tracking memory usage:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_base_kinds_created</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_intermediate_kinds_created</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_constructed_kinds_created</span><span class="plain"> = 0;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP18"></a><b>§18. Constructing kinds. </b>All kind structures are obtained by one of the following. First, a base
|
|
construction, one with arity 0. This makes a kind tree with a single leaf
|
|
node, of course, and that's something we need very often. So we create it
|
|
only on the first request, and cache the pointer to it with the constructor;
|
|
we can then use that same pointer on all subsequent requests.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="functiontext">Kinds::base_construction</span><span class="plain">(</span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">con</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">con</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"impossible construction"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">con</span><span class="plain"> == </span><span class="identifier">CON_KIND_VARIABLE</span><span class="plain">) || (</span><span class="identifier">con</span><span class="plain"> == </span><span class="identifier">CON_INTERMEDIATE</span><span class="plain">))</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"forbidden construction"</span><span class="plain">);</span>
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="functiontext">Kinds::Constructors::arity</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">)) {</span>
|
|
<span class="reserved">case</span><span class="plain"> 1:</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">con</span><span class="plain"> == </span><span class="identifier">CON_list_of</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Kinds::unary_construction</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Kinds::unary_construction</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">);</span>
|
|
<span class="reserved">case</span><span class="plain"> 2: </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Kinds::binary_construction</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">K_value</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">kind</span><span class="plain"> **</span><span class="identifier">cache</span><span class="plain"> = </span><span class="functiontext">Kinds::Constructors::cache_location</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cache</span><span class="plain">) { </span><span class="reserved">if</span><span class="plain"> (*</span><span class="identifier">cache</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> *</span><span class="identifier">cache</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="cwebmacro">Create a raw kind structure</span> <span class="cwebmacronumber">18.4</span>><span class="plain">;</span>
|
|
<span class="identifier">K</span><span class="plain">-</span><span class="element">>construct</span><span class="plain"> = </span><span class="identifier">con</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cache</span><span class="plain">) *</span><span class="identifier">cache</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">;</span>
|
|
<span class="identifier">no_base_kinds_created</span><span class="plain">++;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::base_construction is used in <a href="#SP22">§22</a>, <a href="#SP33">§33</a>, 2/kc2 (<a href="2-kc2.html#SP3">§3</a>, <a href="2-kc2.html#SP7">§7</a>, <a href="2-kc2.html#SP7_1">§7.1</a>), 2/ki (<a href="2-ki.html#SP14_1">§14.1</a>, <a href="2-ki.html#SP28_4">§28.4</a>), 2/dk (<a href="2-dk.html#SP10">§10</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP18_1"></a><b>§18.1. </b>As noted above, <code class="display"><span class="extract">CON_INTERMEDIATE</span></code> is used to store intermediate results
|
|
of calculations that are never accessible to outside source text, and have
|
|
kinds which couldn't be represented there. For example, if we evaluate
|
|
E = mc^2
|
|
then we may have perfectly good kinds of value to store energy, mass and
|
|
velocity, but have no kind of value for c^2, a velocity squared. Such
|
|
evanescent kinds are given the special constructor <code class="display"><span class="extract">CON_INTERMEDIATE</span></code>.
|
|
These are needed relatively seldom and are not cached.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="functiontext">Kinds::intermediate_construction</span><span class="plain">(</span><span class="reserved">unit_sequence</span><span class="plain"> *</span><span class="identifier">ik</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ik</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">"made unknown as Kinds::intermediate_construction"</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="cwebmacro">Create a raw kind structure</span> <span class="cwebmacronumber">18.4</span>><span class="plain">;</span>
|
|
<span class="identifier">K</span><span class="plain">-</span><span class="element">>construct</span><span class="plain"> = </span><span class="identifier">CON_INTERMEDIATE</span><span class="plain">;</span>
|
|
<span class="identifier">K</span><span class="plain">-</span><span class="element">>intermediate_result</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">unit_sequence</span><span class="plain">);</span>
|
|
<span class="plain">*(</span><span class="identifier">K</span><span class="plain">-</span><span class="element">>intermediate_result</span><span class="plain">) = *</span><span class="identifier">ik</span><span class="plain">;</span>
|
|
<span class="identifier">no_intermediate_kinds_created</span><span class="plain">++;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::intermediate_construction is used in 2/dmn (<a href="2-dmn.html#SP40_4">§40.4</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP18_2"></a><b>§18.2. </b>Kind variables A to Z (where <code class="display"><span class="extract">N</span></code> is 1 to 26 below) can usually stand for
|
|
any kind, but can also be marked with a "declaration", usually
|
|
constraining what kind of value they are allowed to hold. For example, K
|
|
might be marked as being an arithmetical kind of value. See "Kind
|
|
Checking.w".
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="functiontext">Kinds::variable_construction</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain">, </span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">declaration</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">N</span><span class="plain"> == 0) || (</span><span class="identifier">N</span><span class="plain"> > </span><span class="constant">MAX_KIND_VARIABLES</span><span class="plain">)) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"bad kind variable"</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="cwebmacro">Create a raw kind structure</span> <span class="cwebmacronumber">18.4</span>><span class="plain">;</span>
|
|
<span class="identifier">K</span><span class="plain">-</span><span class="element">>construct</span><span class="plain"> = </span><span class="identifier">CON_KIND_VARIABLE</span><span class="plain">;</span>
|
|
<span class="identifier">K</span><span class="plain">-</span><span class="element">>kind_variable_number</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="element">>kc_args</span><span class="plain">[0] = </span><span class="identifier">declaration</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::variable_construction is used in 2/dk (<a href="2-dk.html#SP6">§6</a>, <a href="2-dk.html#SP9">§9</a>, <a href="2-dk.html#SP18">§18</a>, <a href="2-dk.html#SP19">§19</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP18_3"></a><b>§18.3. </b>That completes the possible base constructions. Proper constructions are made
|
|
using the following. For example,
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">Kinds::unary_construction(CON_list_of, K_number)</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">produces a kind structure meaning "list of numbers". This is not cached
|
|
anywhere, so a second request for the same thing will produce a different copy
|
|
in memory of the same structure. Profiling shows that little memory is in
|
|
practice wasted.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="functiontext">Kinds::unary_construction</span><span class="plain">(</span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">con</span><span class="plain">, </span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">X</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="functiontext">Kinds::Constructors::arity</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">) != 1) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"bad unary construction"</span><span class="plain">);</span>
|
|
<<span class="cwebmacro">Create a raw kind structure</span> <span class="cwebmacronumber">18.4</span>><span class="plain">;</span>
|
|
<span class="identifier">K</span><span class="plain">-</span><span class="element">>construct</span><span class="plain"> = </span><span class="identifier">con</span><span class="plain">; </span><span class="identifier">K</span><span class="plain">-</span><span class="element">>kc_args</span><span class="plain">[0] = </span><span class="identifier">X</span><span class="plain">;</span>
|
|
<span class="identifier">no_constructed_kinds_created</span><span class="plain">++;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="functiontext">Kinds::binary_construction</span><span class="plain">(</span><span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">con</span><span class="plain">, </span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">X</span><span class="plain">, </span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">Y</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="functiontext">Kinds::Constructors::arity</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">) != 2) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"bad binary construction"</span><span class="plain">);</span>
|
|
<<span class="cwebmacro">Create a raw kind structure</span> <span class="cwebmacronumber">18.4</span>><span class="plain">;</span>
|
|
<span class="identifier">K</span><span class="plain">-</span><span class="element">>construct</span><span class="plain"> = </span><span class="identifier">con</span><span class="plain">; </span><span class="identifier">K</span><span class="plain">-</span><span class="element">>kc_args</span><span class="plain">[0] = </span><span class="identifier">X</span><span class="plain">; </span><span class="identifier">K</span><span class="plain">-</span><span class="element">>kc_args</span><span class="plain">[1] = </span><span class="identifier">Y</span><span class="plain">;</span>
|
|
<span class="identifier">no_constructed_kinds_created</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_phrase</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">X</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">Y</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"bad function kind"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">X</span><span class="plain">-</span><span class="element">>construct</span><span class="plain"> == </span><span class="identifier">CON_TUPLE_ENTRY</span><span class="plain">) && (</span><span class="identifier">X</span><span class="plain">-</span><span class="element">>kc_args</span><span class="plain">[0] == </span><span class="identifier">K_nil</span><span class="plain">))</span>
|
|
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"nil nil"</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Y</span><span class="plain">-</span><span class="element">>construct</span><span class="plain"> == </span><span class="identifier">CON_TUPLE_ENTRY</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"bizarre"</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">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::unary_construction is used in <a href="#SP18">§18</a>, <a href="#SP29">§29</a>, <a href="#SP30">§30</a>, <a href="#SP31">§31</a>, 2/kc (<a href="2-kc.html#SP12">§12</a>, <a href="2-kc.html#SP18_6">§18.6</a>), 2/dk (<a href="2-dk.html#SP11">§11</a>, <a href="2-dk.html#SP12_1">§12.1</a>).</p>
|
|
|
|
<p class="endnote">The function Kinds::binary_construction is used in <a href="#SP18">§18</a>, <a href="#SP19">§19</a>, <a href="#SP20">§20</a>, <a href="#SP29">§29</a>, <a href="#SP30">§30</a>, <a href="#SP31">§31</a>, 2/kc (<a href="2-kc.html#SP12">§12</a>, <a href="2-kc.html#SP18_6">§18.6</a>), 2/dk (<a href="2-dk.html#SP11">§11</a>, <a href="2-dk.html#SP12_1">§12.1</a>, <a href="2-dk.html#SP13">§13</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP18_4"></a><b>§18.4. </b>We've now seen the only ways to create a kind structure, and they share the
|
|
following initialisation:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Create a raw kind structure</span> <span class="cwebmacronumber">18.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">K</span><span class="plain"> = </span><span class="identifier">CREATE</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="element">>construct</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="element">>intermediate_result</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="element">>kind_variable_number</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"><</span><span class="constant">MAX_KIND_CONSTRUCTION_ARITY</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">K</span><span class="plain">-</span><span class="element">>kc_args</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP18">§18</a>, <a href="#SP18_1">§18.1</a>, <a href="#SP18_2">§18.2</a>, <a href="#SP18_3">§18.3</a> (twice).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP19"></a><b>§19. Constructing kinds for functions. </b>The following uses the above methods to put together the kind of a function,
|
|
making use of the punctuation nodes <code class="display"><span class="extract">CON_TUPLE_ENTRY</span></code> and <code class="display"><span class="extract">CON_NIL</span></code>. Note
|
|
that we use <code class="display"><span class="extract">K_nil</span></code> to represent the absence of a return kind (the "nothing"
|
|
in a function to nothing). Note also that a function from X to Y, with just
|
|
one argument, comes out as:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">CON_phrase</span>
|
|
<span class="plain"> CON_TUPLE_ENTRY</span>
|
|
<span class="plain"> X</span>
|
|
<span class="plain"> CON_NIL</span>
|
|
<span class="plain"> Y</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">rather than as:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">CON_phrase</span>
|
|
<span class="plain"> X</span>
|
|
<span class="plain"> Y</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">(It's more convenient to have a predictable form than to save on kind nodes.)
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="functiontext">Kinds::function_kind</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_args</span><span class="plain">, </span><span class="reserved">kind</span><span class="plain"> **</span><span class="identifier">args</span><span class="plain">, </span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">return_K</span><span class="plain">) {</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">arguments_K</span><span class="plain"> = </span><span class="identifier">K_nil</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=</span><span class="identifier">no_args</span><span class="plain">-1; </span><span class="identifier">i</span><span class="plain">>=0; </span><span class="identifier">i</span><span class="plain">--)</span>
|
|
<span class="identifier">arguments_K</span><span class="plain"> = </span><span class="functiontext">Kinds::binary_construction</span><span class="plain">(</span><span class="identifier">CON_TUPLE_ENTRY</span><span class="plain">, </span><span class="identifier">args</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">], </span><span class="identifier">arguments_K</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">return_K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">return_K</span><span class="plain"> = </span><span class="identifier">K_nil</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Kinds::binary_construction</span><span class="plain">(</span><span class="identifier">CON_phrase</span><span class="plain">, </span><span class="identifier">arguments_K</span><span class="plain">, </span><span class="identifier">return_K</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::function_kind appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20"></a><b>§20. Constructing kinds for pairs. </b>Similarly, but more simply, here is the kind for an ordered pair of values:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="functiontext">Kinds::pair_kind</span><span class="plain">(</span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">X</span><span class="plain">, </span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">Y</span><span class="plain">) {</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Kinds::binary_construction</span><span class="plain">(</span><span class="identifier">CON_combination</span><span class="plain">, </span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">Y</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::pair_kind appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP21"></a><b>§21. Iterating through kinds. </b>It's clearly not literally possible to iterate through kinds (there are
|
|
infinitely many) or even through base kinds (since intermediate and variable
|
|
constructions confuse the picture), but it does turn out to be convenient
|
|
to iterate through all possible constructions, wrapped up into base kind
|
|
format. Thus:
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="identifier">LOOP_OVER_BASE_KINDS</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">=</span><span class="functiontext">Kinds::first_base_k</span><span class="plain">(); </span><span class="identifier">K</span><span class="plain">; </span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Kinds::next_base_k</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">))</span>
|
|
</pre>
|
|
<p class="inwebparagraph"><a id="SP22"></a><b>§22. </b>This requires the following iterator routines. Note that these will
|
|
produce base constructions using constructors of higher arity than that
|
|
(for example, it will make "list of K" as a base kind, with no arguments);
|
|
this would be unsuitable as the kind of any data, but is convenient for
|
|
drawing up the index, and so on.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="functiontext">Kinds::first_base_k</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="identifier">con</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">, </span><span class="reserved">kind_constructor</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">con</span><span class="plain"> != </span><span class="identifier">CON_KIND_VARIABLE</span><span class="plain">) && (</span><span class="identifier">con</span><span class="plain"> != </span><span class="identifier">CON_INTERMEDIATE</span><span class="plain">))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Kinds::base_construction</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="functiontext">Kinds::next_base_k</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">kind_constructor</span><span class="plain"> *</span><span class="identifier">con</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">-</span><span class="element">>construct</span><span class="plain">;</span>
|
|
<span class="reserved">do</span><span class="plain"> {</span>
|
|
<span class="identifier">con</span><span class="plain"> = </span><span class="identifier">NEXT_OBJECT</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">, </span><span class="reserved">kind_constructor</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">con</span><span class="plain"> == </span><span class="identifier">CON_KIND_VARIABLE</span><span class="plain">) || (</span><span class="identifier">con</span><span class="plain"> == </span><span class="identifier">CON_INTERMEDIATE</span><span class="plain">));</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">con</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Kinds::base_construction</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::first_base_k is used in <a href="#SP21">§21</a>.</p>
|
|
|
|
<p class="endnote">The function Kinds::next_base_k is used in <a href="#SP21">§21</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP23"></a><b>§23. Annotations of kinds. </b>Most of the time, the only annotation of a kind node is the constructor used:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind_constructor</span><span class="plain"> *</span><span class="functiontext">Kinds::get_construct</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="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">-</span><span class="element">>construct</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::get_construct is used in <a href="#SP33">§33</a>, 2/kc (<a href="2-kc.html#SP15_1">§15.1</a>), 2/kc2 (<a href="2-kc2.html#SP7">§7</a>, <a href="2-kc2.html#SP15">§15</a>, <a href="2-kc2.html#SP19">§19</a>), 2/ki (<a href="2-ki.html#SP14_1">§14.1</a>), 2/uk (<a href="2-uk.html#SP16">§16</a>, <a href="2-uk.html#SP32">§32</a>), 2/dk (<a href="2-dk.html#SP24">§24</a>, <a href="2-dk.html#SP24_1">§24.1</a>, <a href="2-dk.html#SP24_1_1">§24.1.1</a>, <a href="2-dk.html#SP25">§25</a>), 2/dmn (<a href="2-dmn.html#SP14">§14</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP24"></a><b>§24. </b>But for the benefit of intermediate and variable kind nodes, we also need:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::is_intermediate</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">K</span><span class="plain">-</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">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::get_variable_number</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">K</span><span class="plain">-</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">K</span><span class="plain">-</span><span class="element">>kind_variable_number</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> -1;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="functiontext">Kinds::get_variable_stipulation</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">K</span><span class="plain">-</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">K</span><span class="plain">-</span><span class="element">>kc_args</span><span class="plain">[0];</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::is_intermediate is used in 2/dmn (<a href="2-dmn.html#SP32_2">§32.2</a>, <a href="2-dmn.html#SP33">§33</a>).</p>
|
|
|
|
<p class="endnote">The function Kinds::get_variable_number is used in <a href="#SP29">§29</a>, 2/kc (<a href="2-kc.html#SP10">§10</a>, <a href="2-kc.html#SP15">§15</a>, <a href="2-kc.html#SP15_6">§15.6</a>), 2/dk (<a href="2-dk.html#SP24_1_2">§24.1.2</a>).</p>
|
|
|
|
<p class="endnote">The function Kinds::get_variable_stipulation is used in 2/kc (<a href="2-kc.html#SP15_6">§15.6</a>, <a href="2-kc.html#SP15_6_1">§15.6.1</a>), 2/dk (<a href="2-dk.html#SP24_1_2">§24.1.2</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP25"></a><b>§25. </b>Two convenient wrappers for talking about the constructor used:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::is_proper_constructor</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="functiontext">Kinds::arity_of_constructor</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">) > 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::arity_of_constructor</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="reserved">return</span><span class="plain"> </span><span class="functiontext">Kinds::Constructors::arity</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-</span><span class="element">>construct</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> 0;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::is_proper_constructor is used in <a href="#SP29">§29</a>, <a href="#SP30">§30</a>, <a href="#SP31">§31</a>, 2/dk (<a href="2-dk.html#SP24">§24</a>), 2/dmn (<a href="2-dmn.html#SP18">§18</a>).</p>
|
|
|
|
<p class="endnote">The function Kinds::arity_of_constructor is used in <a href="#SP26">§26</a>, <a href="#SP27">§27</a>, <a href="#SP29">§29</a>, <a href="#SP30">§30</a>, <a href="#SP31">§31</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP26"></a><b>§26. </b>Given, say, "list of numbers", the following returns "number":
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="functiontext">Kinds::unary_construction_material</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="functiontext">Kinds::arity_of_constructor</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">) != 1) </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">-</span><span class="element">>kc_args</span><span class="plain">[0];</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::unary_construction_material is used in <a href="#SP29">§29</a>, <a href="#SP30">§30</a>, <a href="#SP31">§31</a>, 2/kc (<a href="2-kc.html#SP15_1">§15.1</a>), 2/dk (<a href="2-dk.html#SP24_3">§24.3</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP27"></a><b>§27. </b>More awkwardly:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::binary_construction_material</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">kind</span><span class="plain"> **</span><span class="identifier">X</span><span class="plain">, </span><span class="reserved">kind</span><span class="plain"> **</span><span class="identifier">Y</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::arity_of_constructor</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">) != 2) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">X</span><span class="plain">) *</span><span class="identifier">X</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">Y</span><span class="plain">) *</span><span class="identifier">Y</span><span class="plain"> = </span><span class="identifier">NULL</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">X</span><span class="plain">) *</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">-</span><span class="element">>kc_args</span><span class="plain">[0];</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Y</span><span class="plain">) *</span><span class="identifier">Y</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">-</span><span class="element">>kc_args</span><span class="plain">[1];</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::binary_construction_material is used in <a href="#SP29">§29</a>, <a href="#SP30">§30</a>, <a href="#SP31">§31</a>, 2/dk (<a href="2-dk.html#SP24_1_1">§24.1.1</a>, <a href="2-dk.html#SP24_3">§24.3</a>, <a href="2-dk.html#SP25">§25</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP28"></a><b>§28. Traversing the tree. </b>Here we look through a kind tree in search of a given constructor at any node.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::contains</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">kind_constructor</span><span class="plain"> *</span><span class="identifier">con</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">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">-</span><span class="element">>construct</span><span class="plain"> == </span><span class="identifier">con</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"><</span><span class="constant">MAX_KIND_CONSTRUCTION_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::contains</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-</span><span class="element">>kc_args</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">], </span><span class="identifier">con</span><span class="plain">))</span>
|
|
<span class="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::contains appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP29"></a><b>§29. Kind variable substitution. </b>Once we have determined what the kind variables stand for, we sometimes want
|
|
to perform substitution to convert (say) "relation of K to list of K" to
|
|
</p>
|
|
|
|
<ul class="items"><li>(say) "relation of numbers to list of numbers".
|
|
</li></ul>
|
|
<p class="inwebparagraph">However, in order to ensure that caches are never invalidated, we are careful
|
|
never to alter a <code class="display"><span class="extract">kind</span></code> structure once it has been created; instead,
|
|
we return a different structure imitating the shape of the original.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">We set the flag indicated by <code class="display"><span class="extract">changed</span></code> to <code class="display"><span class="extract">TRUE</span></code> if we make any change,
|
|
assuming that it was originally <code class="display"><span class="extract">FALSE</span></code> before the first use of this function.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="functiontext">Kinds::substitute</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">kind</span><span class="plain"> **</span><span class="identifier">meanings</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> *</span><span class="identifier">changed</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">meanings</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">meanings</span><span class="plain"> = </span><span class="identifier">values_of_kind_variables</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Kinds::get_variable_number</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"> > 0) {</span>
|
|
<span class="plain">*</span><span class="identifier">changed</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">meanings</span><span class="plain">[</span><span class="identifier">N</span><span class="plain">];</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::is_proper_constructor</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)) {</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">X_after</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">Y</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">Y_after</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">tx</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">ty</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">a</span><span class="plain"> = </span><span class="functiontext">Kinds::arity_of_constructor</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">a</span><span class="plain"> == 1) {</span>
|
|
<span class="identifier">X</span><span class="plain"> = </span><span class="functiontext">Kinds::unary_construction_material</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
|
|
<span class="identifier">X_after</span><span class="plain"> = </span><span class="functiontext">Kinds::substitute</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">meanings</span><span class="plain">, &</span><span class="identifier">tx</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tx</span><span class="plain">) {</span>
|
|
<span class="plain">*</span><span class="identifier">changed</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="functiontext">Kinds::unary_construction</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-</span><span class="element">>construct</span><span class="plain">, </span><span class="identifier">X_after</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="functiontext">Kinds::binary_construction_material</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, &</span><span class="identifier">X</span><span class="plain">, &</span><span class="identifier">Y</span><span class="plain">);</span>
|
|
<span class="identifier">X_after</span><span class="plain"> = </span><span class="functiontext">Kinds::substitute</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">meanings</span><span class="plain">, &</span><span class="identifier">tx</span><span class="plain">);</span>
|
|
<span class="identifier">Y_after</span><span class="plain"> = </span><span class="functiontext">Kinds::substitute</span><span class="plain">(</span><span class="identifier">Y</span><span class="plain">, </span><span class="identifier">meanings</span><span class="plain">, &</span><span class="identifier">ty</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">tx</span><span class="plain">) || (</span><span class="identifier">ty</span><span class="plain">)) {</span>
|
|
<span class="plain">*</span><span class="identifier">changed</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="functiontext">Kinds::binary_construction</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-</span><span class="element">>construct</span><span class="plain">, </span><span class="identifier">X_after</span><span class="plain">, </span><span class="identifier">Y_after</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::substitute appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP30"></a><b>§30. Weakening. </b>This operation corresponds to rounding kinds up to "object": that is, any
|
|
subkind of "object" is replaced by "object".
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="functiontext">Kinds::weaken</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="functiontext">Kinds::is_proper_constructor</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)) {</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">Y</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">a</span><span class="plain"> = </span><span class="functiontext">Kinds::arity_of_constructor</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">a</span><span class="plain"> == 1) {</span>
|
|
<span class="identifier">X</span><span class="plain"> = </span><span class="functiontext">Kinds::unary_construction_material</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::unary_construction</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-</span><span class="element">>construct</span><span class="plain">, </span><span class="functiontext">Kinds::weaken</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">));</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="functiontext">Kinds::binary_construction_material</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, &</span><span class="identifier">X</span><span class="plain">, &</span><span class="identifier">Y</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Kinds::binary_construction</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-</span><span class="element">>construct</span><span class="plain">, </span><span class="functiontext">Kinds::weaken</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">), </span><span class="functiontext">Kinds::weaken</span><span class="plain">(</span><span class="identifier">Y</span><span class="plain">));</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">K</span><span class="plain">) && (</span><span class="functiontext">Kinds::Compare::lt</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">K_object</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">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::weaken is used in 2/uk (<a href="2-uk.html#SP26">§26</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP31"></a><b>§31. Property dereferencing. </b>Properties are sometimes nouns referring to themselves, and sometimes nouns
|
|
referring to their values, and these have different kinds. So:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="functiontext">Kinds::dereference_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">K</span><span class="plain">-</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="functiontext">Kinds::unary_construction_material</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="functiontext">Kinds::is_proper_constructor</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)) {</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">Y</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">a</span><span class="plain"> = </span><span class="functiontext">Kinds::arity_of_constructor</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">a</span><span class="plain"> == 1) {</span>
|
|
<span class="identifier">X</span><span class="plain"> = </span><span class="functiontext">Kinds::unary_construction_material</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::unary_construction</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-</span><span class="element">>construct</span><span class="plain">,</span>
|
|
<span class="functiontext">Kinds::dereference_properties</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">));</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="functiontext">Kinds::binary_construction_material</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, &</span><span class="identifier">X</span><span class="plain">, &</span><span class="identifier">Y</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Kinds::binary_construction</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-</span><span class="element">>construct</span><span class="plain">,</span>
|
|
<span class="functiontext">Kinds::dereference_properties</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">), </span><span class="functiontext">Kinds::dereference_properties</span><span class="plain">(</span><span class="identifier">Y</span><span class="plain">));</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::dereference_properties appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP32"></a><b>§32. </b>Inform builds "natural language" in so that it can create an instance for
|
|
each natural language whose bundle it can find. "Grammatical gender" is used
|
|
as a kind whose name coincides with a property.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"><</span><span class="identifier">notable</span><span class="plain">-</span><span class="identifier">linguistic</span><span class="plain">-</span><span class="identifier">kinds</span><span class="plain">> ::=</span>
|
|
<span class="identifier">natural</span><span class="plain"> </span><span class="identifier">language</span><span class="plain"> |</span>
|
|
<span class="identifier">grammatical</span><span class="plain"> </span><span class="identifier">gender</span><span class="plain"> |</span>
|
|
<span class="identifier">grammatical</span><span class="plain"> </span><span class="identifier">tense</span><span class="plain"> |</span>
|
|
<span class="identifier">narrative</span><span class="plain"> </span><span class="identifier">viewpoint</span><span class="plain"> |</span>
|
|
<span class="identifier">grammatical</span><span class="plain"> </span><span class="reserved">case</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP33"></a><b>§33. Creating new base kind constructors. </b>Inform's whole stock of constructors comes from two routes: this one, from the
|
|
source text, and another we shall see later, from the Kind Interpreter. The
|
|
following is called in response to sentences like:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Texture is a kind of value. A musical instrument is a kind of thing.</p>
|
|
|
|
</blockquote>
|
|
|
|
<p class="inwebparagraph">The word range is the name ("texture", "musical instrument"), and <code class="display"><span class="extract">super</span></code>
|
|
is the super-kind ("value", "thing").
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_kinds_of_object</span><span class="plain"> = 1;</span>
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="functiontext">Kinds::new_base</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="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">super</span><span class="plain">) {</span>
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">PROTECTED_MODEL_PROCEDURE</span>
|
|
<span class="identifier">PROTECTED_MODEL_PROCEDURE</span><span class="plain">;</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span>
|
|
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Kinds::base_construction</span><span class="plain">(</span>
|
|
<span class="functiontext">Kinds::Constructors::new</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="functiontext">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">super</span><span class="plain">), </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"#NEW"</span><span class="plain">));</span>
|
|
<<span class="cwebmacro">Renew the subject if necessary to cope with an early subject creation</span> <span class="cwebmacronumber">33.1</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="functiontext">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">super</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">))</span>
|
|
<span class="identifier">InferenceSubjects::falls_within</span><span class="plain">(</span><span class="identifier">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">), </span><span class="identifier">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">super</span><span class="plain">));</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span>
|
|
|
|
<<span class="cwebmacro">Use the source-text name to attach a noun to the constructor</span> <span class="cwebmacronumber">33.2</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (<</span><span class="identifier">notable</span><span class="plain">-</span><span class="identifier">linguistic</span><span class="plain">-</span><span class="identifier">kinds</span><span class="plain">>(</span><span class="identifier">W</span><span class="plain">)) {</span>
|
|
<span class="functiontext">Kinds::Constructors::mark_as_linguistic</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-</span><span class="element">>construct</span><span class="plain">);</span>
|
|
<span class="reserved">switch</span><span class="plain"> (<<</span><span class="identifier">r</span><span class="plain">>>) {</span>
|
|
<span class="reserved">case</span><span class="plain"> 0: </span><span class="identifier">K_inform_language</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">;</span>
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">NATURAL_LANGUAGES_PRESENT</span>
|
|
<span class="identifier">NaturalLanguages::stock_nl_kind</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> 1: </span><span class="identifier">K_grammatical_gender</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="plain">#</span><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">property</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">>(</span><span class="identifier">W</span><span class="plain">)) {</span>
|
|
<span class="identifier">property</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = <<</span><span class="identifier">rp</span><span class="plain">>>;</span>
|
|
<span class="identifier">Properties::Valued::set_kind</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
|
|
<span class="identifier">Instances::make_kind_coincident</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_grammatical_gender</span><span class="plain">)) </span><span class="identifier">P_grammatical_gender</span><span class="plain"> = </span><span class="identifier">P</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span>
|
|
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">NEW_BASE_KIND_NOTIFY</span>
|
|
<span class="identifier">Plugins::Call::new_base_kind_notify</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="functiontext">Kinds::Behaviour::get_name_in_template_code</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">), </span><span class="identifier">W</span><span class="plain">);</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span>
|
|
<span class="identifier">latest_base_kind_of_value</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">;</span>
|
|
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">KIND_CREATIONS</span><span class="plain">, </span><span class="string">"Created base kind $u\</span><span class="plain">n</span><span class="string">"</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">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::new_base appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP33_1"></a><b>§33.1. </b>This is used to overcome a timing problem. A few inference subjects need to
|
|
be defined early in Inform's run to set up relations — "thing", for example.
|
|
So when we do finally create "thing" as a kind of object, it needs to be
|
|
matched up with the inference subject already existing.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Renew the subject if necessary to cope with an early subject creation</span> <span class="cwebmacronumber">33.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">CORE_MODULE</span>
|
|
<span class="identifier">inference_subject</span><span class="plain"> *</span><span class="identifier">revised</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">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="identifier">Plugins::Call::name_to_early_infs</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, &</span><span class="identifier">revised</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">revised</span><span class="plain">) {</span>
|
|
<span class="identifier">InferenceSubjects::renew</span><span class="plain">(</span><span class="identifier">revised</span><span class="plain">,</span>
|
|
<span class="identifier">Kinds::Knowledge::as_subject</span><span class="plain">(</span><span class="identifier">super</span><span class="plain">), </span><span class="identifier">KIND_SUB</span><span class="plain">, </span><span class="identifier">STORE_POINTER_kind_constructor</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-</span><span class="element">>construct</span><span class="plain">), </span><span class="identifier">LIKELY_CE</span><span class="plain">);</span>
|
|
<span class="identifier">Kinds::Knowledge::set_subject</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">revised</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">This code is used in <a href="#SP33">§33</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP33_2"></a><b>§33.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Use the source-text name to attach a noun to the constructor</span> <span class="cwebmacronumber">33.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">unsigned</span><span class="plain"> </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">mc</span><span class="plain"> = </span><span class="constant">KIND_SLOW_MC</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">super</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) </span><span class="identifier">mc</span><span class="plain"> = </span><span class="identifier">NOUN_MC</span><span class="plain">;</span>
|
|
<span class="identifier">noun</span><span class="plain"> *</span><span class="identifier">nt</span><span class="plain"> = </span><span class="identifier">Nouns::new_common_noun</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">NEUTER_GENDER</span><span class="plain">,</span>
|
|
<span class="identifier">PARSE_EXACTLY_NTOPT</span><span class="plain"> + </span><span class="identifier">REGISTER_SINGULAR_NTOPT</span><span class="plain"> +</span>
|
|
<span class="identifier">REGISTER_PLURAL_NTOPT</span><span class="plain"> + </span><span class="identifier">ATTACH_TO_SEARCH_LIST_NTOPT</span><span class="plain">,</span>
|
|
<span class="constant">KIND_SLOW_MC</span><span class="plain">, </span><span class="identifier">STORE_POINTER_kind_constructor</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-</span><span class="element">>construct</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">super</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">))</span>
|
|
<span class="identifier">Nouns::set_range_number</span><span class="plain">(</span><span class="identifier">nt</span><span class="plain">, </span><span class="identifier">no_kinds_of_object</span><span class="plain">++);</span>
|
|
<span class="functiontext">Kinds::Constructors::attach_noun</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">-</span><span class="element">>construct</span><span class="plain">, </span><span class="identifier">nt</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP33">§33</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP34"></a><b>§34. Kind names in the I6 template. </b>We defined some "constant" kinds and constructors above, to provide
|
|
values like <code class="display"><span class="extract">K_number</span></code> for use in this C source code. We will also want to
|
|
refer to these kinds in the Inform 6 source code for the template, where
|
|
they will have identifiers such as <code class="display"><span class="extract">NUMBER_TY</span></code>. (If anything it's the other
|
|
way round, since the template creates these kinds at run-time, using the
|
|
kind interpreter — of which, more later.)
|
|
</p>
|
|
|
|
<p class="inwebparagraph">So we need a way of pairing up names in these two source codes, and here
|
|
it is. There is no need for speed here.
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="identifier">text_of_I6_name</span><span class="plain">, </span><span class="identifier">pointer_to_I7_structure</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">sn</span><span class="plain">) && (</span><span class="identifier">Str::eq_narrow_string</span><span class="plain">(</span><span class="identifier">sn</span><span class="plain">, </span><span class="identifier">text_of_I6_name</span><span class="plain">))) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">pointer_to_I7_structure</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind_constructor</span><span class="plain"> **</span><span class="functiontext">Kinds::known_constructor_name</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">sn</span><span class="plain">) {</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"ACTIVITY_TY"</span><span class="plain">, &</span><span class="identifier">CON_activity</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"COMBINATION_TY"</span><span class="plain">, &</span><span class="identifier">CON_combination</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"DESCRIPTION_OF_TY"</span><span class="plain">, &</span><span class="identifier">CON_description</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"INTERMEDIATE_TY"</span><span class="plain">, &</span><span class="identifier">CON_INTERMEDIATE</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"KIND_VARIABLE_TY"</span><span class="plain">, &</span><span class="identifier">CON_KIND_VARIABLE</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"LIST_OF_TY"</span><span class="plain">, &</span><span class="identifier">CON_list_of</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"PHRASE_TY"</span><span class="plain">, &</span><span class="identifier">CON_phrase</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"NIL_TY"</span><span class="plain">, &</span><span class="identifier">CON_NIL</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"PROPERTY_TY"</span><span class="plain">, &</span><span class="identifier">CON_property</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"RELATION_TY"</span><span class="plain">, &</span><span class="identifier">CON_relation</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"RULE_TY"</span><span class="plain">, &</span><span class="identifier">CON_rule</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"RULEBOOK_TY"</span><span class="plain">, &</span><span class="identifier">CON_rulebook</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"TABLE_COLUMN_TY"</span><span class="plain">, &</span><span class="identifier">CON_table_column</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"TUPLE_ENTRY_TY"</span><span class="plain">, &</span><span class="identifier">CON_TUPLE_ENTRY</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"VARIABLE_TY"</span><span class="plain">, &</span><span class="identifier">CON_variable</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">kind</span><span class="plain"> **</span><span class="functiontext">Kinds::known_kind_name</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">sn</span><span class="plain">) {</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"ARITHMETIC_VALUE_TY"</span><span class="plain">, &</span><span class="identifier">K_arithmetic_value</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"ENUMERATED_VALUE_TY"</span><span class="plain">, &</span><span class="identifier">K_enumerated_value</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"EQUATION_TY"</span><span class="plain">, &</span><span class="identifier">K_equation</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"TEXT_TY"</span><span class="plain">, &</span><span class="identifier">K_text</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"NUMBER_TY"</span><span class="plain">, &</span><span class="identifier">K_number</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"OBJECT_TY"</span><span class="plain">, &</span><span class="identifier">K_object</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"POINTER_VALUE_TY"</span><span class="plain">, &</span><span class="identifier">K_pointer_value</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"REAL_ARITHMETIC_VALUE_TY"</span><span class="plain">, &</span><span class="identifier">K_real_arithmetic_value</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"REAL_NUMBER_TY"</span><span class="plain">, &</span><span class="identifier">K_real_number</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"RESPONSE_TY"</span><span class="plain">, &</span><span class="identifier">K_response</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"RULEBOOK_OUTCOME_TY"</span><span class="plain">, &</span><span class="identifier">K_rulebook_outcome</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"SAYABLE_VALUE_TY"</span><span class="plain">, &</span><span class="identifier">K_sayable_value</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"SNIPPET_TY"</span><span class="plain">, &</span><span class="identifier">K_snippet</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"TABLE_TY"</span><span class="plain">, &</span><span class="identifier">K_table</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"TRUTH_STATE_TY"</span><span class="plain">, &</span><span class="identifier">K_truth_state</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"UNDERSTANDING_TY"</span><span class="plain">, &</span><span class="identifier">K_understanding</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"UNICODE_CHARACTER_TY"</span><span class="plain">, &</span><span class="identifier">K_unicode_character</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"USE_OPTION_TY"</span><span class="plain">, &</span><span class="identifier">K_use_option</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"VALUE_TY"</span><span class="plain">, &</span><span class="identifier">K_value</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"VERB_TY"</span><span class="plain">, &</span><span class="identifier">K_verb</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"WORD_VALUE_TY"</span><span class="plain">, &</span><span class="identifier">K_word_value</span><span class="plain">);</span>
|
|
<span class="identifier">IDENTIFIERS_CORRESPOND</span><span class="plain">(</span><span class="string">"NIL_TY"</span><span class="plain">, &</span><span class="identifier">K_nil</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Kinds::known_name</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">sn</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::known_constructor_name</span><span class="plain">(</span><span class="identifier">sn</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::known_kind_name</span><span class="plain">(</span><span class="identifier">sn</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::known_constructor_name is used in 2/kc2 (<a href="2-kc2.html#SP7">§7</a>).</p>
|
|
|
|
<p class="endnote">The function Kinds::known_kind_name is used in 2/kc2 (<a href="2-kc2.html#SP7">§7</a>).</p>
|
|
|
|
<p class="endnote">The function Kinds::known_name is used in 2/ki (<a href="2-ki.html#SP14_1">§14.1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP35"></a><b>§35. Annotating vocabulary. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">kind</span><span class="plain"> *</span><span class="functiontext">Kinds::read_kind_marking_from_vocabulary</span><span class="plain">(</span><span class="identifier">vocabulary_entry</span><span class="plain"> *</span><span class="identifier">ve</span><span class="plain">) {</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ve</span><span class="plain">-></span><span class="identifier">means</span><span class="plain">.</span><span class="identifier">one_word_kind</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Kinds::mark_vocabulary_as_kind</span><span class="plain">(</span><span class="identifier">vocabulary_entry</span><span class="plain"> *</span><span class="identifier">ve</span><span class="plain">, </span><span class="reserved">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">) {</span>
|
|
<span class="identifier">ve</span><span class="plain">-></span><span class="identifier">means</span><span class="plain">.</span><span class="identifier">one_word_kind</span><span class="plain"> = </span><span class="identifier">K</span><span class="plain">;</span>
|
|
<span class="identifier">Vocabulary::set_flags</span><span class="plain">(</span><span class="identifier">ve</span><span class="plain">, </span><span class="constant">KIND_FAST_MC</span><span class="plain">);</span>
|
|
<span class="identifier">Preform::mark_vocabulary</span><span class="plain">(</span><span class="identifier">ve</span><span class="plain">, <</span><span class="identifier">k</span><span class="plain">-</span><span class="reserved">kind</span><span class="plain">>);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function Kinds::read_kind_marking_from_vocabulary is used in 2/dk (<a href="2-dk.html#SP10">§10</a>).</p>
|
|
|
|
<p class="endnote">The function Kinds::mark_vocabulary_as_kind is used in 2/ki (<a href="2-ki.html#SP28_4">§28.4</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP36"></a><b>§36. Errors. </b></p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">enum</span> <span class="constant">DimensionRedundant_KINDERROR</span><span class="definitionkeyword"> from </span><span class="constant">1</span>
|
|
<span class="definitionkeyword">enum</span> <span class="constant">DimensionNotBaseKOV_KINDERROR</span>
|
|
<span class="definitionkeyword">enum</span> <span class="constant">NonDimensional_KINDERROR</span>
|
|
<span class="definitionkeyword">enum</span> <span class="constant">UnitSequenceOverflow_KINDERROR</span>
|
|
<span class="definitionkeyword">enum</span> <span class="constant">DimensionsInconsistent_KINDERROR</span>
|
|
<span class="definitionkeyword">enum</span> <span class="constant">KindUnalterable_KINDERROR</span>
|
|
<span class="definitionkeyword">enum</span> <span class="constant">KindsCircular_KINDERROR</span>
|
|
<span class="definitionkeyword">enum</span> <span class="constant">LPCantScaleYet_KINDERROR</span>
|
|
<span class="definitionkeyword">enum</span> <span class="constant">LPCantScaleTwice_KINDERROR</span>
|
|
</pre>
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><a href="2-itk.html">Back to 'Introduction to Kinds'</a></li><li><a href="2-kc.html">Continue with 'Kind Checking'</a></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|