1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-18 15:04:25 +03:00
inform7/docs/codegen-module/3-iap.html

1491 lines
201 KiB
HTML
Raw Normal View History

2019-03-17 14:40:57 +02:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
2020-04-14 19:56:54 +03:00
<title>Instances and Properties</title>
2020-03-19 02:11:25 +02:00
<meta name="viewport" content="width=device-width initial-scale=1">
2019-03-17 14:40:57 +02:00
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
2020-03-19 02:11:25 +02:00
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
2020-04-14 19:56:54 +03:00
2019-03-17 14:40:57 +02:00
</head>
<body>
2020-03-19 02:11:25 +02:00
<nav role="navigation">
2020-04-14 19:56:54 +03:00
<h1><a href="../index.html">
<img src="../docs-src/Figures/Inform.png" height=72">
</a></h1>
<ul><li><a href="../compiler.html">compiler tools</a></li>
2020-03-19 02:11:25 +02:00
<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>
2020-04-14 19:56:54 +03:00
</ul><h2>Compiler Webs</h2><ul>
2020-03-19 02:11:25 +02:00
<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>
2020-04-14 19:56:54 +03:00
</ul><h2>Inbuild Modules</h2><ul>
<li><a href="../supervisor-module/index.html">supervisor</a></li>
</ul><h2>Inform7 Modules</h2><ul>
2020-03-19 02:11:25 +02:00
<li><a href="../core-module/index.html">core</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>
2020-04-14 19:56:54 +03:00
<li><a href="../problems-module/index.html">problems</a></li>
2020-03-19 02:11:25 +02:00
<li><a href="../index-module/index.html">index</a></li>
2020-04-14 19:56:54 +03:00
</ul><h2>Inter Modules</h2><ul>
<li><a href="../bytecode-module/index.html">bytecode</a></li>
2020-03-19 02:11:25 +02:00
<li><a href="../building-module/index.html">building</a></li>
2020-04-14 19:56:54 +03:00
<li><a href="index.html"><span class="selectedlink">codegen</span></a></li>
</ul><h2>Shared Modules</h2><ul>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../html-module/index.html">html</a></li>
2020-03-19 02:11:25 +02:00
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
2020-04-14 19:56:54 +03:00
</ul>
2020-03-19 02:11:25 +02:00
</nav>
<main role="main">
2020-04-14 19:56:54 +03:00
<!--Weave of 'Instances and Properties' generated by 7-->
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inter Modules</a></li><li><a href="index.html">codegen</a></li><li><a href="index.html#3">Chapter 3: Inter to Final Code</a></li><li><b>Instances and Properties</b></li></ul><p class="purpose">To generate the initial state of storage for instances and their properties, and all associated metadata.</p>
2019-03-17 14:40:57 +02:00
<ul class="toc"><li><a href="3-iap.html#SP2">&#167;2. Representing instances in I6</a></li><li><a href="3-iap.html#SP3">&#167;3. Representing properties in I6</a></li><li><a href="3-iap.html#SP4">&#167;4. Properties</a></li><li><a href="3-iap.html#SP5_7">&#167;5.7. The kind inheritance tree</a></li><li><a href="3-iap.html#SP5_8">&#167;5.8. Lookup mechanism for properties of value instances</a></li><li><a href="3-iap.html#SP6">&#167;6. Instances</a></li></ul><hr class="tocbar">
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">properties_written</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">FBNA_found</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">properties_found</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="identifier">attribute_slots_used</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_property_frames</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">no_instance_frames</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">no_kind_frames</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_tree_node</span><span class="plain"> **</span><span class="identifier">property_frames</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_tree_node</span><span class="plain"> **</span><span class="identifier">instance_frames</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_tree_node</span><span class="plain"> **</span><span class="identifier">kind_frames</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
2020-04-14 19:56:54 +03:00
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CodeGen::IP::prepare<button class="popup" onclick="togglePopup('usagePopup149')">...<span class="popuptext" id="usagePopup149">Usage of <b>CodeGen::IP::prepare</b>:<br>Code Generation - <a href="3-cg.html#SP8_1">&#167;8.1</a></span></button></span><span class="plain">(</span><span class="reserved">code_generation</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">) {</span>
2019-06-29 15:17:29 +03:00
<span class="identifier">properties_written</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">FBNA_found</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">properties_found</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">attribute_slots_used</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">no_property_frames</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">no_instance_frames</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">no_kind_frames</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">Inter::Tree::traverse</span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">-&gt;</span><span class="element">from</span><span class="plain">, </span><span class="functiontext"><a href="3-iap.html#SP1">CodeGen::IP::count</a></span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">no_property_frames</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">)</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">property_frames</span><span class="plain"> = (</span><span class="identifier">inter_tree_node</span><span class="plain"> **)</span>
<span class="plain">(</span><span class="identifier">Memory::calloc</span><span class="plain">(</span><span class="identifier">no_property_frames</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="identifier">inter_tree_node</span><span class="plain"> *), </span><span class="constant">CODE_GENERATION_MREASON</span><span class="plain">));</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">no_instance_frames</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">)</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">instance_frames</span><span class="plain"> = (</span><span class="identifier">inter_tree_node</span><span class="plain"> **)</span>
<span class="plain">(</span><span class="identifier">Memory::calloc</span><span class="plain">(</span><span class="identifier">no_instance_frames</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="identifier">inter_tree_node</span><span class="plain"> *), </span><span class="constant">CODE_GENERATION_MREASON</span><span class="plain">));</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">no_kind_frames</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">)</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">kind_frames</span><span class="plain"> = (</span><span class="identifier">inter_tree_node</span><span class="plain"> **)</span>
<span class="plain">(</span><span class="identifier">Memory::calloc</span><span class="plain">(</span><span class="identifier">no_kind_frames</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="identifier">inter_tree_node</span><span class="plain"> *), </span><span class="constant">CODE_GENERATION_MREASON</span><span class="plain">));</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">no_property_frames</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">no_instance_frames</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">no_kind_frames</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">Inter::Tree::traverse</span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">-&gt;</span><span class="element">from</span><span class="plain">, </span><span class="functiontext"><a href="3-iap.html#SP1">CodeGen::IP::store</a></span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="plain">}</span>
2020-04-14 19:56:54 +03:00
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CodeGen::IP::count<button class="popup" onclick="togglePopup('usagePopup150')">...<span class="popuptext" id="usagePopup150">Usage of <b>CodeGen::IP::count</b>:<br>none</span></button></span><span class="plain">(</span><span class="identifier">inter_tree</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">state</span><span class="plain">) {</span>
2019-07-24 22:29:29 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">P</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">ID_IFLD</span><span class="plain">] == </span><span class="identifier">PROPERTY_IST</span><span class="plain">) </span><span class="identifier">no_property_frames</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">P</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">ID_IFLD</span><span class="plain">] == </span><span class="identifier">INSTANCE_IST</span><span class="plain">) </span><span class="identifier">no_instance_frames</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">P</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">ID_IFLD</span><span class="plain">] == </span><span class="identifier">KIND_IST</span><span class="plain">) </span><span class="identifier">no_kind_frames</span><span class="plain">++;</span>
<span class="plain">}</span>
2020-04-14 19:56:54 +03:00
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CodeGen::IP::store<button class="popup" onclick="togglePopup('usagePopup151')">...<span class="popuptext" id="usagePopup151">Usage of <b>CodeGen::IP::store</b>:<br>none</span></button></span><span class="plain">(</span><span class="identifier">inter_tree</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">state</span><span class="plain">) {</span>
2019-07-24 22:29:29 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">P</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">ID_IFLD</span><span class="plain">] == </span><span class="identifier">PROPERTY_IST</span><span class="plain">) </span><span class="identifier">property_frames</span><span class="plain">[</span><span class="identifier">no_property_frames</span><span class="plain">++] = </span><span class="identifier">P</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">P</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">ID_IFLD</span><span class="plain">] == </span><span class="identifier">INSTANCE_IST</span><span class="plain">) </span><span class="identifier">instance_frames</span><span class="plain">[</span><span class="identifier">no_instance_frames</span><span class="plain">++] = </span><span class="identifier">P</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">P</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">ID_IFLD</span><span class="plain">] == </span><span class="identifier">KIND_IST</span><span class="plain">) </span><span class="identifier">kind_frames</span><span class="plain">[</span><span class="identifier">no_kind_frames</span><span class="plain">++] = </span><span class="identifier">P</span><span class="plain">;</span>
2019-06-29 15:17:29 +03:00
<span class="plain">}</span>
2020-04-14 19:56:54 +03:00
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CodeGen::IP::write_properties<button class="popup" onclick="togglePopup('usagePopup152')">...<span class="popuptext" id="usagePopup152">Usage of <b>CodeGen::IP::write_properties</b>:<br>Code Generation - <a href="3-cg.html#SP8_3">&#167;8.3</a><br>Frame Control - <a href="3-fc.html#SP1">&#167;1</a></span></button></span><span class="plain">(</span><span class="reserved">code_generation</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">properties_written</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
2020-04-14 19:56:54 +03:00
<span class="reserved">generated_segment</span><span class="plain"> *</span><span class="identifier">saved</span><span class="plain"> = </span><span class="functiontext"><a href="3-cg.html#SP5">CodeGen::select</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="functiontext"><a href="4-ft.html#SP4">CodeGen::Targets::default_segment</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">));</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">TO</span><span class="plain"> = </span><span class="functiontext"><a href="3-cg.html#SP7">CodeGen::current</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext"><a href="3-cal.html#SP1">CodeGen::CL::quartet_present</a></span><span class="plain">()) {</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">TO</span><span class="plain">, </span><span class="string">"Object Compass \"compass\" has concealed;\n"</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">TO</span><span class="plain">, </span><span class="string">"Object thedark \"(darkness object)\";\n"</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">TO</span><span class="plain">, </span><span class="string">"Object InformParser \"(Inform Parser)\" has proper;\n"</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">TO</span><span class="plain">, </span><span class="string">"Object InformLibrary \"(Inform Library)\" has proper;\n"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="functiontext"><a href="3-iap.html#SP5">CodeGen::IP::knowledge</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">);</span>
2020-04-14 19:56:54 +03:00
<span class="functiontext"><a href="3-cg.html#SP5">CodeGen::deselect</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">saved</span><span class="plain">);</span>
<span class="identifier">properties_written</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. Representing instances in I6. </b>Partly for historical reasons, partly to squeeze performance out of the
2019-03-17 14:40:57 +02:00
virtual machines used in traditional parser IF, the I6 run-time
implementation of instances and their properties is complicated.
</p>
<p class="inwebparagraph">The main complication is that there are two sorts of instance: objects,
such as doors and people, and everything else, such as scenes. The two
sorts are handled equally in Inter, but have completely different run-time
representations in I6:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) "Object instances" are instances of a kind which is a subkind, perhaps
indirectly, of "object". These are stored as I6 objects, and the I6 classes
of these objects correspond exactly to their I7 kinds (except that the kind
"object" itself is mapped to the I6 class "Class").
</li></ul>
<ul class="items"><li>(b) "Value instances" are instances of kinds which are not objects but can
nevertheless have properties. The scene "entire game" is a value instance; the
number 27 is not. Value instances are stored as enumerated constants. For
example, if there are scenes called "entire game", "Overture" and "Grand
Finale", then these are stored as the constants 1, 2, 3; and I6 constants are
defined to represent them.
</li></ul>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. Representing properties in I6. </b>Both sorts of instance can have properties; for example:
2019-03-17 14:40:57 +02:00
</p>
<blockquote>
<p>A supporter has a number called carrying capacity.</p>
</blockquote>
<blockquote>
<p>A scene has a number called completion score.</p>
</blockquote>
<p class="inwebparagraph">allows a property to be held by object instances (supporters) and value
instances (scenes). To the writer of I7 source text, no distinction between
these cases is visible, and the same is true of Inter code.
</p>
<p class="inwebparagraph">How to store these at run-time is not so straightforward. Speed and
compactness are unusually important here, and constraints imposed by the
virtual machine targeted by I6 add further complications.
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) Properties of object instances are stored as either I6 properties or I6
attributes of their I6 objects. As far as possible, this is a direct mapping
from I7 instances and kinds onto I6 objects and classes. It is a little
bulkier in memory than using flat arrays, but the Glulx and Z-machine virtual
machines offer a very rapid lookup operation. Thus "the carrying capacity of
the player" can be compiled to the I6 expression <code class="display"><span class="extract">player.capacity</span></code>, which
compiles to a single short call to the I6 veneer &mdash; and one which many
interpreters today have optimised out as a basic operation, taking only a
single VM clock cycle.
</li></ul>
<ul class="items"><li>(b) The properties of value instances are stored in flat arrays called
"sticks", with each property having its own stick. For example, the property
"recurring" for a scene would have a stick holding three values, one each for
the three scenes. Sticks have the same run-time format as table columns and
this is not a coincidence, because some kinds of value instances are created
by table in I7, and this lets us use the table as a ready-made set of sticks.
But now we don't have run-time lookup mechanisms already provided for us, so
we will need to set up some metadata structures to make it possible to seek
property values for value instances quickly.
</li></ul>
<p class="inwebparagraph">In practice, property access is slightly faster for object instances, and
property storage is slightly more compact for value instances, which is
probably the right bargain.
</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Properties. </b>Properties in I7 are of two sorts: either-or, which behave adjectivally,
2019-03-17 14:40:57 +02:00
such as "open"; and value, which behave as nouns, such as "carrying capacity".
We can distinguish these because the I7 compiler annotates the property name
symbols with the <code class="display"><span class="extract">EITHER_OR_IANN</span></code> flag. It also always gives either-or
properties the kind <code class="display"><span class="extract">K_truth_state</span></code>, but note that a few value properties
also have this kind, so the annotation is the only way to be sure.
</p>
<p class="inwebparagraph">Some either-or properties of object instances can be stored as I6
"attributes". This is memory-efficient and fast at run-time: but only a
limited number can be stored this way. Here we choose which.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CodeGen::IP::property<button class="popup" onclick="togglePopup('usagePopup153')">...<span class="popuptext" id="usagePopup153">Usage of <b>CodeGen::IP::property</b>:<br><a href="3-iap.html#SP5_1">&#167;5.1</a></span></button></span><span class="plain">(</span><span class="identifier">inter_tree</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">prop_name</span><span class="plain">, </span><span class="reserved">code_generation</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">) {</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prop_name</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 property"</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">EITHER_OR_IANN</span><span class="plain">) &gt;= </span><span class="constant">0</span><span class="plain">) {</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">translated</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">EXPLICIT_ATTRIBUTE_IANN</span><span class="plain">) &gt;= </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">translated</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">ASSIMILATED_IANN</span><span class="plain">) &gt;= </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">translated</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">make_attribute</span><span class="plain"> = </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Any either/or property which can belong to a value instance is ineligible</span> <span class="cwebmacronumber">4.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">An either/or property translated to an attribute declared in the I6 template must be chosen</span> <span class="cwebmacronumber">4.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Otherwise give away attribute slots on a first-come-first-served basis</span> <span class="cwebmacronumber">4.3</span>&gt;<span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">make_attribute</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">) </span><span class="identifier">Inter::Symbols::set_flag</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">ATTRIBUTE_MARK_BIT</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Check against the I7 compiler's beliefs</span> <span class="cwebmacronumber">4.4</span>&gt;<span class="character">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">make_attribute</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Declare as an I6 attribute</span> <span class="cwebmacronumber">4.5</span>&gt;<span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
&lt;<span class="cwebmacro">Worry about the FBNA</span> <span class="cwebmacronumber">4.6</span>&gt;<span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP4_1"></a><b>&#167;4.1. </b>The dodge of using an attribute to store an either-or property won't work
2019-03-17 14:40:57 +02:00
for properties of value instances, because then the value-property-holder
object couldn't store the necessary table address (see next section). So we
must rule out any property which might belong to any value.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Any either/or property which can belong to a value instance is ineligible</span> <span class="cwebmacronumber">4.1</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
<span class="identifier">inter_node_list</span><span class="plain"> *</span><span class="identifier">PL</span><span class="plain"> =</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">Inter::Warehouse::get_frame_list</span><span class="plain">(</span>
<span class="identifier">Inter::Tree::warehouse</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">),</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">Inter::Property::permissions_list</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">PL</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no permissions list"</span><span class="plain">);</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">X</span><span class="plain">;</span>
<span class="identifier">LOOP_THROUGH_INTER_NODE_LIST</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">PL</span><span class="plain">) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">owner_name</span><span class="plain"> =</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">Inter::SymbolsTables::symbol_from_id</span><span class="plain">(</span><span class="identifier">Inter::Packages::scope_of</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">), </span><span class="identifier">X</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">OWNER_PERM_IFLD</span><span class="plain">]);</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">owner_name</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 owner"</span><span class="plain">);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">owner_kind</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">D</span><span class="plain"> = </span><span class="identifier">Inter::Symbols::definition</span><span class="plain">(</span><span class="identifier">owner_name</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">D</span><span class="plain">) &amp;&amp; (</span><span class="identifier">D</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">ID_IFLD</span><span class="plain">] == </span><span class="identifier">INSTANCE_IST</span><span class="plain">)) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">owner_kind</span><span class="plain"> = </span><span class="identifier">Inter::Instance::kind_of</span><span class="plain">(</span><span class="identifier">owner_name</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">owner_kind</span><span class="plain"> = </span><span class="identifier">owner_name</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext"><a href="3-iap.html#SP9">CodeGen::IP::is_kind_of_object</a></span><span class="plain">(</span><span class="identifier">owner_kind</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="identifier">make_attribute</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP4">&#167;4</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP4_2"></a><b>&#167;4.2. </b>An either/or property which has been deliberately equated to an I6
2019-03-17 14:40:57 +02:00
template attribute with a sentence like...
</p>
<blockquote>
<p>The fixed in place property translates into I6 as "static".</p>
</blockquote>
<p class="inwebparagraph">...is (we must assume) already declared as an <code class="display"><span class="extract">Attribute</span></code>, so we need to
remember that it's implemented as an attribute when compiling references
to it.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">An either/or property translated to an attribute declared in the I6 template must be chosen</span> <span class="cwebmacronumber">4.2</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">translated</span><span class="plain">) </span><span class="identifier">make_attribute</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP4">&#167;4</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP4_3"></a><b>&#167;4.3. </b>We have in theory 48 Attribute slots to use up, that being the number
2019-03-17 14:40:57 +02:00
available in versions 5 and higher of the Z-machine, but the I6 template
layer consumes so many that only a few slots remain for the user's own
creations. Giving these away to the first-created properties is the
simplest way to allocate them, and in fact it works pretty well, because
the first such either/or properties tend to be created in extensions and
to be frequently used.
</p>
<pre class="definitions">
2020-04-07 03:06:09 +03:00
<span class="definitionkeyword">define</span> <span class="constant">ATTRIBUTE_SLOTS_TO_GIVE_AWAY</span><span class="plain"> </span><span class="constant">11</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Otherwise give away attribute slots on a first-come-first-served basis</span> <span class="cwebmacronumber">4.3</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">make_attribute</span><span class="plain"> == </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">attribute_slots_used</span><span class="plain">++ &lt; </span><span class="constant">ATTRIBUTE_SLOTS_TO_GIVE_AWAY</span><span class="plain">)</span>
<span class="identifier">make_attribute</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">else</span>
<span class="identifier">make_attribute</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP4">&#167;4</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP4_4"></a><b>&#167;4.4. </b>At present the I7 compiler makes a decision matching this one for its
2019-03-17 14:40:57 +02:00
own internal needs. We want to make sure its decision matches ours, so we
check that here. (It tells us by marking the property name with the
<code class="display"><span class="extract">ATTRIBUTE_IANN</span></code> annotation.) But this code will eventually go.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Check against the I7 compiler's beliefs</span> <span class="cwebmacronumber">4.4</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">made_attribute</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">ATTRIBUTE_IANN</span><span class="plain">) &gt;= </span><span class="constant">0</span><span class="plain">)</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">made_attribute</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">made_attribute</span><span class="plain"> != </span><span class="identifier">make_attribute</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Disagree on %S: %d vs %d\n"</span><span class="plain">, </span><span class="identifier">prop_name</span><span class="plain">-&gt;</span><span class="identifier">symbol_name</span><span class="plain">, </span><span class="identifier">made_attribute</span><span class="plain">, </span><span class="identifier">make_attribute</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"attribute allocation dispute"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP4">&#167;4</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP4_5"></a><b>&#167;4.5. </b>A curiosity of I6 is that attributes must be declared before use, whereas
2019-03-17 14:40:57 +02:00
properties need not be. We generate suitable <code class="display"><span class="extract">Attribute</span></code> statements here.
Note that if the property has been translated onto an existing I6 name, then
we assume that's the name of an attribute already declared (for example
in the I6 template, or some extension), and we therefore do nothing.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Declare as an I6 attribute</span> <span class="cwebmacronumber">4.5</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
2020-04-14 19:56:54 +03:00
<span class="reserved">generated_segment</span><span class="plain"> *</span><span class="identifier">saved</span><span class="plain"> = </span><span class="functiontext"><a href="3-cg.html#SP5">CodeGen::select</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="functiontext"><a href="4-ft.html#SP4">CodeGen::Targets::basic_constant_segment</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="constant">1</span><span class="plain">));</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">ASSIMILATED_IANN</span><span class="plain">) &gt;= </span><span class="constant">0</span><span class="plain">) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain"> = </span><span class="identifier">Inter::Symbols::get_translate</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">);</span>
2020-04-14 19:56:54 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">A</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">A</span><span class="plain"> = </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="functiontext"><a href="3-cg.html#SP7">CodeGen::current</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">), </span><span class="string">"Attribute %S;\n"</span><span class="plain">, </span><span class="identifier">A</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<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">translated</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="functiontext"><a href="3-cg.html#SP7">CodeGen::current</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">), </span><span class="string">"Attribute %S;\n"</span><span class="plain">, </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">));</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
2020-04-14 19:56:54 +03:00
<span class="functiontext"><a href="3-cg.html#SP5">CodeGen::deselect</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">saved</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP4">&#167;4</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP4_6"></a><b>&#167;4.6. </b>The weak point in our scheme for making some either/or properties into
2019-03-17 14:40:57 +02:00
Attributes is that run-time code is going to need a fast way to determine
which, since they have to be accessed differently. We rely on the facts that
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) at run-time, attribute numbers are all numerically lower than property
numbers, and
</li></ul>
<ul class="items"><li>(b) property numbers increase in order of their first appearances in the
I6 source code.
</li></ul>
<p class="inwebparagraph">Thus an either/or property <code class="display"><span class="extract">P</span></code> must be an I6 attribute if <code class="display"><span class="extract">P &lt; F</span></code> and must be
an I6 property if <code class="display"><span class="extract">P &gt;= F</span></code>, where <code class="display"><span class="extract">F</span></code> is the earliest-defined either/or
property which isn't stored as an attribute.
</p>
<p class="inwebparagraph">This cutoff value <code class="display"><span class="extract">F</span></code> is customarily called FBNA, the "first boolean not
an attribute". (Perhaps she ought to be called FEONA.) The following
compiles an I6 constant for this value.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Worry about the FBNA</span> <span class="cwebmacronumber">4.6</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">FBNA_found</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">FBNA_found</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
2020-04-14 19:56:54 +03:00
<span class="reserved">generated_segment</span><span class="plain"> *</span><span class="identifier">saved</span><span class="plain"> = </span><span class="functiontext"><a href="3-cg.html#SP5">CodeGen::select</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="functiontext"><a href="4-ft.html#SP4">CodeGen::Targets::constant_segment</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">));</span>
<span class="functiontext"><a href="4-ft.html#SP11">CodeGen::Targets::begin_constant</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"FBNA_PROP_NUMBER"</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="functiontext"><a href="3-cg.html#SP7">CodeGen::current</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">), </span><span class="string">"%S"</span><span class="plain">, </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">));</span>
<span class="functiontext"><a href="4-ft.html#SP11">CodeGen::Targets::end_constant</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"FBNA_PROP_NUMBER"</span><span class="plain">);</span>
<span class="functiontext"><a href="3-cg.html#SP5">CodeGen::deselect</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">saved</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP4">&#167;4</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>It's unlikely, but just possible, that no FBNAs ever exist, so after the
2019-03-17 14:40:57 +02:00
above has been tried on all properties:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CodeGen::IP::knowledge<button class="popup" onclick="togglePopup('usagePopup154')">...<span class="popuptext" id="usagePopup154">Usage of <b>CodeGen::IP::knowledge</b>:<br><a href="3-iap.html#SP1">&#167;1</a></span></button></span><span class="plain">(</span><span class="reserved">code_generation</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">) {</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain"> = </span><span class="functiontext"><a href="3-cg.html#SP7">CodeGen::current</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">inter_tree</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="identifier">gen</span><span class="plain">-&gt;</span><span class="element">from</span><span class="plain">;</span>
2019-06-27 01:50:30 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">FBNA_found</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">properties_found</span><span class="plain">)) {</span>
2020-04-14 19:56:54 +03:00
<span class="reserved">generated_segment</span><span class="plain"> *</span><span class="identifier">saved</span><span class="plain"> = </span><span class="functiontext"><a href="3-cg.html#SP5">CodeGen::select</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="functiontext"><a href="4-ft.html#SP4">CodeGen::Targets::constant_segment</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">));</span>
<span class="functiontext"><a href="4-ft.html#SP11">CodeGen::Targets::begin_constant</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"FBNA_PROP_NUMBER"</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="functiontext"><a href="3-cg.html#SP7">CodeGen::current</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">), </span><span class="string">"MAX_POSITIVE_NUMBER"</span><span class="plain">);</span>
<span class="functiontext"><a href="4-ft.html#SP11">CodeGen::Targets::end_constant</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"FBNA_PROP_NUMBER"</span><span class="plain">);</span>
<span class="functiontext"><a href="3-cg.html#SP5">CodeGen::deselect</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">saved</span><span class="plain">);</span>
2019-06-27 01:50:30 +03:00
<span class="plain">}</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> **</span><span class="identifier">all_props_in_source_order</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_symbol</span><span class="plain"> **</span><span class="identifier">props_in_source_order</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_properties</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">total_no_properties</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Make a list of properties in source order</span> <span class="cwebmacronumber">5.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Compile the property numberspace forcer</span> <span class="cwebmacronumber">5.5</span>&gt;<span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> **</span><span class="identifier">kinds_in_source_order</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">inter_symbol</span><span class="plain"> **</span><span class="identifier">kinds_in_declaration_order</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Make a list of kinds in source order</span> <span class="cwebmacronumber">5.2</span>&gt;<span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> **</span><span class="identifier">instances_in_declaration_order</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Make a list of instances in declaration order</span> <span class="cwebmacronumber">5.4</span>&gt;<span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">properties_found</span><span class="plain">) </span>&lt;<span class="cwebmacro">Write Value Property Holder objects for each kind of value instance</span> <span class="cwebmacronumber">5.8</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Make a list of kinds in declaration order</span> <span class="cwebmacronumber">5.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Annotate kinds of object with a sequence counter</span> <span class="cwebmacronumber">5.6</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Write the KindHierarchy array</span> <span class="cwebmacronumber">5.7</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Write an I6 Class definition for each kind of object</span> <span class="cwebmacronumber">5.9</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Write an I6 Object definition for each object instance</span> <span class="cwebmacronumber">5.10</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Write the property metadata array</span> <span class="cwebmacronumber">5.11</span>&gt;<span class="plain">;</span>
2019-03-17 14:40:57 +02:00
&lt;<span class="cwebmacro">Stub the properties</span> <span class="cwebmacronumber">5.12</span>&gt;<span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP5_1"></a><b>&#167;5.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Make a list of properties in source order</span> <span class="cwebmacronumber">5.1</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">no_property_frames</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">property_frames</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">];</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">prop_name</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_frame_data</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">DEFN_PROP_IFLD</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">ASSIMILATED_IANN</span><span class="plain">) != </span><span class="constant">1</span><span class="plain">)</span>
<span class="identifier">total_no_properties</span><span class="plain">++;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">ASSIMILATED_IANN</span><span class="plain">) != </span><span class="constant">1</span><span class="plain">)</span>
<span class="identifier">no_properties</span><span class="plain">++;</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">no_properties</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">properties_found</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">total_no_properties</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">all_props_in_source_order</span><span class="plain"> = (</span><span class="identifier">inter_symbol</span><span class="plain"> **)</span>
<span class="plain">(</span><span class="identifier">Memory::calloc</span><span class="plain">(</span><span class="identifier">total_no_properties</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="identifier">inter_symbol</span><span class="plain"> *), </span><span class="constant">CODE_GENERATION_MREASON</span><span class="plain">));</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">no_property_frames</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">property_frames</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">];</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">prop_name</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_frame_data</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">DEFN_PROP_IFLD</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">ASSIMILATED_IANN</span><span class="plain">) != </span><span class="constant">1</span><span class="plain">)</span>
<span class="identifier">all_props_in_source_order</span><span class="plain">[</span><span class="identifier">c</span><span class="plain">++] = </span><span class="identifier">prop_name</span><span class="plain">;</span>
<span class="reserved">else</span>
<span class="functiontext"><a href="3-iap.html#SP4">CodeGen::IP::property</a></span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">gen</span><span class="plain">);</span>
<span class="plain">}</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">qsort</span><span class="plain">(</span><span class="identifier">all_props_in_source_order</span><span class="plain">, (</span><span class="identifier">size_t</span><span class="plain">) </span><span class="identifier">total_no_properties</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="identifier">inter_symbol</span><span class="plain"> *),</span>
<span class="functiontext"><a href="3-iap.html#SP7">CodeGen::IP::compare_kind_symbols</a></span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">p</span><span class="plain">=0; </span><span class="identifier">p</span><span class="plain">&lt;</span><span class="identifier">total_no_properties</span><span class="plain">; </span><span class="identifier">p</span><span class="plain">++) {</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">prop_name</span><span class="plain"> = </span><span class="identifier">all_props_in_source_order</span><span class="plain">[</span><span class="identifier">p</span><span class="plain">];</span>
<span class="functiontext"><a href="3-iap.html#SP4">CodeGen::IP::property</a></span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">gen</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">properties_found</span><span class="plain">) {</span>
<span class="identifier">props_in_source_order</span><span class="plain"> = (</span><span class="identifier">inter_symbol</span><span class="plain"> **)</span>
<span class="plain">(</span><span class="identifier">Memory::calloc</span><span class="plain">(</span><span class="identifier">no_properties</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="identifier">inter_symbol</span><span class="plain"> *), </span><span class="constant">CODE_GENERATION_MREASON</span><span class="plain">));</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">no_property_frames</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">property_frames</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">];</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">prop_name</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_frame_data</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">DEFN_PROP_IFLD</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">ASSIMILATED_IANN</span><span class="plain">) != </span><span class="constant">1</span><span class="plain">)</span>
<span class="identifier">props_in_source_order</span><span class="plain">[</span><span class="identifier">c</span><span class="plain">++] = </span><span class="identifier">prop_name</span><span class="plain">;</span>
<span class="plain">}</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">no_property_frames</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">property_frames</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">];</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">prop_name</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_frame_data</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">DEFN_PROP_IFLD</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">ASSIMILATED_IANN</span><span class="plain">) == </span><span class="constant">1</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">ATTRIBUTE_IANN</span><span class="plain">) != </span><span class="constant">1</span><span class="plain">)) {</span>
2020-04-14 19:56:54 +03:00
<span class="functiontext"><a href="4-ft.html#SP8">CodeGen::Targets::declare_property</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="plain">}</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5">&#167;5</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_2"></a><b>&#167;5.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Make a list of kinds in source order</span> <span class="cwebmacronumber">5.2</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">no_kind_frames</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">kinds_in_source_order</span><span class="plain"> = (</span><span class="identifier">inter_symbol</span><span class="plain"> **)</span>
<span class="plain">(</span><span class="identifier">Memory::calloc</span><span class="plain">(</span><span class="identifier">no_kind_frames</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="identifier">inter_symbol</span><span class="plain"> *), </span><span class="constant">CODE_GENERATION_MREASON</span><span class="plain">));</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">no_kind_frames</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">kind_frames</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">];</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">kind_name</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_frame_data</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">DEFN_KIND_IFLD</span><span class="plain">);</span>
<span class="identifier">kinds_in_source_order</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">kind_name</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">qsort</span><span class="plain">(</span><span class="identifier">kinds_in_source_order</span><span class="plain">, (</span><span class="identifier">size_t</span><span class="plain">) </span><span class="identifier">no_kind_frames</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="identifier">inter_symbol</span><span class="plain"> *),</span>
<span class="functiontext"><a href="3-iap.html#SP7">CodeGen::IP::compare_kind_symbols</a></span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5">&#167;5</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_3"></a><b>&#167;5.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Make a list of kinds in declaration order</span> <span class="cwebmacronumber">5.3</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
<span class="identifier">kinds_in_declaration_order</span><span class="plain"> = (</span><span class="identifier">inter_symbol</span><span class="plain"> **)</span>
<span class="plain">(</span><span class="identifier">Memory::calloc</span><span class="plain">(</span><span class="identifier">no_kind_frames</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="identifier">inter_symbol</span><span class="plain"> *), </span><span class="constant">CODE_GENERATION_MREASON</span><span class="plain">));</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">no_kind_frames</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">kind_frames</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">];</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">kind_name</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_frame_data</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">DEFN_KIND_IFLD</span><span class="plain">);</span>
<span class="identifier">kinds_in_declaration_order</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">kind_name</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">qsort</span><span class="plain">(</span><span class="identifier">kinds_in_declaration_order</span><span class="plain">, (</span><span class="identifier">size_t</span><span class="plain">) </span><span class="identifier">no_kind_frames</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="identifier">inter_symbol</span><span class="plain"> *),</span>
<span class="functiontext"><a href="3-iap.html#SP7">CodeGen::IP::compare_kind_symbols_decl</a></span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5">&#167;5</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_4"></a><b>&#167;5.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Make a list of instances in declaration order</span> <span class="cwebmacronumber">5.4</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">no_instance_frames</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">instances_in_declaration_order</span><span class="plain"> = (</span><span class="identifier">inter_symbol</span><span class="plain"> **)</span>
<span class="plain">(</span><span class="identifier">Memory::calloc</span><span class="plain">(</span><span class="identifier">no_instance_frames</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="identifier">inter_symbol</span><span class="plain"> *), </span><span class="constant">CODE_GENERATION_MREASON</span><span class="plain">));</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">no_instance_frames</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">instance_frames</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">];</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">inst_name</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_frame_data</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">DEFN_INST_IFLD</span><span class="plain">);</span>
<span class="identifier">instances_in_declaration_order</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">inst_name</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">qsort</span><span class="plain">(</span><span class="identifier">instances_in_declaration_order</span><span class="plain">, (</span><span class="identifier">size_t</span><span class="plain">) </span><span class="identifier">no_instance_frames</span><span class="plain">, </span><span class="reserved">sizeof</span><span class="plain">(</span><span class="identifier">inter_symbol</span><span class="plain"> *),</span>
<span class="functiontext"><a href="3-iap.html#SP7">CodeGen::IP::compare_kind_symbols_decl</a></span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5">&#167;5</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_5"></a><b>&#167;5.5. </b>But there's a snag. The above assumes that property values will have the
2019-03-17 14:40:57 +02:00
same ordering at run-time as their definition order here, but that isn't
necessarily true. The run-time ordering depends on how early in the I6
source code they appear, and that in turn depends on which objects have
which properties, and so on &mdash; nothing we can rely on.
</p>
<p class="inwebparagraph">We finesse this by creating the following spurious object before the
class hierarchy and object tree are created: its properties are therefore
all new creations, and since we declare them in I7 creation order, they
are now allocated I6 property numbers in a sequence matching this. (We
don't care about the numbering of non-either/or properties, so we don't
bother to force them.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Compile the property numberspace forcer</span> <span class="cwebmacronumber">5.5</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">properties_found</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Object property_numberspace_forcer\n"</span><span class="plain">); </span><span class="identifier">INDENT</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">p</span><span class="plain">=0; </span><span class="identifier">p</span><span class="plain">&lt;</span><span class="identifier">no_properties</span><span class="plain">; </span><span class="identifier">p</span><span class="plain">++) {</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">prop_name</span><span class="plain"> = </span><span class="identifier">props_in_source_order</span><span class="plain">[</span><span class="identifier">p</span><span class="plain">];</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Symbols::get_flag</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">ATTRIBUTE_MARK_BIT</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">kind_name</span><span class="plain"> = </span><span class="identifier">Inter::Property::kind_of</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">kind_name</span><span class="plain"> == </span><span class="identifier">truth_state_kind_symbol</span><span class="plain">) {</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" with %S false\n"</span><span class="plain">, </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">));</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">OUTDENT</span><span class="plain">; </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">";\n"</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5">&#167;5</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_6"></a><b>&#167;5.6. </b><code class="display">
&lt;<span class="cwebmacrodefn">Annotate kinds of object with a sequence counter</span> <span class="cwebmacronumber">5.6</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
2020-04-07 03:06:09 +03:00
<span class="identifier">inter_t</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">no_kind_frames</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">kind_name</span><span class="plain"> = </span><span class="identifier">kinds_in_source_order</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"><a href="3-iap.html#SP9">CodeGen::IP::is_kind_of_object</a></span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">))</span>
<span class="identifier">Inter::Symbols::annotate_i</span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">, </span><span class="identifier">OBJECT_KIND_COUNTER_IANN</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">++);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5">&#167;5</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_7"></a><b>&#167;5.7. The kind inheritance tree. </b>We begin with an array providing metadata on the kinds of object: there
2019-03-17 14:40:57 +02:00
are just two words per kind &mdash; the Inform 6 class corresponding to the kind,
then the instance count for its own kind. For instance, "door" is usually
kind number 4, so it occupies record 4 in this array &mdash; words 8 and 9. Word
8 will be <code class="display"><span class="extract">K4_door</span></code>, the Inform 6 class for doors, and word 9 will be the
number 2, meaning kind number 2, "thing". This tells us that a door is
a kind of thing. In this way, we store the hierarchy of <code class="display"><span class="extract">N</span></code> kinds in <code class="display"><span class="extract">2N</span></code>
words of memory; it's needed at run-time for checking dynamically that
property usage is legal.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Write the KindHierarchy array</span> <span class="cwebmacronumber">5.7</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
2020-04-07 03:06:09 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_kos</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">no_kind_frames</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">kind_name</span><span class="plain"> = </span><span class="identifier">kinds_in_source_order</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"><a href="3-iap.html#SP9">CodeGen::IP::is_kind_of_object</a></span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">)) </span><span class="identifier">no_kos</span><span class="plain">++;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">no_kos</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Array KindHierarchy --&gt; K0_kind (0)"</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">no_kind_frames</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">kind_name</span><span class="plain"> = </span><span class="identifier">kinds_in_source_order</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"><a href="3-iap.html#SP9">CodeGen::IP::is_kind_of_object</a></span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">)) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">super_name</span><span class="plain"> = </span><span class="identifier">Inter::Kind::super</span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">super_name</span><span class="plain">) &amp;&amp; (</span><span class="identifier">super_name</span><span class="plain"> != </span><span class="identifier">object_kind_symbol</span><span class="plain">)) {</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" %S (%d)"</span><span class="plain">, </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">),</span>
<span class="functiontext"><a href="3-iap.html#SP10">CodeGen::IP::kind_of_object_count</a></span><span class="plain">(</span><span class="identifier">super_name</span><span class="plain">));</span>
2019-03-17 14:40:57 +02:00
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" %S (0)"</span><span class="plain">, </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">));</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">";\n"</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Array KindHierarchy --&gt; (0) (0);\n"</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5">&#167;5</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_8"></a><b>&#167;5.8. Lookup mechanism for properties of value instances. </b>As noted above, if <code class="display"><span class="extract">K</span></code> is a kind which can have properties but is not a subkind
2019-03-17 14:40:57 +02:00
of object, then a property for instances of <code class="display"><span class="extract">K</span></code> is stored in an array called
a "stick". At run-time, given the property number and <code class="display"><span class="extract">K</span></code>, we will need to find
where in memory the correct stick is, and this needs to be quick.
</p>
<p class="inwebparagraph">This is essentially a dictionary lookup problem and we solve it by compiling
a faux object <code class="display"><span class="extract">V</span></code> for each <code class="display"><span class="extract">K</span></code>, called a "value property holder" or VPH.
2020-04-08 01:02:44 +03:00
Given <code class="display"><span class="extract">K</span></code> we find <code class="display"><span class="extract">V</span></code> by looking it up in the array <code class="display"><span class="extract">value_property_holders</span></code>.
2019-03-17 14:40:57 +02:00
</p>
<p class="inwebparagraph">Once we know <code class="display"><span class="extract">V</span></code>, we then look up <code class="display"><span class="extract">V.P</span></code> to get the address of the stick for
property <code class="display"><span class="extract">P</span></code>, something which the virtual machine can do quickly.
</p>
<p class="inwebparagraph">This comes at the cost of several hundred bytes of overhead, which we don't
take lightly in the Z-machine. But speed and flexibility are worth more.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Write Value Property Holder objects for each kind of value instance</span> <span class="cwebmacronumber">5.8</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
&lt;<span class="cwebmacro">Define the I6 VPH class</span> <span class="cwebmacronumber">5.8.1</span>&gt;<span class="plain">;</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">max_weak_id</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_name_in_main_or_basics</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"MAX_WEAK_ID"</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">max_weak_id</span><span class="plain">) {</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">Inter::Symbols::definition</span><span class="plain">(</span><span class="identifier">max_weak_id</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">M</span><span class="plain"> = (</span><span class="reserved">int</span><span class="plain">) </span><span class="identifier">P</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">DATA_CONST_IFLD</span><span class="plain"> + </span><span class="constant">1</span><span class="plain">];</span>
2019-03-17 14:40:57 +02:00
&lt;<span class="cwebmacro">Decide who gets a VPH</span> <span class="cwebmacronumber">5.8.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Write the VPH lookup array</span> <span class="cwebmacronumber">5.8.3</span>&gt;<span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">w</span><span class="plain">=1; </span><span class="identifier">w</span><span class="plain">&lt;</span><span class="identifier">M</span><span class="plain">; </span><span class="identifier">w</span><span class="plain">++) {</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">no_kind_frames</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">kind_name</span><span class="plain"> = </span><span class="identifier">kinds_in_source_order</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"><a href="3-iap.html#SP7">CodeGen::IP::weak_id</a></span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">) == </span><span class="identifier">w</span><span class="plain">) {</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Symbols::get_flag</span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">, </span><span class="identifier">VPH_MARK_BIT</span><span class="plain">)) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">sticks</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"VPH_Class VPH_%d\n with value_range %d\n"</span><span class="plain">,</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">w</span><span class="plain">, </span><span class="identifier">Inter::Kind::instance_count</span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">));</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">p</span><span class="plain">=0; </span><span class="identifier">p</span><span class="plain">&lt;</span><span class="identifier">no_properties</span><span class="plain">; </span><span class="identifier">p</span><span class="plain">++) {</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">prop_name</span><span class="plain"> = </span><span class="identifier">props_in_source_order</span><span class="plain">[</span><span class="identifier">p</span><span class="plain">];</span>
2020-04-14 19:56:54 +03:00
<span class="functiontext"><a href="3-cg.html#SP10">CodeGen::unmark</a></span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="identifier">inter_node_list</span><span class="plain"> *</span><span class="identifier">FL</span><span class="plain"> =</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">Inter::Warehouse::get_frame_list</span><span class="plain">(</span><span class="identifier">Inter::Tree::warehouse</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">Inter::Kind::permissions_list</span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">));</span>
&lt;<span class="cwebmacro">Work through this frame list of permissions</span> <span class="cwebmacronumber">5.8.4</span>&gt;<span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">in</span><span class="plain">=0; </span><span class="identifier">in</span><span class="plain">&lt;</span><span class="identifier">no_instance_frames</span><span class="plain">; </span><span class="identifier">in</span><span class="plain">++) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">inst_name</span><span class="plain"> = </span><span class="identifier">instances_in_declaration_order</span><span class="plain">[</span><span class="identifier">in</span><span class="plain">];</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Kind::is_a</span><span class="plain">(</span><span class="identifier">Inter::Instance::kind_of</span><span class="plain">(</span><span class="identifier">inst_name</span><span class="plain">), </span><span class="identifier">kind_name</span><span class="plain">)) {</span>
<span class="identifier">inter_node_list</span><span class="plain"> *</span><span class="identifier">FL</span><span class="plain"> =</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">Inter::Warehouse::get_frame_list</span><span class="plain">(</span><span class="identifier">Inter::Tree::warehouse</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">Inter::Instance::permissions_list</span><span class="plain">(</span><span class="identifier">inst_name</span><span class="plain">));</span>
&lt;<span class="cwebmacro">Work through this frame list of permissions</span> <span class="cwebmacronumber">5.8.4</span>&gt;<span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">";\n%S\n"</span><span class="plain">, </span><span class="identifier">sticks</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">sticks</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5">&#167;5</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_8_1"></a><b>&#167;5.8.1. </b>It's convenient to be able to distinguish, at run-time, which objects are
2019-03-17 14:40:57 +02:00
the VPH objects used only for kind-property indexing; we can test if <code class="display"><span class="extract">O</span></code> is
such an object with the I6 condition <code class="display"><span class="extract">(O ofclass VPH_Class)</span></code>.
</p>
<p class="inwebparagraph">The property <code class="display"><span class="extract">value_range</span></code> for a VPH object is the number <code class="display"><span class="extract">N</span></code> such that the
legal values at run-time for this kind are <code class="display"><span class="extract">1, 2, 3, ..., N</span></code>: or in other
words, the number of instances of this kind.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Define the I6 VPH class</span> <span class="cwebmacronumber">5.8.1</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Class VPH_Class;\n"</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5_8">&#167;5.8</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_8_2"></a><b>&#167;5.8.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Decide who gets a VPH</span> <span class="cwebmacronumber">5.8.2</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">no_kind_frames</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">kind_name</span><span class="plain"> = </span><span class="identifier">kinds_in_source_order</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"><a href="3-iap.html#SP9">CodeGen::IP::is_kind_of_object</a></span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">)) </span><span class="reserved">continue</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">kind_name</span><span class="plain"> == </span><span class="identifier">object_kind_symbol</span><span class="plain">) </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">kind_name</span><span class="plain"> == </span><span class="identifier">unchecked_kind_symbol</span><span class="plain">) </span><span class="reserved">continue</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">vph_me</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">inter_node_list</span><span class="plain"> *</span><span class="identifier">FL</span><span class="plain"> =</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">Inter::Warehouse::get_frame_list</span><span class="plain">(</span><span class="identifier">Inter::Tree::warehouse</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">Inter::Kind::permissions_list</span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">FL</span><span class="plain">-&gt;</span><span class="identifier">first_in_inl</span><span class="plain">) </span><span class="identifier">vph_me</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">in</span><span class="plain">=0; </span><span class="identifier">in</span><span class="plain">&lt;</span><span class="identifier">no_instance_frames</span><span class="plain">; </span><span class="identifier">in</span><span class="plain">++) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">inst_name</span><span class="plain"> = </span><span class="identifier">instances_in_declaration_order</span><span class="plain">[</span><span class="identifier">in</span><span class="plain">];</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Kind::is_a</span><span class="plain">(</span><span class="identifier">Inter::Instance::kind_of</span><span class="plain">(</span><span class="identifier">inst_name</span><span class="plain">), </span><span class="identifier">kind_name</span><span class="plain">)) {</span>
<span class="identifier">inter_node_list</span><span class="plain"> *</span><span class="identifier">FL</span><span class="plain"> =</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">Inter::Warehouse::get_frame_list</span><span class="plain">(</span><span class="identifier">Inter::Tree::warehouse</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">Inter::Instance::permissions_list</span><span class="plain">(</span><span class="identifier">inst_name</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">FL</span><span class="plain">-&gt;</span><span class="identifier">first_in_inl</span><span class="plain">) </span><span class="identifier">vph_me</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">vph_me</span><span class="plain">) </span><span class="identifier">Inter::Symbols::set_flag</span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">, </span><span class="identifier">VPH_MARK_BIT</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5_8">&#167;5.8</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP_1"></a><b>&#167;.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Look through this frame list of permissions</span> <span class="cwebmacronumber">.1</span>&gt; =
</code></p>
<pre class="displaydefn">
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is never used.</p>
<p class="inwebparagraph"><a id="SP5_8_3"></a><b>&#167;5.8.3. </b>This array is indexed by the weak kind ID of <code class="display"><span class="extract">K</span></code>. The entry is 0 if <code class="display"><span class="extract">K</span></code>
2019-03-17 14:40:57 +02:00
doesn't have a VPH, or the object number of its VPH if it has.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Write the VPH lookup array</span> <span class="cwebmacronumber">5.8.3</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Array value_property_holders --&gt; 0"</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">vph</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">w</span><span class="plain">=1; </span><span class="identifier">w</span><span class="plain">&lt;</span><span class="identifier">M</span><span class="plain">; </span><span class="identifier">w</span><span class="plain">++) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">written</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">no_kind_frames</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">kind_name</span><span class="plain"> = </span><span class="identifier">kinds_in_source_order</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"><a href="3-iap.html#SP7">CodeGen::IP::weak_id</a></span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">) == </span><span class="identifier">w</span><span class="plain">) {</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Symbols::get_flag</span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">, </span><span class="identifier">VPH_MARK_BIT</span><span class="plain">)) {</span>
<span class="identifier">written</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" VPH_%d"</span><span class="plain">, </span><span class="identifier">w</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">written</span><span class="plain">) </span><span class="identifier">vph</span><span class="plain">++; </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" 0"</span><span class="plain">);</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">";\n"</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Stub a faux VPH if none have otherwise been created</span> <span class="cwebmacronumber">5.8.3.1</span>&gt;<span class="plain">;</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5_8">&#167;5.8</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_8_3_1"></a><b>&#167;5.8.3.1. </b>In the event that no value instances have properties, there'll be no
2019-03-17 14:40:57 +02:00
instances of the <code class="display"><span class="extract">VPH_Class</span></code>, and no I6 object will be compiled with a
<code class="display"><span class="extract">value_range</span></code> property; that means I6 code referring to this will fail with an
I6 error. We don't want that, so if necessary we compile a useless VPH object
just to force the property into being.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Stub a faux VPH if none have otherwise been created</span> <span class="cwebmacronumber">5.8.3.1</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">vph</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"VPH_Class UnusedVPH with value_range 0;\n"</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5_8_3">&#167;5.8.3</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_8_4"></a><b>&#167;5.8.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Work through this frame list of permissions</span> <span class="cwebmacronumber">5.8.4</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">X</span><span class="plain">;</span>
<span class="identifier">LOOP_THROUGH_INTER_NODE_LIST</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">FL</span><span class="plain">) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">prop_name</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_frame_data</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">PROP_PERM_IFLD</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prop_name</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no property"</span><span class="plain">);</span>
2020-04-14 19:56:54 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext"><a href="3-cg.html#SP10">CodeGen::marked</a></span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="functiontext"><a href="3-cg.html#SP10">CodeGen::mark</a></span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">);</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">call_it</span><span class="plain"> = </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" with %S "</span><span class="plain">, </span><span class="identifier">call_it</span><span class="plain">);</span>
2019-07-24 22:29:29 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">X</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">STORAGE_PERM_IFLD</span><span class="plain">]) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">store</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_frame_data</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">STORAGE_PERM_IFLD</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">store</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 PP in inter"</span><span class="plain">);</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S"</span><span class="plain">, </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">store</span><span class="plain">));</span>
2019-03-17 14:40:57 +02:00
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
&lt;<span class="cwebmacro">Compile a stick of property values and put its address here</span> <span class="cwebmacronumber">5.8.4.1</span>&gt;<span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\n"</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5_8">&#167;5.8</a> (twice).</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_8_4_1"></a><b>&#167;5.8.4.1. </b>These little arrays are sticks of property values, and they are laid out
2019-03-17 14:40:57 +02:00
as if they were column arrays in a Table data structure. This means they must
be <code class="display"><span class="extract">table</span></code> arrays (which wastes one word of memory) and must have blanked-out
table column header words at the front (which wastes a further <code class="display"><span class="extract">COL_HSIZE</span></code>
words). But the cost is a simple overhead, not rising with the number of
instances, and it's a small price for the gain in simplicity and speed.
</p>
<p class="inwebparagraph">The entries here are bracketed to avoid the Inform 6 syntax ambiguity between
<code class="display"><span class="extract">4 -5</span></code> (two entries, four followed by minus five) and <code class="display"><span class="extract">4-5</span></code> (one entry, just
minus one). Inform 6 always uses the second interpretation, so just in case
there are negative literal integers in these array entries, we use
brackets: thus <code class="display"><span class="extract">(4) (-5)</span></code>. This cannot be confused with function calling
because I6 doesn't allow function calls in a constant context.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Compile a stick of property values and put its address here</span> <span class="cwebmacronumber">5.8.4.1</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">ident</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">ident</span><span class="plain">, </span><span class="string">"KOVP_%d_P%d"</span><span class="plain">, </span><span class="identifier">w</span><span class="plain">, </span><span class="functiontext"><a href="3-iap.html#SP7">CodeGen::IP::pnum</a></span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">));</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">ident</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">sticks</span><span class="plain">, </span><span class="string">"Array %S table 0 0"</span><span class="plain">, </span><span class="identifier">ident</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain">=0; </span><span class="identifier">j</span><span class="plain">&lt;</span><span class="identifier">no_instance_frames</span><span class="plain">; </span><span class="identifier">j</span><span class="plain">++) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">inst_name</span><span class="plain"> = </span><span class="identifier">instances_in_declaration_order</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">];</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Kind::is_a</span><span class="plain">(</span><span class="identifier">Inter::Instance::kind_of</span><span class="plain">(</span><span class="identifier">inst_name</span><span class="plain">), </span><span class="identifier">kind_name</span><span class="plain">)) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">found</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">inter_node_list</span><span class="plain"> *</span><span class="identifier">PVL</span><span class="plain"> =</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">Inter::Node::ID_to_frame_list</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">,</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">Inter::Instance::properties_list</span><span class="plain">(</span><span class="identifier">inst_name</span><span class="plain">));</span>
&lt;<span class="cwebmacro">Work through this frame list of values</span> <span class="cwebmacronumber">5.8.4.1.1</span>&gt;<span class="plain">;</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">PVL</span><span class="plain"> = </span><span class="identifier">Inter::Node::ID_to_frame_list</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">,</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">Inter::Kind::properties_list</span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">));</span>
&lt;<span class="cwebmacro">Work through this frame list of values</span> <span class="cwebmacronumber">5.8.4.1.1</span>&gt;<span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">found</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">sticks</span><span class="plain">, </span><span class="string">" (0)"</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">sticks</span><span class="plain">, </span><span class="string">";\n"</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5_8_4">&#167;5.8.4</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_8_4_1_1"></a><b>&#167;5.8.4.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Work through this frame list of values</span> <span class="cwebmacronumber">5.8.4.1.1</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">Y</span><span class="plain">;</span>
<span class="identifier">LOOP_THROUGH_INTER_NODE_LIST</span><span class="plain">(</span><span class="identifier">Y</span><span class="plain">, </span><span class="identifier">PVL</span><span class="plain">) {</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">p_name</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_id</span><span class="plain">(</span><span class="identifier">Inter::Packages::scope_of</span><span class="plain">(</span><span class="identifier">Y</span><span class="plain">), </span><span class="identifier">Y</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">PROP_PVAL_IFLD</span><span class="plain">]);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">p_name</span><span class="plain"> == </span><span class="identifier">prop_name</span><span class="plain">) &amp;&amp; (</span><span class="identifier">found</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">)) {</span>
<span class="identifier">found</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_t</span><span class="plain"> </span><span class="identifier">v1</span><span class="plain"> = </span><span class="identifier">Y</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">DVAL1_PVAL_IFLD</span><span class="plain">];</span>
<span class="identifier">inter_t</span><span class="plain"> </span><span class="identifier">v2</span><span class="plain"> = </span><span class="identifier">Y</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">DVAL2_PVAL_IFLD</span><span class="plain">];</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">sticks</span><span class="plain">, </span><span class="string">" ("</span><span class="plain">);</span>
2020-04-14 19:56:54 +03:00
<span class="functiontext"><a href="3-cg.html#SP6">CodeGen::select_temporary</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">sticks</span><span class="plain">);</span>
<span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::literal</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">Inter::Packages::scope_of</span><span class="plain">(</span><span class="identifier">Y</span><span class="plain">), </span><span class="identifier">v1</span><span class="plain">, </span><span class="identifier">v2</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="functiontext"><a href="3-cg.html#SP6">CodeGen::deselect_temporary</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">sticks</span><span class="plain">, </span><span class="string">")"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5_8_4_1">&#167;5.8.4.1</a> (twice).</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_9"></a><b>&#167;5.9. </b><code class="display">
&lt;<span class="cwebmacrodefn">Write an I6 Class definition for each kind of object</span> <span class="cwebmacronumber">5.9</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">no_kind_frames</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">kind_name</span><span class="plain"> = </span><span class="identifier">kinds_in_declaration_order</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">];</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">kind_name</span><span class="plain"> == </span><span class="identifier">object_kind_symbol</span><span class="plain">) ||</span>
<span class="plain">(</span><span class="functiontext"><a href="3-iap.html#SP9">CodeGen::IP::is_kind_of_object</a></span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">))) {</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Class %S\n"</span><span class="plain">, </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">));</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">super_name</span><span class="plain"> = </span><span class="identifier">Inter::Kind::super</span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">);</span>
2020-04-14 19:56:54 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">super_name</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" class %S\n"</span><span class="plain">, </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">super_name</span><span class="plain">));</span>
<span class="functiontext"><a href="3-iap.html#SP8">CodeGen::IP::append</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">kind_name</span><span class="plain">);</span>
<span class="identifier">inter_node_list</span><span class="plain"> *</span><span class="identifier">FL</span><span class="plain"> =</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">Inter::Warehouse::get_frame_list</span><span class="plain">(</span><span class="identifier">Inter::Tree::warehouse</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">Inter::Kind::properties_list</span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">));</span>
<span class="functiontext"><a href="3-iap.html#SP8">CodeGen::IP::plist</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">FL</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">";\n\n"</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5">&#167;5</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_10"></a><b>&#167;5.10. </b><code class="display">
&lt;<span class="cwebmacrodefn">Write an I6 Object definition for each object instance</span> <span class="cwebmacronumber">5.10</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">no_instance_frames</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">inst_name</span><span class="plain"> = </span><span class="identifier">instances_in_declaration_order</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">];</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">D</span><span class="plain"> = </span><span class="identifier">Inter::Symbols::definition</span><span class="plain">(</span><span class="identifier">inst_name</span><span class="plain">);</span>
<span class="functiontext"><a href="3-iap.html#SP8">CodeGen::IP::object_instance</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">D</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5">&#167;5</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_11"></a><b>&#167;5.11. </b>The following lets the run-time environment know what properties are
2019-03-17 14:40:57 +02:00
called, and which kinds of object are allowed to have them. This might look
a little odd: why does the run-time code need to know any of that?
</p>
<p class="inwebparagraph">The answer is that the Inform compiler will prevent grossly type-unsafe
property accesses at compile time &mdash; for example, asking if a number is
"recurring" (an either/or property of scenes), which can be ruled out
because numbers and scenes are wholly disjoint as values. But it will allow
any object property of any object to be accessed, because it's not usually
possible for the typechecker to know if an object value <code class="display"><span class="extract">O</span></code> is a vehicle, a
direction, and so on. So the finer access controls for properties of
objects are left until run-time (whereas no such regime is needed for
properties of values). To make this possible, we need to tell the run-time
code what is and is not allowed.
</p>
<p class="inwebparagraph">The <code class="display"><span class="extract">property_metadata</span></code> array is organised as a sequence of variable-sized
records. Because of that, we also need arrays telling us where to find
the start of the record for a given I6 property (or attribute): we have two
of these, called <code class="display"><span class="extract">attributed_property_offsets</span></code> and <code class="display"><span class="extract">valued_property_offsets</span></code>.
The dummy value <code class="display"><span class="extract">-1</span></code> means that the relevant property has no metadata record,
though this won't happen for any property created by I7 source text.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Write the property metadata array</span> <span class="cwebmacronumber">5.11</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">properties_found</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">pm_writer</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">pm_writer</span><span class="plain">, </span><span class="string">"[ CreatePropertyOffsets i;\n"</span><span class="plain">); </span><span class="identifier">STREAM_INDENT</span><span class="plain">(</span><span class="identifier">pm_writer</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">pm_writer</span><span class="plain">, </span><span class="string">"for (i=0: i&lt;attributed_property_offsets_SIZE: i++)"</span><span class="plain">); </span><span class="identifier">STREAM_INDENT</span><span class="plain">(</span><span class="identifier">pm_writer</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">pm_writer</span><span class="plain">, </span><span class="string">"attributed_property_offsets--&gt;i = -1;\n"</span><span class="plain">); </span><span class="identifier">STREAM_OUTDENT</span><span class="plain">(</span><span class="identifier">pm_writer</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">pm_writer</span><span class="plain">, </span><span class="string">"for (i=0: i&lt;valued_property_offsets_SIZE: i++)"</span><span class="plain">); </span><span class="identifier">STREAM_INDENT</span><span class="plain">(</span><span class="identifier">pm_writer</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">pm_writer</span><span class="plain">, </span><span class="string">"valued_property_offsets--&gt;i = -1;\n"</span><span class="plain">); </span><span class="identifier">STREAM_OUTDENT</span><span class="plain">(</span><span class="identifier">pm_writer</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Array property_metadata --&gt;\n"</span><span class="plain">); </span><span class="identifier">INDENT</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">pos</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">p</span><span class="plain">=0; </span><span class="identifier">p</span><span class="plain">&lt;</span><span class="identifier">no_properties</span><span class="plain">; </span><span class="identifier">p</span><span class="plain">++) {</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">prop_name</span><span class="plain"> = </span><span class="identifier">props_in_source_order</span><span class="plain">[</span><span class="identifier">p</span><span class="plain">];</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"! offset %d: property %S\n"</span><span class="plain">, </span><span class="identifier">pos</span><span class="plain">, </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">));</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Symbols::get_flag</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">ATTRIBUTE_MARK_BIT</span><span class="plain">))</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">pm_writer</span><span class="plain">, </span><span class="string">"attributed_property_offsets"</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">pm_writer</span><span class="plain">, </span><span class="string">"valued_property_offsets"</span><span class="plain">);</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">pm_writer</span><span class="plain">, </span><span class="string">"--&gt;%S = %d;\n"</span><span class="plain">, </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">), </span><span class="identifier">pos</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
&lt;<span class="cwebmacro">Write the property name in double quotes</span> <span class="cwebmacronumber">5.11.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Write a list of kinds or objects which are permitted to have this property</span> <span class="cwebmacronumber">5.11.2</span>&gt;<span class="plain">;</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"NULL\n"</span><span class="plain">); </span><span class="identifier">pos</span><span class="plain">++;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">OUTDENT</span><span class="plain">; </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">";\n"</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">STREAM_OUTDENT</span><span class="plain">(</span><span class="identifier">pm_writer</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">pm_writer</span><span class="plain">, </span><span class="string">"];\n"</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">pm_writer</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">pm_writer</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5">&#167;5</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_11_1"></a><b>&#167;5.11.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Write the property name in double quotes</span> <span class="cwebmacronumber">5.11.1</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\""</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="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">PROPERTY_NAME_IANN</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> &lt;= </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"&lt;nameless&gt;"</span><span class="plain">);</span>
2019-07-24 22:29:29 +03:00
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">Inter::Warehouse::get_text</span><span class="plain">(</span><span class="identifier">Inter::Tree::warehouse</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">N</span><span class="plain">));</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\" "</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">pos</span><span class="plain">++;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5_11">&#167;5.11</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_11_2"></a><b>&#167;5.11.2. </b>A complete list here would be wasteful both of space and run-time
2020-04-14 19:56:54 +03:00
checking time, but we only need a list \(O_1, O_2, ..., O_k\) such that for
each \(W\) allowed to have the property, either \(W = O_i\) for some \(i\), or
\(W\) is of kind \(O_i\) for some \(i\) (perhaps indirectly).
2019-03-17 14:40:57 +02:00
</p>
<p class="inwebparagraph">In a tricksy complication, we need to allow for the possibility that two
or more different I7 properties are actually equal at run-time. This wouldn't
happen by itself, but does happen if two different properties are translated
to the same I6 property, and in fact the template does this: "lighted" and
"lit" both translate to I6 <code class="display"><span class="extract">light</span></code>. The only way to reconcile this is to
make the list a union of the lists of both. This does mean the routine
2020-04-14 19:56:54 +03:00
runs in \(O(P^2N)\) time, where \(P\) is the number of properties and \(N\) the
number of objects, but we can live with that. \(P\) does not in practice rise
linearly with the size of the source text, even though \(N\) does.
2019-03-17 14:40:57 +02:00
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Write a list of kinds or objects which are permitted to have this property</span> <span class="cwebmacronumber">5.11.2</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">e</span><span class="plain">=0; </span><span class="identifier">e</span><span class="plain">&lt;</span><span class="identifier">no_properties</span><span class="plain">; </span><span class="identifier">e</span><span class="plain">++) {</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">eprop_name</span><span class="plain"> = </span><span class="identifier">props_in_source_order</span><span class="plain">[</span><span class="identifier">e</span><span class="plain">];</span>
2020-04-14 19:56:54 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq</span><span class="plain">(</span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">eprop_name</span><span class="plain">), </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">))) {</span>
<span class="identifier">inter_node_list</span><span class="plain"> *</span><span class="identifier">EVL</span><span class="plain"> =</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">Inter::Warehouse::get_frame_list</span><span class="plain">(</span><span class="identifier">Inter::Tree::warehouse</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">), </span><span class="identifier">Inter::Property::permissions_list</span><span class="plain">(</span><span class="identifier">eprop_name</span><span class="plain">));</span>
2019-03-17 14:40:57 +02:00
&lt;<span class="cwebmacro">List any O with an explicit permission</span> <span class="cwebmacronumber">5.11.2.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">List all top-level kinds if "object" itself has an explicit permission</span> <span class="cwebmacronumber">5.11.2.2</span>&gt;<span class="plain">;</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5_11">&#167;5.11</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_11_2_1"></a><b>&#167;5.11.2.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">List any O with an explicit permission</span> <span class="cwebmacronumber">5.11.2.1</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">=0; </span><span class="identifier">k</span><span class="plain">&lt;</span><span class="identifier">no_kind_frames</span><span class="plain">; </span><span class="identifier">k</span><span class="plain">++) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">kind_name</span><span class="plain"> = </span><span class="identifier">kinds_in_source_order</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"><a href="3-iap.html#SP9">CodeGen::IP::is_kind_of_object</a></span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">)) {</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">X</span><span class="plain">;</span>
<span class="identifier">LOOP_THROUGH_INTER_NODE_LIST</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">EVL</span><span class="plain">) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">owner_name</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_frame_data</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">OWNER_PERM_IFLD</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">owner_name</span><span class="plain"> == </span><span class="identifier">kind_name</span><span class="plain">) {</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S "</span><span class="plain">, </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">));</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">pos</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">in</span><span class="plain">=0; </span><span class="identifier">in</span><span class="plain">&lt;</span><span class="identifier">no_instance_frames</span><span class="plain">; </span><span class="identifier">in</span><span class="plain">++) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">inst_name</span><span class="plain"> = </span><span class="identifier">instances_in_declaration_order</span><span class="plain">[</span><span class="identifier">in</span><span class="plain">];</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext"><a href="3-iap.html#SP9">CodeGen::IP::is_kind_of_object</a></span><span class="plain">(</span><span class="identifier">Inter::Instance::kind_of</span><span class="plain">(</span><span class="identifier">inst_name</span><span class="plain">))) {</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">X</span><span class="plain">;</span>
<span class="identifier">LOOP_THROUGH_INTER_NODE_LIST</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">EVL</span><span class="plain">) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">owner_name</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_frame_data</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">OWNER_PERM_IFLD</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">owner_name</span><span class="plain"> == </span><span class="identifier">inst_name</span><span class="plain">) {</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S "</span><span class="plain">, </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">inst_name</span><span class="plain">));</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">pos</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5_11_2">&#167;5.11.2</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_11_2_2"></a><b>&#167;5.11.2.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">List all top-level kinds if "object" itself has an explicit permission</span> <span class="cwebmacronumber">5.11.2.2</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">eprop_name</span><span class="plain">, </span><span class="identifier">RTO_IANN</span><span class="plain">) &lt; </span><span class="constant">0</span><span class="plain">) {</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">X</span><span class="plain">;</span>
<span class="identifier">LOOP_THROUGH_INTER_NODE_LIST</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">EVL</span><span class="plain">) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">owner_name</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_frame_data</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">OWNER_PERM_IFLD</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">owner_name</span><span class="plain"> == </span><span class="identifier">object_kind_symbol</span><span class="plain">) {</span>
2020-01-13 13:02:57 +02:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"K0_kind "</span><span class="plain">); </span><span class="identifier">pos</span><span class="plain">++;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">=0; </span><span class="identifier">k</span><span class="plain">&lt;</span><span class="identifier">no_kind_frames</span><span class="plain">; </span><span class="identifier">k</span><span class="plain">++) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">kind_name</span><span class="plain"> = </span><span class="identifier">kinds_in_source_order</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">Inter::Kind::super</span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">) == </span><span class="identifier">object_kind_symbol</span><span class="plain">) {</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S "</span><span class="plain">, </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">));</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">pos</span><span class="plain">++;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5_11_2">&#167;5.11.2</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP5_12"></a><b>&#167;5.12. </b><code class="display">
&lt;<span class="cwebmacrodefn">Stub the properties</span> <span class="cwebmacronumber">5.12</span>&gt; =
2019-03-17 14:40:57 +02:00
</code></p>
<pre class="displaydefn">
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">p</span><span class="plain">=0; </span><span class="identifier">p</span><span class="plain">&lt;</span><span class="identifier">no_properties</span><span class="plain">; </span><span class="identifier">p</span><span class="plain">++) {</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">prop_name</span><span class="plain"> = </span><span class="identifier">props_in_source_order</span><span class="plain">[</span><span class="identifier">p</span><span class="plain">];</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">ASSIMILATED_IANN</span><span class="plain">) != </span><span class="constant">1</span><span class="plain">) {</span>
2020-04-14 19:56:54 +03:00
<span class="functiontext"><a href="4-ft.html#SP8">CodeGen::Targets::declare_property</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
2019-06-27 01:50:30 +03:00
<span class="plain">}</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="3-iap.html#SP5">&#167;5</a>.</p>
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Instances. </b></p>
2019-03-17 14:40:57 +02:00
<pre class="display">
2020-04-14 19:56:54 +03:00
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CodeGen::IP::instance<button class="popup" onclick="togglePopup('usagePopup155')">...<span class="popuptext" id="usagePopup155">Usage of <b>CodeGen::IP::instance</b>:<br>Frame Control - <a href="3-fc.html#SP1">&#167;1</a></span></button></span><span class="plain">(</span><span class="reserved">code_generation</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain">) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">inst_name</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_frame_data</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">DEFN_INST_IFLD</span><span class="plain">);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">inst_kind</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_frame_data</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">KIND_INST_IFLD</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Kind::is_a</span><span class="plain">(</span><span class="identifier">inst_kind</span><span class="plain">, </span><span class="identifier">object_kind_symbol</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_t</span><span class="plain"> </span><span class="identifier">val1</span><span class="plain"> = </span><span class="identifier">P</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">VAL1_INST_IFLD</span><span class="plain">];</span>
<span class="identifier">inter_t</span><span class="plain"> </span><span class="identifier">val2</span><span class="plain"> = </span><span class="identifier">P</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">VAL2_INST_IFLD</span><span class="plain">];</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain"> = </span><span class="functiontext"><a href="3-cg.html#SP7">CodeGen::current</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">);</span>
2019-06-29 15:17:29 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">defined</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">val1</span><span class="plain"> == </span><span class="identifier">UNDEF_IVAL</span><span class="plain">) </span><span class="identifier">defined</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
2020-04-14 19:56:54 +03:00
<span class="functiontext"><a href="4-ft.html#SP11">CodeGen::Targets::begin_constant</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">inst_name</span><span class="plain">), </span><span class="identifier">defined</span><span class="plain">);</span>
2019-06-29 15:17:29 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">defined</span><span class="plain">) {</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">hex</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
2019-07-26 10:59:23 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Annotations::find</span><span class="plain">(&amp;(</span><span class="identifier">inst_name</span><span class="plain">-&gt;</span><span class="identifier">ann_set</span><span class="plain">), </span><span class="identifier">HEX_IANN</span><span class="plain">)) </span><span class="identifier">hex</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
2019-06-29 15:17:29 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">hex</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"$%x"</span><span class="plain">, </span><span class="identifier">val2</span><span class="plain">); </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%d"</span><span class="plain">, </span><span class="identifier">val2</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
2020-04-14 19:56:54 +03:00
<span class="functiontext"><a href="4-ft.html#SP11">CodeGen::Targets::end_constant</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">inst_name</span><span class="plain">));</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CodeGen::IP::pnum<button class="popup" onclick="togglePopup('usagePopup156')">...<span class="popuptext" id="usagePopup156">Usage of <b>CodeGen::IP::pnum</b>:<br><a href="3-iap.html#SP5_8_4_1">&#167;5.8.4.1</a></span></button></span><span class="plain">(</span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">prop_name</span><span class="plain">) {</span>
2019-07-26 10:59:23 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = </span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">SOURCE_ORDER_IANN</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">N</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CodeGen::IP::compare_kind_symbols<button class="popup" onclick="togglePopup('usagePopup157')">...<span class="popuptext" id="usagePopup157">Usage of <b>CodeGen::IP::compare_kind_symbols</b>:<br><a href="3-iap.html#SP5_1">&#167;5.1</a>, <a href="3-iap.html#SP5_2">&#167;5.2</a></span></button></span><span class="plain">(</span><span class="reserved">const</span><span class="plain"> </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">elem1</span><span class="plain">, </span><span class="reserved">const</span><span class="plain"> </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">elem2</span><span class="plain">) {</span>
<span class="reserved">const</span><span class="plain"> </span><span class="identifier">inter_symbol</span><span class="plain"> **</span><span class="identifier">e1</span><span class="plain"> = (</span><span class="reserved">const</span><span class="plain"> </span><span class="identifier">inter_symbol</span><span class="plain"> **) </span><span class="identifier">elem1</span><span class="plain">;</span>
<span class="reserved">const</span><span class="plain"> </span><span class="identifier">inter_symbol</span><span class="plain"> **</span><span class="identifier">e2</span><span class="plain"> = (</span><span class="reserved">const</span><span class="plain"> </span><span class="identifier">inter_symbol</span><span class="plain"> **) </span><span class="identifier">elem2</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((*</span><span class="identifier">e1</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (*</span><span class="identifier">e2</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">"Disaster while sorting kinds"</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">s1</span><span class="plain"> = </span><span class="functiontext"><a href="3-iap.html#SP7">CodeGen::IP::kind_sequence_number</a></span><span class="plain">(*</span><span class="identifier">e1</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">s2</span><span class="plain"> = </span><span class="functiontext"><a href="3-iap.html#SP7">CodeGen::IP::kind_sequence_number</a></span><span class="plain">(*</span><span class="identifier">e2</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">s1</span><span class="plain"> != </span><span class="identifier">s2</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">s1</span><span class="plain">-</span><span class="identifier">s2</span><span class="plain">;</span>
2019-07-26 10:59:23 +03:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Inter::Symbols::sort_number</span><span class="plain">(*</span><span class="identifier">e1</span><span class="plain">) - </span><span class="identifier">Inter::Symbols::sort_number</span><span class="plain">(*</span><span class="identifier">e2</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CodeGen::IP::compare_kind_symbols_decl<button class="popup" onclick="togglePopup('usagePopup158')">...<span class="popuptext" id="usagePopup158">Usage of <b>CodeGen::IP::compare_kind_symbols_decl</b>:<br><a href="3-iap.html#SP5_3">&#167;5.3</a>, <a href="3-iap.html#SP5_4">&#167;5.4</a></span></button></span><span class="plain">(</span><span class="reserved">const</span><span class="plain"> </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">elem1</span><span class="plain">, </span><span class="reserved">const</span><span class="plain"> </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">elem2</span><span class="plain">) {</span>
<span class="reserved">const</span><span class="plain"> </span><span class="identifier">inter_symbol</span><span class="plain"> **</span><span class="identifier">e1</span><span class="plain"> = (</span><span class="reserved">const</span><span class="plain"> </span><span class="identifier">inter_symbol</span><span class="plain"> **) </span><span class="identifier">elem1</span><span class="plain">;</span>
<span class="reserved">const</span><span class="plain"> </span><span class="identifier">inter_symbol</span><span class="plain"> **</span><span class="identifier">e2</span><span class="plain"> = (</span><span class="reserved">const</span><span class="plain"> </span><span class="identifier">inter_symbol</span><span class="plain"> **) </span><span class="identifier">elem2</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((*</span><span class="identifier">e1</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (*</span><span class="identifier">e2</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">"Disaster while sorting kinds"</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">s1</span><span class="plain"> = </span><span class="functiontext"><a href="3-iap.html#SP7">CodeGen::IP::kind_sequence_number_decl</a></span><span class="plain">(*</span><span class="identifier">e1</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">s2</span><span class="plain"> = </span><span class="functiontext"><a href="3-iap.html#SP7">CodeGen::IP::kind_sequence_number_decl</a></span><span class="plain">(*</span><span class="identifier">e2</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">s1</span><span class="plain"> != </span><span class="identifier">s2</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">s1</span><span class="plain">-</span><span class="identifier">s2</span><span class="plain">;</span>
2019-07-26 10:59:23 +03:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Inter::Symbols::sort_number</span><span class="plain">(*</span><span class="identifier">e1</span><span class="plain">) - </span><span class="identifier">Inter::Symbols::sort_number</span><span class="plain">(*</span><span class="identifier">e2</span><span class="plain">);</span>
<span class="plain">}</span>
2020-04-14 19:56:54 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CodeGen::IP::kind_sequence_number<button class="popup" onclick="togglePopup('usagePopup159')">...<span class="popuptext" id="usagePopup159">Usage of <b>CodeGen::IP::kind_sequence_number</b>:<br>none</span></button></span><span class="plain">(</span><span class="reserved">const</span><span class="plain"> </span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">kind_name</span><span class="plain">) {</span>
2019-07-26 10:59:23 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = </span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">, </span><span class="identifier">SOURCE_ORDER_IANN</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">N</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">100000000</span><span class="plain">;</span>
<span class="plain">}</span>
2020-04-14 19:56:54 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CodeGen::IP::kind_sequence_number_decl<button class="popup" onclick="togglePopup('usagePopup160')">...<span class="popuptext" id="usagePopup160">Usage of <b>CodeGen::IP::kind_sequence_number_decl</b>:<br>none</span></button></span><span class="plain">(</span><span class="reserved">const</span><span class="plain"> </span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">kind_name</span><span class="plain">) {</span>
2019-07-26 10:59:23 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = </span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">, </span><span class="identifier">DECLARATION_ORDER_IANN</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">N</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">100000000</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CodeGen::IP::weak_id<button class="popup" onclick="togglePopup('usagePopup161')">...<span class="popuptext" id="usagePopup161">Usage of <b>CodeGen::IP::weak_id</b>:<br><a href="3-iap.html#SP5_8">&#167;5.8</a>, <a href="3-iap.html#SP5_8_3">&#167;5.8.3</a></span></button></span><span class="plain">(</span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">kind_name</span><span class="plain">) {</span>
2019-07-26 10:59:23 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = </span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">, </span><span class="identifier">WEAK_ID_IANN</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">N</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>For the I6 header syntax, see the DM4. Note that the "hardwired" short
2019-03-17 14:40:57 +02:00
name is intentionally made blank: we always use I6's <code class="display"><span class="extract">short_name</span></code> property
instead. I7's spatial plugin, if loaded (as it usually is), will have
annotated the Inter symbol for the object with an arrow count, that is,
a measure of its spatial depth. This we translate into I6 arrow notation.
If the spatial plugin wasn't loaded then we have no notion of containment,
all arrow counts are 0, and we define a flat sequence of free-standing objects.
</p>
<p class="inwebparagraph">One last oddball thing is that direction objects have to be compiled in I6
as if they were spatially inside a special object called <code class="display"><span class="extract">Compass</span></code>. This doesn't
really make much conceptual sense, and I7 dropped the idea &mdash; it has no
"compass".
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CodeGen::IP::object_instance<button class="popup" onclick="togglePopup('usagePopup162')">...<span class="popuptext" id="usagePopup162">Usage of <b>CodeGen::IP::object_instance</b>:<br><a href="3-iap.html#SP5_10">&#167;5.10</a></span></button></span><span class="plain">(</span><span class="reserved">code_generation</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain">) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">inst_name</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_frame_data</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">DEFN_INST_IFLD</span><span class="plain">);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">inst_kind</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_frame_data</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">KIND_INST_IFLD</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Kind::is_a</span><span class="plain">(</span><span class="identifier">inst_kind</span><span class="plain">, </span><span class="identifier">object_kind_symbol</span><span class="plain">)) {</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain"> = </span><span class="functiontext"><a href="3-cg.html#SP7">CodeGen::current</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"Object "</span><span class="plain">);</span>
2019-07-26 10:59:23 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">inst_name</span><span class="plain">, </span><span class="identifier">ARROW_COUNT_IANN</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">c</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"-&gt; "</span><span class="plain">);</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S \"\""</span><span class="plain">, </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">inst_name</span><span class="plain">));</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Kind::is_a</span><span class="plain">(</span><span class="identifier">inst_kind</span><span class="plain">, </span><span class="identifier">direction_kind_symbol</span><span class="plain">)) { </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" Compass"</span><span class="plain">); }</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\n class %S\n"</span><span class="plain">, </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">inst_kind</span><span class="plain">));</span>
<span class="functiontext"><a href="3-iap.html#SP8">CodeGen::IP::append</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">inst_name</span><span class="plain">);</span>
<span class="identifier">inter_node_list</span><span class="plain"> *</span><span class="identifier">FL</span><span class="plain"> =</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">Inter::Node::ID_to_frame_list</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">,</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">Inter::Instance::properties_list</span><span class="plain">(</span><span class="identifier">inst_name</span><span class="plain">));</span>
<span class="functiontext"><a href="3-iap.html#SP8">CodeGen::IP::plist</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">FL</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">";\n\n"</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CodeGen::IP::plist<button class="popup" onclick="togglePopup('usagePopup163')">...<span class="popuptext" id="usagePopup163">Usage of <b>CodeGen::IP::plist</b>:<br><a href="3-iap.html#SP5_9">&#167;5.9</a></span></button></span><span class="plain">(</span><span class="reserved">code_generation</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">inter_node_list</span><span class="plain"> *</span><span class="identifier">FL</span><span class="plain">) {</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain"> = </span><span class="functiontext"><a href="3-cg.html#SP7">CodeGen::current</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">FL</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no properties list"</span><span class="plain">);</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">X</span><span class="plain">;</span>
<span class="identifier">LOOP_THROUGH_INTER_NODE_LIST</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">FL</span><span class="plain">) {</span>
2019-03-17 14:40:57 +02:00
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">prop_name</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_frame_data</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">PROP_PVAL_IFLD</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prop_name</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no property"</span><span class="plain">);</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">call_it</span><span class="plain"> = </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Symbols::get_flag</span><span class="plain">(</span><span class="identifier">prop_name</span><span class="plain">, </span><span class="identifier">ATTRIBUTE_MARK_BIT</span><span class="plain">)) {</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">maybe</span><span class="plain"> = </span><span class="string">""</span><span class="plain">;</span>
2019-07-24 22:29:29 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">X</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">DVAL1_PVAL_IFLD</span><span class="plain">] == </span><span class="identifier">LITERAL_IVAL</span><span class="plain">) &amp;&amp;</span>
2020-04-07 03:06:09 +03:00
<span class="plain">(</span><span class="identifier">X</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">DVAL2_PVAL_IFLD</span><span class="plain">] == </span><span class="constant">0</span><span class="plain">)) </span><span class="identifier">maybe</span><span class="plain"> = </span><span class="string">"~"</span><span class="plain">;</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" has %s%S\n"</span><span class="plain">, </span><span class="identifier">maybe</span><span class="plain">, </span><span class="identifier">call_it</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" with %S "</span><span class="plain">, </span><span class="identifier">call_it</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">done</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
2019-07-24 22:29:29 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Inter::Symbols::is_stored_in_data</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">DVAL1_PVAL_IFLD</span><span class="plain">], </span><span class="identifier">X</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">DVAL2_PVAL_IFLD</span><span class="plain">])) {</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_data_pair_and_frame</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">DVAL1_PVAL_IFLD</span><span class="plain">], </span><span class="identifier">X</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">DVAL2_PVAL_IFLD</span><span class="plain">], </span><span class="identifier">X</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">S</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">INLINE_ARRAY_IANN</span><span class="plain">) == </span><span class="constant">1</span><span class="plain">)) {</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">inter_tree_node</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">Inter::Symbols::definition</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=</span><span class="identifier">DATA_CONST_IFLD</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">P</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">extent</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">=</span><span class="identifier">i</span><span class="plain">+2) {</span>
2019-03-17 14:40:57 +02:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain">&gt;</span><span class="identifier">DATA_CONST_IFLD</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" "</span><span class="plain">);</span>
2020-04-14 19:56:54 +03:00
<span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::literal</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">Inter::Packages::scope_of</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">), </span><span class="identifier">P</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">], </span><span class="identifier">P</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">+1], </span><span class="identifier">FALSE</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="identifier">done</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">done</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)</span>
2020-04-14 19:56:54 +03:00
<span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::literal</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">Inter::Packages::scope_of</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">),</span>
2019-07-24 22:29:29 +03:00
<span class="identifier">X</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">DVAL1_PVAL_IFLD</span><span class="plain">], </span><span class="identifier">X</span><span class="plain">-&gt;</span><span class="identifier">W</span><span class="plain">.</span><span class="identifier">data</span><span class="plain">[</span><span class="identifier">DVAL2_PVAL_IFLD</span><span class="plain">], </span><span class="identifier">FALSE</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\n"</span><span class="plain">);</span>
2019-03-17 14:40:57 +02:00
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CodeGen::IP::append<button class="popup" onclick="togglePopup('usagePopup164')">...<span class="popuptext" id="usagePopup164">Usage of <b>CodeGen::IP::append</b>:<br><a href="3-iap.html#SP5_9">&#167;5.9</a></span></button></span><span class="plain">(</span><span class="reserved">code_generation</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">symb</span><span class="plain">) {</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain"> = </span><span class="functiontext"><a href="3-cg.html#SP7">CodeGen::current</a></span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="identifier">inter_tree</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="identifier">gen</span><span class="plain">-&gt;</span><span class="element">from</span><span class="plain">;</span>
2019-07-26 10:59:23 +03:00
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain"> = </span><span class="identifier">Inter::Symbols::read_annotation_t</span><span class="plain">(</span><span class="identifier">symb</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">APPEND_IANN</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" "</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">L</span><span class="plain"> = </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">L</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">wchar_t</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> == </span><span class="constant">URL_SYMBOL_CHAR</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">T</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">i</span><span class="plain">&lt;</span><span class="identifier">L</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">wchar_t</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> == </span><span class="constant">URL_SYMBOL_CHAR</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
<span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">symb</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::url_name_to_symbol</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">T</span><span class="plain">);</span>
2020-04-14 19:56:54 +03:00
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S"</span><span class="plain">, </span><span class="functiontext"><a href="3-cal.html#SP4">CodeGen::CL::name</a></span><span class="plain">(</span><span class="identifier">symb</span><span class="plain">));</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">PUT</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">c</span><span class="plain"> == </span><span class="character">'\n'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">i</span><span class="plain"> != </span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">)-1)) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">" "</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CodeGen::IP::is_kind_of_object<button class="popup" onclick="togglePopup('usagePopup165')">...<span class="popuptext" id="usagePopup165">Usage of <b>CodeGen::IP::is_kind_of_object</b>:<br><a href="3-iap.html#SP4_1">&#167;4.1</a>, <a href="3-iap.html#SP5_6">&#167;5.6</a>, <a href="3-iap.html#SP5_7">&#167;5.7</a>, <a href="3-iap.html#SP5_8_2">&#167;5.8.2</a>, <a href="3-iap.html#SP5_9">&#167;5.9</a>, <a href="3-iap.html#SP5_11_2_1">&#167;5.11.2.1</a></span></button></span><span class="plain">(</span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">kind_name</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">kind_name</span><span class="plain"> == </span><span class="identifier">object_kind_symbol</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="identifier">inter_data_type</span><span class="plain"> *</span><span class="identifier">idt</span><span class="plain"> = </span><span class="identifier">Inter::Kind::data_type</span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">idt</span><span class="plain"> == </span><span class="identifier">unchecked_idt</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">Inter::Kind::is_a</span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">, </span><span class="identifier">object_kind_symbol</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="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>Counting kinds of object, not very quickly:
</p>
<pre class="display">
<span class="identifier">inter_t</span><span class="plain"> </span><span class="functiontext">CodeGen::IP::kind_of_object_count<button class="popup" onclick="togglePopup('usagePopup166')">...<span class="popuptext" id="usagePopup166">Usage of <b>CodeGen::IP::kind_of_object_count</b>:<br><a href="3-iap.html#SP5_7">&#167;5.7</a></span></button></span><span class="plain">(</span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">kind_name</span><span class="plain">) {</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">kind_name</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">kind_name</span><span class="plain"> == </span><span class="identifier">object_kind_symbol</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
2019-07-26 10:59:23 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = </span><span class="identifier">Inter::Symbols::read_annotation</span><span class="plain">(</span><span class="identifier">kind_name</span><span class="plain">, </span><span class="identifier">OBJECT_KIND_COUNTER_IANN</span><span class="plain">);</span>
2020-04-07 03:06:09 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">N</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
2019-03-17 14:40:57 +02:00
<hr class="tocbar">
2019-08-28 12:35:44 +03:00
<ul class="toc"><li><a href="3-cal.html">Back to 'Constants and Literals'</a></li><li><a href="3-vrb.html">Continue with 'Variables'</a></li></ul><hr class="tocbar">
2019-04-22 17:42:10 +03:00
<!--End of weave-->
2020-04-14 19:56:54 +03:00
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
MathJax = {
tex: {
inlineMath: '$', '$'], ['\\(', '\\)'
},
svg: {
fontCache: 'global'
}
};
</script>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>
2020-03-19 02:11:25 +02:00
</main>
2019-03-17 14:40:57 +02:00
</body>
</html>