1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 16:44:21 +03:00
inform7/docs/core-module/14-cfs.html
2020-01-27 21:54:07 +00:00

266 lines
33 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>14/ds</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of '14/cfs' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">core</a></li><li><a href="index.html#14">Chapter 14: Specifications</a></li><li><b>Compiling from Specifications</b></li></ul><p class="purpose">To compile specifications into Inform 6 values, conditions or void expressions.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Definitions</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Definitions. </b></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>In a more traditional compiler, the code-generator would be something of a
landmark &mdash; one of the three or four most important stations. Here it's
something of an anticlimax, partly because traditional "code" &mdash; values
and statements &mdash; are only a small part of the I6 we have to generate,
which also includes object and class definitions, grammar, and so on.
</p>
<p class="inwebparagraph">Still, this is the key point where the actual rather than generic
specifications &mdash; phrases to do something, or to decide things; constants;
variables; conditions &mdash; finally convert into I6 code.
</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>For the most part this is "modeless" &mdash; that is, the I6 code generated
by a specification does not depend on any context. But not entirely so, and
we have a small set of "C-modes", each of which slightly alters the result
to fit some particular need.
</p>
<p class="inwebparagraph">The rule is that any part of Inform needing to do something in a specific
mode should place that operation within a pair of <code class="display"><span class="extract">BEGIN_COMPILATION_MODE</span></code>
and <code class="display"><span class="extract">END_COMPILATION_MODE</span></code> macros, in such a way that execution always
passes from one to the other. Within those bookends, it can use either the
enter or exit macros to switch a particular mode on or off.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">BEGIN_COMPILATION_MODE</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">status_quo_ante</span><span class="plain"> = </span><span class="identifier">compilation_mode</span><span class="plain">;</span>
<span class="definitionkeyword">define</span> <span class="identifier">COMPILATION_MODE_ENTER</span><span class="plain">(</span><span class="identifier">mode</span><span class="plain">)</span>
<span class="identifier">compilation_mode</span><span class="plain"> |= </span><span class="identifier">mode</span><span class="plain">;</span>
<span class="definitionkeyword">define</span> <span class="identifier">COMPILATION_MODE_EXIT</span><span class="plain">(</span><span class="identifier">mode</span><span class="plain">)</span>
<span class="identifier">compilation_mode</span><span class="plain"> &amp;= (~</span><span class="identifier">mode</span><span class="plain">);</span>
<span class="definitionkeyword">define</span> <span class="constant">END_COMPILATION_MODE</span>
<span class="identifier">compilation_mode</span><span class="plain"> = </span><span class="identifier">status_quo_ante</span><span class="plain">;</span>
<span class="definitionkeyword">define</span> <span class="identifier">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="identifier">mode</span><span class="plain">)</span>
<span class="plain">(</span><span class="identifier">compilation_mode</span><span class="plain"> &amp; </span><span class="identifier">mode</span><span class="plain">)</span>
<span class="definitionkeyword">define</span> <span class="constant">DEREFERENCE_POINTERS_CMODE</span><span class="plain"> 0</span><span class="identifier">x00000001</span><span class="plain"> </span> <span class="comment">make an independent copy of the result if on the heap</span>
<span class="definitionkeyword">define</span> <span class="constant">IMPLY_NEWLINES_IN_SAY_CMODE</span><span class="plain"> 0</span><span class="identifier">x00000010</span><span class="plain"> </span> <span class="comment">at the end, that is</span>
<span class="definitionkeyword">define</span> <span class="constant">PERMIT_LOCALS_IN_TEXT_CMODE</span><span class="plain"> 0</span><span class="identifier">x00000020</span><span class="plain"> </span> <span class="comment">unless casting to text</span>
<span class="definitionkeyword">define</span> <span class="constant">COMPILE_TEXT_TO_QUOT_CMODE</span><span class="plain"> 0</span><span class="identifier">x00000080</span><span class="plain"> </span> <span class="comment">for the idiosyncratic I6 <code class="display"><span class="extract">box</span></code> statement</span>
<span class="definitionkeyword">define</span> <span class="constant">COMPILE_TEXT_TO_XML_CMODE</span><span class="plain"> 0</span><span class="identifier">x00000100</span><span class="plain"> </span> <span class="comment">use XML escapes and UTF-8 encoding</span>
<span class="definitionkeyword">define</span> <span class="constant">TRUNCATE_TEXT_CMODE</span><span class="plain"> 0</span><span class="identifier">x00000200</span><span class="plain"> </span> <span class="comment">into a plausible filename length</span>
<span class="definitionkeyword">define</span> <span class="constant">COMPILE_TEXT_TO_I6_CMODE</span><span class="plain"> 0</span><span class="identifier">x00001000</span><span class="plain"> </span> <span class="comment">for bibliographic text to I6 constants</span>
<span class="definitionkeyword">define</span> <span class="constant">CONSTANT_CMODE</span><span class="plain"> 0</span><span class="identifier">x00002000</span><span class="plain"> </span> <span class="comment">compiling values in a constant context</span>
<span class="definitionkeyword">define</span> <span class="constant">SPECIFICATIONS_CMODE</span><span class="plain"> 0</span><span class="identifier">x00004000</span><span class="plain"> </span> <span class="comment">compiling specifications at all</span>
<span class="definitionkeyword">define</span> <span class="constant">BLANK_OUT_CMODE</span><span class="plain"> 0</span><span class="identifier">x00008000</span><span class="plain"> </span> <span class="comment">blank out table references</span>
<span class="definitionkeyword">define</span> <span class="constant">TREAT_AS_LVALUE_CMODE</span><span class="plain"> 0</span><span class="identifier">x00010000</span><span class="plain"> </span> <span class="comment">similarly affects table references</span>
<span class="definitionkeyword">define</span> <span class="constant">JUST_ROUTINE_CMODE</span><span class="plain"> 0</span><span class="identifier">x00020000</span><span class="plain"> </span> <span class="comment">similarly affects table references</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">compilation_mode</span><span class="plain"> = </span><span class="constant">DEREFERENCE_POINTERS_CMODE</span><span class="plain"> + </span><span class="constant">IMPLY_NEWLINES_IN_SAY_CMODE</span><span class="plain">; </span> <span class="comment">default</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>These modes are all explained where they are used. The one used right here
is <code class="display"><span class="extract">DEREFERENCE_POINTERS_CMODE</span></code>. This applies only when compiling a specification
which generates a pointer value &mdash; an I6 value which is a pointer to a larger
block of data on the heap, such as a list or text.
</p>
<p class="inwebparagraph">Inform presents such values to the end user exactly as if they are non-pointer
values. It must always be careful to ensure that there are never two different
I7 values each holding pointers to the same block of data, because then
changing one would also change the other. So we ordinarily need
to make a copy of any block of data produced as a value; this is called
"dereferencing".
</p>
<p class="inwebparagraph">But there are some circumstances &mdash; initialising entries in an Inform 6 array,
for instance &mdash; where we don't want to do this, and indeed can't, because the
code to handle dereferencing is invalid as an Inform 6 constant. The mode
therefore exists as a way of temporarily turning off dereferencing &mdash; by
default, it is always on.
</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>The outer shell here has two purposes. One is to copy the specification
onto the local stack frame and then compile that copy &mdash; useful since
compilation may alter its contents. The other purpose, and this is not to
be dismissed lightly, is to ensure correct indentation in the log when
we exit unexpectedly, for instance due to a problem.
</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Specifications::Compiler::compile_inner</span><span class="plain">(</span><span class="identifier">value_holster</span><span class="plain"> *</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">EXPRESSIONS</span><span class="plain">, </span><span class="string">"Compiling: $P\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="identifier">spec</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::substitute_constants</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="constant">BEGIN_COMPILATION_MODE</span><span class="plain">;</span>
<span class="identifier">COMPILATION_MODE_ENTER</span><span class="plain">(</span><span class="constant">SPECIFICATIONS_CMODE</span><span class="plain">);</span>
<span class="identifier">LOG_INDENT</span><span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> </span><span class="identifier">breakable_copy</span><span class="plain"> = *</span><span class="identifier">spec</span><span class="plain">;</span>
<span class="functiontext">Specifications::Compiler::spec_compile_primitive</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, &amp;</span><span class="identifier">breakable_copy</span><span class="plain">);</span>
<span class="identifier">LOG_OUTDENT</span><span class="plain">;</span>
<span class="constant">END_COMPILATION_MODE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Specifications::Compiler::compile_inner is used in <a href="#SP9">&#167;9</a>, 15/vp (<a href="15-vp.html#SP11">&#167;11</a>), 25/cii (<a href="25-cii.html#SP8">&#167;8</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>So this is where the compilation is done, or rather, delegated:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Specifications::Compiler::spec_compile_primitive</span><span class="plain">(</span><span class="identifier">value_holster</span><span class="plain"> *</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K_found</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="functiontext">Kinds::RunTime::notify_of_use</span><span class="plain">(</span><span class="identifier">K_found</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">dereffed</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">TEST_COMPILATION_MODE</span><span class="plain">(</span><span class="constant">DEREFERENCE_POINTERS_CMODE</span><span class="plain">)) {</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">K</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Kinds::Behaviour::uses_pointer_values</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">))) {</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">BLKVALUECOPY_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Frames::emit_allocation</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">dereffed</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="functiontext">ParseTreeUsage::is_lvalue</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
<span class="functiontext">Lvalues::compile</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTreeUsage::is_rvalue</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
<span class="functiontext">Rvalues::compile</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">VH</span><span class="plain">-&gt;</span><span class="identifier">vhmode_provided</span><span class="plain"> == </span><span class="identifier">INTER_DATA_VHMODE</span><span class="plain">) &amp;&amp; (</span><span class="identifier">VH</span><span class="plain">-&gt;</span><span class="identifier">vhmode_wanted</span><span class="plain"> == </span><span class="identifier">INTER_VAL_VHMODE</span><span class="plain">)) {</span>
<span class="identifier">Holsters::to_val_mode</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">VH</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">ParseTreeUsage::is_condition</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
<span class="functiontext">Conditions::compile</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">dereffed</span><span class="plain">) {</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Specifications::Compiler::spec_compile_primitive is used in <a href="#SP6">&#167;6</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>A variation on this is to compile a specification which represents
a value in a context where a particular kind of value is expected:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Specifications::Compiler::emit_to_kind</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">value</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K_wanted</span><span class="plain">) {</span>
<span class="functiontext">Kinds::RunTime::notify_of_use</span><span class="plain">(</span><span class="identifier">K_wanted</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K_found</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">value</span><span class="plain">);</span>
<span class="functiontext">Kinds::RunTime::notify_of_use</span><span class="plain">(</span><span class="identifier">K_found</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">K_understanding</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K_wanted</span><span class="plain">, </span><span class="identifier">K_understanding</span><span class="plain">)) &amp;&amp; (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K_found</span><span class="plain">, </span><span class="identifier">K_text</span><span class="plain">))) {</span>
<span class="identifier">ParseTree::set_kind_of_value</span><span class="plain">(</span><span class="identifier">value</span><span class="plain">, </span><span class="identifier">K_understanding</span><span class="plain">);</span>
<span class="identifier">K_found</span><span class="plain"> = </span><span class="identifier">K_understanding</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">down</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="functiontext">Kinds::RunTime::emit_cast_call</span><span class="plain">(</span><span class="identifier">K_found</span><span class="plain">, </span><span class="identifier">K_wanted</span><span class="plain">, &amp;</span><span class="identifier">down</span><span class="plain">);</span>
<span class="constant">BEGIN_COMPILATION_MODE</span><span class="plain">;</span>
<span class="identifier">COMPILATION_MODE_ENTER</span><span class="plain">(</span><span class="constant">PERMIT_LOCALS_IN_TEXT_CMODE</span><span class="plain">);</span>
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">value</span><span class="plain">);</span>
<span class="constant">END_COMPILATION_MODE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">down</span><span class="plain">) </span><span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Specifications::Compiler::emit_to_kind is used in 12/is (<a href="12-is.html#SP7_3">&#167;7.3</a>), 13/ca (<a href="13-ca.html#SP1_2_1">&#167;1.2.1</a>, <a href="13-ca.html#SP1_2_2">&#167;1.2.2</a>), 25/ci (<a href="25-ci.html#SP3_2_3_1_1">&#167;3.2.3.1.1</a>), 25/ciac (<a href="25-ciac.html#SP2_1">&#167;2.1</a>), 25/cii (<a href="25-cii.html#SP3_1_1_3">&#167;3.1.1.3</a>, <a href="25-cii.html#SP3_1_1_4_7_1">&#167;3.1.1.4.7.1</a>, <a href="25-cii.html#SP3_5_8">&#167;3.5.8</a>, <a href="25-cii.html#SP3_5_8_1">&#167;3.5.8.1</a>, <a href="25-cii.html#SP3_5_8_2">&#167;3.5.8.2</a>, <a href="25-cii.html#SP3_5_8_3">&#167;3.5.8.3</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>And the same in a constant context:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Specifications::Compiler::compile_constant_to_kind_vh</span><span class="plain">(</span><span class="identifier">value_holster</span><span class="plain"> *</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">value</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K_wanted</span><span class="plain">) {</span>
<span class="functiontext">Kinds::RunTime::notify_of_use</span><span class="plain">(</span><span class="identifier">K_wanted</span><span class="plain">);</span>
<span class="constant">BEGIN_COMPILATION_MODE</span><span class="plain">;</span>
<span class="identifier">COMPILATION_MODE_EXIT</span><span class="plain">(</span><span class="constant">DEREFERENCE_POINTERS_CMODE</span><span class="plain">);</span>
<span class="identifier">COMPILATION_MODE_ENTER</span><span class="plain">(</span><span class="constant">CONSTANT_CMODE</span><span class="plain">);</span>
<span class="functiontext">Specifications::Compiler::compile_inner</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">Kinds::Behaviour::cast_constant</span><span class="plain">(</span><span class="identifier">value</span><span class="plain">, </span><span class="identifier">K_wanted</span><span class="plain">));</span>
<span class="constant">END_COMPILATION_MODE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Specifications::Compiler::emit_constant_to_kind</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">value</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K_wanted</span><span class="plain">) {</span>
<span class="functiontext">Kinds::RunTime::notify_of_use</span><span class="plain">(</span><span class="identifier">K_wanted</span><span class="plain">);</span>
<span class="constant">BEGIN_COMPILATION_MODE</span><span class="plain">;</span>
<span class="identifier">COMPILATION_MODE_EXIT</span><span class="plain">(</span><span class="constant">DEREFERENCE_POINTERS_CMODE</span><span class="plain">);</span>
<span class="identifier">COMPILATION_MODE_ENTER</span><span class="plain">(</span><span class="constant">CONSTANT_CMODE</span><span class="plain">);</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">casted</span><span class="plain"> = </span><span class="identifier">Kinds::Behaviour::cast_constant</span><span class="plain">(</span><span class="identifier">value</span><span class="plain">, </span><span class="identifier">K_wanted</span><span class="plain">);</span>
<span class="constant">END_COMPILATION_MODE</span><span class="plain">;</span>
<span class="functiontext">Specifications::Compiler::emit</span><span class="plain">(</span><span class="identifier">casted</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Specifications::Compiler::emit_constant_to_kind_as_val</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">value</span><span class="plain">, </span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K_wanted</span><span class="plain">) {</span>
<span class="functiontext">Kinds::RunTime::notify_of_use</span><span class="plain">(</span><span class="identifier">K_wanted</span><span class="plain">);</span>
<span class="constant">BEGIN_COMPILATION_MODE</span><span class="plain">;</span>
<span class="identifier">COMPILATION_MODE_EXIT</span><span class="plain">(</span><span class="constant">DEREFERENCE_POINTERS_CMODE</span><span class="plain">);</span>
<span class="identifier">COMPILATION_MODE_ENTER</span><span class="plain">(</span><span class="constant">CONSTANT_CMODE</span><span class="plain">);</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">casted</span><span class="plain"> = </span><span class="identifier">Kinds::Behaviour::cast_constant</span><span class="plain">(</span><span class="identifier">value</span><span class="plain">, </span><span class="identifier">K_wanted</span><span class="plain">);</span>
<span class="constant">END_COMPILATION_MODE</span><span class="plain">;</span>
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">casted</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Specifications::Compiler::emit</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
<span class="identifier">value_holster</span><span class="plain"> </span><span class="identifier">VH</span><span class="plain"> = </span><span class="identifier">Holsters::new</span><span class="plain">(</span><span class="identifier">INTER_DATA_VHMODE</span><span class="plain">);</span>
<span class="constant">BEGIN_COMPILATION_MODE</span><span class="plain">;</span>
<span class="identifier">COMPILATION_MODE_EXIT</span><span class="plain">(</span><span class="constant">DEREFERENCE_POINTERS_CMODE</span><span class="plain">);</span>
<span class="identifier">COMPILATION_MODE_ENTER</span><span class="plain">(</span><span class="constant">CONSTANT_CMODE</span><span class="plain">);</span>
<span class="functiontext">Specifications::Compiler::compile_inner</span><span class="plain">(&amp;</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="constant">END_COMPILATION_MODE</span><span class="plain">;</span>
<span class="identifier">inter_t</span><span class="plain"> </span><span class="identifier">v1</span><span class="plain"> = 0, </span><span class="identifier">v2</span><span class="plain"> = 0;</span>
<span class="identifier">Holsters::unholster_pair</span><span class="plain">(&amp;</span><span class="identifier">VH</span><span class="plain">, &amp;</span><span class="identifier">v1</span><span class="plain">, &amp;</span><span class="identifier">v2</span><span class="plain">);</span>
<span class="functiontext">Emit::array_generic_entry</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="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain">) {</span>
<span class="identifier">value_holster</span><span class="plain"> </span><span class="identifier">VH</span><span class="plain"> = </span><span class="identifier">Holsters::new</span><span class="plain">(</span><span class="identifier">INTER_VAL_VHMODE</span><span class="plain">);</span>
<span class="functiontext">Specifications::Compiler::compile_inner</span><span class="plain">(&amp;</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Specifications::Compiler::compile_constant_to_kind_vh is used in 5/nv (<a href="5-nv.html#SP25">&#167;25</a>), 15/vp (<a href="15-vp.html#SP11">&#167;11</a>).</p>
<p class="endnote">The function Specifications::Compiler::emit_constant_to_kind is used in 18/lc (<a href="18-lc.html#SP12_1">&#167;12.1</a>), 19/rsft (<a href="19-rsft.html#SP1_1_1_1_1_4">&#167;1.1.1.1.1.4</a>).</p>
<p class="endnote">The function Specifications::Compiler::emit_constant_to_kind_as_val appears nowhere else.</p>
<p class="endnote">The function Specifications::Compiler::emit is used in 21/rb (<a href="21-rb.html#SP24_1_3">&#167;24.1.3</a>).</p>
<p class="endnote">The function Specifications::Compiler::emit_as_val is used in <a href="#SP8">&#167;8</a>, 6/bp (<a href="6-bp.html#SP33">&#167;33</a>), 6/rlt (<a href="6-rlt.html#SP30">&#167;30</a>), 11/tr (<a href="11-tr.html#SP10">&#167;10</a>), 12/dtd (<a href="12-dtd.html#SP7_1_2">&#167;7.1.2</a>, <a href="12-dtd.html#SP15">&#167;15</a>, <a href="12-dtd.html#SP17">&#167;17</a>, <a href="12-dtd.html#SP18">&#167;18</a>, <a href="12-dtd.html#SP19">&#167;19</a>, <a href="12-dtd.html#SP20">&#167;20</a>, <a href="12-dtd.html#SP22">&#167;22</a>, <a href="12-dtd.html#SP23">&#167;23</a>, <a href="12-dtd.html#SP25">&#167;25</a>, <a href="12-dtd.html#SP27">&#167;27</a>), 12/cad (<a href="12-cad.html#SP3">&#167;3</a>), 14/rv (<a href="14-rv.html#SP24_3">&#167;24.3</a>), 14/lv (<a href="14-lv.html#SP14_3">&#167;14.3</a>, <a href="14-lv.html#SP14_3_2">&#167;14.3.2</a>, <a href="14-lv.html#SP14_4">&#167;14.4</a>, <a href="14-lv.html#SP14_5">&#167;14.5</a>), 14/cn (<a href="14-cn.html#SP16">&#167;16</a>, <a href="14-cn.html#SP16_1">&#167;16.1</a>, <a href="14-cn.html#SP16_2">&#167;16.2</a>), 20/eq (<a href="20-eq.html#SP48">&#167;48</a>), 21/rl (<a href="21-rl.html#SP11_1">&#167;11.1</a>), 21/rb (<a href="21-rb.html#SP24_1_3">&#167;24.1.3</a>), 21/ac (<a href="21-ac.html#SP14">&#167;14</a>), 23/abc (<a href="23-abc.html#SP1">&#167;1</a>), 24/ch (<a href="24-ch.html#SP7_4_1">&#167;7.4.1</a>), 25/ciac (<a href="25-ciac.html#SP2">&#167;2</a>), 25/cii (<a href="25-cii.html#SP3_1_1_4_9">&#167;3.1.1.4.9</a>, <a href="25-cii.html#SP3_1_1_4_10">&#167;3.1.1.4.10</a>, <a href="25-cii.html#SP8">&#167;8</a>), 25/cp (<a href="25-cp.html#SP5_3_5">&#167;5.3.5</a>, <a href="25-cp.html#SP5_3_5_1">&#167;5.3.5.1</a>), 26/ts (<a href="26-ts.html#SP11">&#167;11</a>, <a href="26-ts.html#SP12">&#167;12</a>).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="14-ds.html">Back to 'Descriptions'</a></li><li><a href="14-ds2.html">Continue with 'Dash'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>