1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-06-02 16:38:08 +03:00
inform7/docs/core-module/14-rv.html
2020-03-11 00:21:09 +00:00

1227 lines
171 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>14/sp</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/rv' 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>RValues</b></li></ul><p class="purpose">Utility functions for specifications representing rvalues.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Constants</a></li><li><a href="#SP7">&#167;7. Literals as rvalues</a></li><li><a href="#SP17">&#167;17. Pairs</a></li><li><a href="#SP18">&#167;18. Constant descriptions</a></li><li><a href="#SP19">&#167;19. Testing</a></li><li><a href="#SP21">&#167;21. Pretty-printing</a></li><li><a href="#SP23">&#167;23. Compilation</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Constants. </b>Constant nodes can store references to many of the structures in this compiler:
for example, each <code class="display"><span class="extract">table *</span></code> pointer in Inform corresponds to a constant node
representing the name of that table.
</p>
<p class="inwebparagraph">Dealing with these is very repetitive, and we use macros to define the
relevant routines. Firstly, creating a CONSTANT node from one of these
pointers:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="identifier">CONV_FROM</span><span class="plain">(</span><span class="identifier">structure</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">ParseTree::new</span><span class="plain">(</span><span class="constant">CONSTANT_NT</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_constant_</span><span class="plain">##</span><span class="identifier">structure</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">val</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">;</span>
</pre>
<pre class="display">
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_action_name</span><span class="plain">(</span><span class="identifier">action_name</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">) { </span><span class="identifier">CONV_FROM</span><span class="plain">(</span><span class="identifier">action_name</span><span class="plain">, </span><span class="identifier">K_action_name</span><span class="plain">) }</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_action_pattern</span><span class="plain">(</span><span class="identifier">action_pattern</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (((</span><span class="identifier">PL::Actions::Patterns::is_unspecific</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">PL::Actions::Patterns::is_overspecific</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">preform_lookahead_mode</span><span class="plain">)) {</span>
<span class="identifier">CONV_FROM</span><span class="plain">(</span><span class="identifier">action_pattern</span><span class="plain">, </span><span class="identifier">K_stored_action</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">CONV_FROM</span><span class="plain">(</span><span class="identifier">action_pattern</span><span class="plain">, </span><span class="identifier">K_description_of_action</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_grammar_verb</span><span class="plain">(</span><span class="identifier">grammar_verb</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">) { </span><span class="identifier">CONV_FROM</span><span class="plain">(</span><span class="identifier">grammar_verb</span><span class="plain">, </span><span class="identifier">K_understanding</span><span class="plain">) }</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_named_action_pattern</span><span class="plain">(</span><span class="identifier">named_action_pattern</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">) { </span><span class="identifier">CONV_FROM</span><span class="plain">(</span><span class="identifier">named_action_pattern</span><span class="plain">, </span><span class="identifier">K_nil</span><span class="plain">) }</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_scene</span><span class="plain">(</span><span class="identifier">scene</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">) { </span><span class="identifier">CONV_FROM</span><span class="plain">(</span><span class="identifier">scene</span><span class="plain">, </span><span class="identifier">K_scene</span><span class="plain">) }</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_activity</span><span class="reserved">(activity</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">) { </span><span class="identifier">CONV_FROM</span><span class="reserved">(activity</span><span class="plain">, </span><span class="functiontext">Activities::to_kind</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">)) }</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_binary_predicate</span><span class="plain">(</span><span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">) { </span><span class="identifier">CONV_FROM</span><span class="plain">(</span><span class="reserved">binary_predicate</span><span class="plain">, </span><span class="identifier">Kinds::base_construction</span><span class="plain">(</span><span class="identifier">CON_relation</span><span class="plain">)) }</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_constant_phrase</span><span class="plain">(</span><span class="reserved">constant_phrase</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">) { </span><span class="identifier">CONV_FROM</span><span class="plain">(</span><span class="reserved">constant_phrase</span><span class="plain">, </span><span class="identifier">Kinds::base_construction</span><span class="plain">(</span><span class="identifier">CON_phrase</span><span class="plain">)) }</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_equation</span><span class="plain">(</span><span class="reserved">equation</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">) { </span><span class="identifier">CONV_FROM</span><span class="plain">(</span><span class="reserved">equation</span><span class="plain">, </span><span class="identifier">K_equation</span><span class="plain">) }</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_named_rulebook_outcome</span><span class="plain">(</span><span class="reserved">named_rulebook_outcome</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">) { </span><span class="identifier">CONV_FROM</span><span class="plain">(</span><span class="reserved">named_rulebook_outcome</span><span class="plain">, </span><span class="identifier">K_rulebook_outcome</span><span class="plain">) }</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_property</span><span class="plain">(</span><span class="reserved">property</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">) { </span><span class="identifier">CONV_FROM</span><span class="plain">(</span><span class="reserved">property</span><span class="plain">, </span><span class="functiontext">Properties::to_kind</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">)) }</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_rule</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">) { </span><span class="identifier">CONV_FROM</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain">, </span><span class="functiontext">Rules::to_kind</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">)) }</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_rulebook</span><span class="plain">(</span><span class="reserved">rulebook</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">) { </span><span class="identifier">CONV_FROM</span><span class="plain">(</span><span class="reserved">rulebook</span><span class="plain">, </span><span class="functiontext">Rulebooks::to_kind</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">)) }</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_table</span><span class="plain">(</span><span class="reserved">table</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">) { </span><span class="identifier">CONV_FROM</span><span class="plain">(</span><span class="reserved">table</span><span class="plain">, </span><span class="identifier">K_table</span><span class="plain">) }</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_table_column</span><span class="plain">(</span><span class="reserved">table_column</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">) { </span><span class="identifier">CONV_FROM</span><span class="plain">(</span><span class="reserved">table_column</span><span class="plain">, </span><span class="functiontext">Tables::Columns::to_kind</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">)) }</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_use_option</span><span class="plain">(</span><span class="reserved">use_option</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">) { </span><span class="identifier">CONV_FROM</span><span class="plain">(</span><span class="reserved">use_option</span><span class="plain">, </span><span class="identifier">K_use_option</span><span class="plain">) }</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_verb_form</span><span class="plain">(</span><span class="identifier">verb_form</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain">) { </span><span class="identifier">CONV_FROM</span><span class="plain">(</span><span class="identifier">verb_form</span><span class="plain">, </span><span class="identifier">K_verb</span><span class="plain">) }</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::from_action_name appears nowhere else.</p>
<p class="endnote">The function Rvalues::from_action_pattern is used in 9/ma (<a href="9-ma.html#SP3_3_11">&#167;3.3.11</a>), 14/cn (<a href="14-cn.html#SP10">&#167;10</a>).</p>
<p class="endnote">The function Rvalues::from_grammar_verb appears nowhere else.</p>
<p class="endnote">The function Rvalues::from_named_action_pattern appears nowhere else.</p>
<p class="endnote">The function Rvalues::from_scene appears nowhere else.</p>
<p class="endnote">The function Rvalues::from_activity is used in 9/tc (<a href="9-tc.html#SP5_4_2_5">&#167;5.4.2.5</a>), 21/ac (<a href="21-ac.html#SP6">&#167;6</a>).</p>
<p class="endnote">The function Rvalues::from_binary_predicate is used in 6/bp (<a href="6-bp.html#SP28">&#167;28</a>), 12/ter (<a href="12-ter.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function Rvalues::from_constant_phrase is used in 22/pav (<a href="22-pav.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function Rvalues::from_equation is used in 10/teav (<a href="10-teav.html#SP12_1">&#167;12.1</a>, <a href="10-teav.html#SP12_3">&#167;12.3</a>), 20/eq (<a href="20-eq.html#SP10_1_3">&#167;10.1.3</a>).</p>
<p class="endnote">The function Rvalues::from_named_rulebook_outcome is used in 21/fao (<a href="21-fao.html#SP10">&#167;10</a>).</p>
<p class="endnote">The function Rvalues::from_property is used in 9/rpt (<a href="9-rpt.html#SP9_7_6_1">&#167;9.7.6.1</a>), 11/tr (<a href="11-tr.html#SP8">&#167;8</a>), 11/pr (<a href="11-pr.html#SP27">&#167;27</a>), 11/tc (<a href="11-tc.html#SP4">&#167;4</a>), 15/pr (<a href="15-pr.html#SP5_8">&#167;5.8</a>), 15/ma (<a href="15-ma.html#SP13">&#167;13</a>).</p>
<p class="endnote">The function Rvalues::from_rule is used in 21/rl (<a href="21-rl.html#SP5_1">&#167;5.1</a>), 21/rb (<a href="21-rb.html#SP24_1">&#167;24.1</a>).</p>
<p class="endnote">The function Rvalues::from_rulebook is used in 9/tc (<a href="9-tc.html#SP5_4_2_4">&#167;5.4.2.4</a>), 21/rl2 (<a href="21-rl2.html#SP10">&#167;10</a>).</p>
<p class="endnote">The function Rvalues::from_table is used in 19/tb (<a href="19-tb.html#SP20_7">&#167;20.7</a>).</p>
<p class="endnote">The function Rvalues::from_table_column is used in 19/tc (<a href="19-tc.html#SP4">&#167;4</a>).</p>
<p class="endnote">The function Rvalues::from_use_option is used in 26/uo (<a href="26-uo.html#SP5">&#167;5</a>).</p>
<p class="endnote">The function Rvalues::from_verb_form is used in 10/cad (<a href="10-cad.html#SP1_1">&#167;1.1</a>).</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Contrariwise, here's how to get back again:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="identifier">CONV_TO</span><span class="plain">(</span><span class="identifier">structure</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">spec</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">structure</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain"> = </span><span class="identifier">ParseTree::get_constant_</span><span class="plain">##</span><span class="identifier">structure</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">val</span><span class="plain">;</span>
</pre>
<pre class="display">
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="identifier">action_name</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_action_name</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">CONV_TO</span><span class="plain">(</span><span class="identifier">action_name</span><span class="plain">) }</span>
<span class="identifier">action_pattern</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_action_pattern</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">CONV_TO</span><span class="plain">(</span><span class="identifier">action_pattern</span><span class="plain">) }</span>
<span class="identifier">grammar_verb</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_grammar_verb</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">CONV_TO</span><span class="plain">(</span><span class="identifier">grammar_verb</span><span class="plain">) }</span>
<span class="identifier">named_action_pattern</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_named_action_pattern</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">CONV_TO</span><span class="plain">(</span><span class="identifier">named_action_pattern</span><span class="plain">) }</span>
<span class="identifier">scene</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_scene</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">CONV_TO</span><span class="plain">(</span><span class="identifier">scene</span><span class="plain">) }</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">activity</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_activity</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">CONV_TO</span><span class="reserved">(activity</span><span class="plain">) }</span>
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_binary_predicate</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">CONV_TO</span><span class="plain">(</span><span class="reserved">binary_predicate</span><span class="plain">) }</span>
<span class="reserved">constant_phrase</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_constant_phrase</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">CONV_TO</span><span class="plain">(</span><span class="reserved">constant_phrase</span><span class="plain">) }</span>
<span class="reserved">equation</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_equation</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">CONV_TO</span><span class="plain">(</span><span class="reserved">equation</span><span class="plain">) }</span>
<span class="reserved">named_rulebook_outcome</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_named_rulebook_outcome</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">CONV_TO</span><span class="plain">(</span><span class="reserved">named_rulebook_outcome</span><span class="plain">) }</span>
<span class="reserved">property</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_property</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">CONV_TO</span><span class="plain">(</span><span class="reserved">property</span><span class="plain">) }</span>
<span class="reserved">rule</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_rule</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">CONV_TO</span><span class="plain">(</span><span class="reserved">rule</span><span class="plain">) }</span>
<span class="reserved">rulebook</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_rulebook</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">CONV_TO</span><span class="plain">(</span><span class="reserved">rulebook</span><span class="plain">) }</span>
<span class="reserved">table</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_table</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">CONV_TO</span><span class="plain">(</span><span class="reserved">table</span><span class="plain">) }</span>
<span class="reserved">table_column</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_table_column</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">CONV_TO</span><span class="plain">(</span><span class="reserved">table_column</span><span class="plain">) }</span>
<span class="reserved">use_option</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_use_option</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">CONV_TO</span><span class="plain">(</span><span class="reserved">use_option</span><span class="plain">) }</span>
<span class="identifier">verb_form</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_verb_form</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">CONV_TO</span><span class="plain">(</span><span class="identifier">verb_form</span><span class="plain">) }</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::to_action_name appears nowhere else.</p>
<p class="endnote">The function Rvalues::to_action_pattern is used in 10/cap (<a href="10-cap.html#SP3">&#167;3</a>), 14/cn (<a href="14-cn.html#SP10">&#167;10</a>, <a href="14-cn.html#SP16">&#167;16</a>), 24/ch (<a href="24-ch.html#SP4">&#167;4</a>).</p>
<p class="endnote">The function Rvalues::to_grammar_verb appears nowhere else.</p>
<p class="endnote">The function Rvalues::to_named_action_pattern appears nowhere else.</p>
<p class="endnote">The function Rvalues::to_scene appears nowhere else.</p>
<p class="endnote">The function Rvalues::to_activity is used in <a href="#SP20">&#167;20</a>, <a href="#SP24_3">&#167;24.3</a>, 9/ma (<a href="9-ma.html#SP3_3_25_1">&#167;3.3.25.1</a>), 21/ac (<a href="21-ac.html#SP11">&#167;11</a>).</p>
<p class="endnote">The function Rvalues::to_binary_predicate is used in <a href="#SP20">&#167;20</a>, <a href="#SP23_2">&#167;23.2</a>, <a href="#SP24_3">&#167;24.3</a>, 11/tcp (<a href="11-tcp.html#SP11_3">&#167;11.3</a>).</p>
<p class="endnote">The function Rvalues::to_constant_phrase is used in <a href="#SP20">&#167;20</a>, <a href="#SP23_6">&#167;23.6</a>, <a href="#SP24_3">&#167;24.3</a>, 22/pav (<a href="22-pav.html#SP4">&#167;4</a>).</p>
<p class="endnote">The function Rvalues::to_equation is used in <a href="#SP24_3">&#167;24.3</a>, 10/teav (<a href="10-teav.html#SP12_2">&#167;12.2</a>), 25/cii (<a href="25-cii.html#SP3_7_3">&#167;3.7.3</a>).</p>
<p class="endnote">The function Rvalues::to_named_rulebook_outcome is used in <a href="#SP24_3">&#167;24.3</a>, 21/fao (<a href="21-fao.html#SP9">&#167;9</a>, <a href="21-fao.html#SP10">&#167;10</a>).</p>
<p class="endnote">The function Rvalues::to_property is used in <a href="#SP20">&#167;20</a>, <a href="#SP23_3">&#167;23.3</a>, <a href="#SP24_3_1">&#167;24.3.1</a>, 9/tc (<a href="9-tc.html#SP4_5">&#167;4.5</a>), 9/ma (<a href="9-ma.html#SP3_3_8_2">&#167;3.3.8.2</a>, <a href="9-ma.html#SP3_3_41_4">&#167;3.3.41.4</a>, <a href="9-ma.html#SP3_3_41_7">&#167;3.3.41.7</a>), 11/pr (<a href="11-pr.html#SP35_2">&#167;35.2</a>), 11/sc (<a href="11-sc.html#SP3_3">&#167;3.3</a>), 11/sm (<a href="11-sm.html#SP17_1">&#167;17.1</a>, <a href="11-sm.html#SP18">&#167;18</a>), 14/lv (<a href="14-lv.html#SP10">&#167;10</a>, <a href="14-lv.html#SP12_5">&#167;12.5</a>, <a href="14-lv.html#SP14_3">&#167;14.3</a>), 14/ds2 (<a href="14-ds2.html#SP11_9_1_1_2_1">&#167;11.9.1.1.2.1</a>, <a href="14-ds2.html#SP11_9_1_1_5_1_2">&#167;11.9.1.1.5.1.2</a>, <a href="14-ds2.html#SP11_9_1_2_3">&#167;11.9.1.2.3</a>, <a href="14-ds2.html#SP13">&#167;13</a>, <a href="14-ds2.html#SP19_3">&#167;19.3</a>), 15/pr (<a href="15-pr.html#SP4">&#167;4</a>), 15/tpr (<a href="15-tpr.html#SP6">&#167;6</a>, <a href="15-tpr.html#SP7">&#167;7</a>), 25/cii (<a href="25-cii.html#SP3_1_1_4_11">&#167;3.1.1.4.11</a>, <a href="25-cii.html#SP3_7">&#167;3.7</a>).</p>
<p class="endnote">The function Rvalues::to_rule is used in <a href="#SP20">&#167;20</a>, <a href="#SP24_3">&#167;24.3</a>, 9/ma (<a href="9-ma.html#SP3_3_41_6">&#167;3.3.41.6</a>), 12/is (<a href="12-is.html#SP7_1">&#167;7.1</a>), 21/rl (<a href="21-rl.html#SP6">&#167;6</a>), 25/cii (<a href="25-cii.html#SP3_1_1_4_12">&#167;3.1.1.4.12</a>).</p>
<p class="endnote">The function Rvalues::to_rulebook is used in <a href="#SP20">&#167;20</a>, <a href="#SP24_3">&#167;24.3</a>, 9/ma (<a href="9-ma.html#SP3_3_18">&#167;3.3.18</a>, <a href="9-ma.html#SP3_3_25_2">&#167;3.3.25.2</a>), 21/rps (<a href="21-rps.html#SP2">&#167;2</a>).</p>
<p class="endnote">The function Rvalues::to_table is used in <a href="#SP24_3">&#167;24.3</a>, 19/tod (<a href="19-tod.html#SP6">&#167;6</a>).</p>
<p class="endnote">The function Rvalues::to_table_column is used in <a href="#SP20">&#167;20</a>, <a href="#SP23_5">&#167;23.5</a>, <a href="#SP24_3">&#167;24.3</a>, 11/sm (<a href="11-sm.html#SP4">&#167;4</a>), 14/lv (<a href="14-lv.html#SP12_3">&#167;12.3</a>), 19/tc (<a href="19-tc.html#SP13">&#167;13</a>).</p>
<p class="endnote">The function Rvalues::to_use_option is used in <a href="#SP24_3">&#167;24.3</a>, 26/uo (<a href="26-uo.html#SP7">&#167;7</a>).</p>
<p class="endnote">The function Rvalues::to_verb_form is used in <a href="#SP24_3">&#167;24.3</a>.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>With enumerated kinds, the possible values are in general stored as instance
objects.
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_instance</span><span class="plain">(</span><span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain"> = </span><span class="identifier">ParseTree::new</span><span class="plain">(</span><span class="constant">CONSTANT_NT</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_kind_of_value</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">, </span><span class="functiontext">Instances::to_kind</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">));</span>
<span class="identifier">ParseTree::set_constant_instance</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">, </span><span class="constant">constant_enumeration_ANNOT</span><span class="plain">, </span><span class="functiontext">Instances::get_numerical_value</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">));</span>
<span class="identifier">ParseTree::set_text</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">, </span><span class="functiontext">Instances::get_name</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">));</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">val</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_instance</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">CONV_TO</span><span class="plain">(</span><span class="reserved">instance</span><span class="plain">) }</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::from_instance is used in 4/am (<a href="4-am.html#SP25_6">&#167;25.6</a>), 5/ins (<a href="5-ins.html#SP6_3">&#167;6.3</a>, <a href="5-ins.html#SP36">&#167;36</a>), 9/rpt (<a href="9-rpt.html#SP6">&#167;6</a>), 9/tc (<a href="9-tc.html#SP5_4_1_1">&#167;5.4.1.1</a>, <a href="9-tc.html#SP5_4_2_3">&#167;5.4.2.3</a>), 10/cad (<a href="10-cad.html#SP17">&#167;17</a>), 11/tr (<a href="11-tr.html#SP8">&#167;8</a>), 11/tc (<a href="11-tc.html#SP3">&#167;3</a>), 12/ap (<a href="12-ap.html#SP9_5_2">&#167;9.5.2</a>), 14/lv (<a href="14-lv.html#SP14_3_1">&#167;14.3.1</a>), 14/ds (<a href="14-ds.html#SP5">&#167;5</a>), 16/is (<a href="16-is.html#SP18">&#167;18</a>), 16/ic (<a href="16-ic.html#SP9">&#167;9</a>), 19/tb (<a href="19-tb.html#SP24">&#167;24</a>).</p>
<p class="endnote">The function Rvalues::to_instance is used in <a href="#SP4">&#167;4</a>, <a href="#SP20">&#167;20</a>, <a href="#SP22">&#167;22</a>, <a href="#SP23_1">&#167;23.1</a>, <a href="#SP24_3">&#167;24.3</a>, 2/sq (<a href="2-sq.html#SP4">&#167;4</a>), 4/am (<a href="4-am.html#SP25_4">&#167;25.4</a>), 5/ins (<a href="5-ins.html#SP17">&#167;17</a>), 9/ma (<a href="9-ma.html#SP3_3_39">&#167;3.3.39</a>, <a href="9-ma.html#SP3_3_40_1">&#167;3.3.40.1</a>, <a href="9-ma.html#SP3_3_41_5">&#167;3.3.41.5</a>), 10/varc (<a href="10-varc.html#SP9_1">&#167;9.1</a>), 11/pr (<a href="11-pr.html#SP35_1">&#167;35.1</a>), 12/ter (<a href="12-ter.html#SP8_5">&#167;8.5</a>), 14/sp (<a href="14-sp.html#SP4">&#167;4</a>), 14/ds (<a href="14-ds.html#SP5">&#167;5</a>), 14/ds2 (<a href="14-ds2.html#SP11_9_1_1_5_1_1">&#167;11.9.1.1.5.1.1</a>), 16/is (<a href="16-is.html#SP17">&#167;17</a>), 22/prcd (<a href="22-prcd.html#SP6">&#167;6</a>), 24/lv (<a href="24-lv.html#SP34">&#167;34</a>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>An instance of a subkind of <code class="display"><span class="extract">K_object</span></code> is called an "object":
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rvalues::is_object</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="reserved">if</span><span class="plain"> ((</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">CONSTANT_NT</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">ParseTree::get_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">), </span><span class="identifier">K_object</span><span class="plain">)))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_object_instance</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="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_object</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Rvalues::to_instance</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::is_object is used in <a href="#SP22">&#167;22</a>, <a href="#SP23">&#167;23</a>, 2/sq (<a href="2-sq.html#SP4">&#167;4</a>), 9/ma (<a href="9-ma.html#SP3_3_41">&#167;3.3.41</a>, <a href="9-ma.html#SP3_3_41_2">&#167;3.3.41.2</a>), 9/rk (<a href="9-rk.html#SP1_3">&#167;1.3</a>), 14/sp (<a href="14-sp.html#SP3">&#167;3</a>, <a href="14-sp.html#SP4">&#167;4</a>), 14/ds2 (<a href="14-ds2.html#SP11_9_1_2_3">&#167;11.9.1.2.3</a>), 24/lv (<a href="24-lv.html#SP34">&#167;34</a>).</p>
<p class="endnote">The function Rvalues::to_object_instance is used in <a href="#SP20">&#167;20</a>, 4/am (<a href="4-am.html#SP25_6">&#167;25.6</a>), 10/cad (<a href="10-cad.html#SP12">&#167;12</a>, <a href="10-cad.html#SP17">&#167;17</a>), 11/tr (<a href="11-tr.html#SP11">&#167;11</a>), 14/ds2 (<a href="14-ds2.html#SP11_9_1_1_5_1">&#167;11.9.1.1.5.1</a>), 16/is (<a href="16-is.html#SP12">&#167;12</a>, <a href="16-is.html#SP17">&#167;17</a>), 25/cp (<a href="25-cp.html#SP5_3_5">&#167;5.3.5</a>).</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>There are two pseudo-objects for which no pointers to <code class="display"><span class="extract">instance</span></code> can exist:
"self" and "nothing". These cause nothing but trouble and are marked out with
special annotations.
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::new_self_object_constant</span><span class="plain">(</span><span class="reserved">void</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">ParseTree::new</span><span class="plain">(</span><span class="constant">CONSTANT_NT</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">self_object_ANNOT</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">spec</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::new_nothing_object_constant</span><span class="plain">(</span><span class="reserved">void</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">ParseTree::new</span><span class="plain">(</span><span class="constant">CONSTANT_NT</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">nothing_object_ANNOT</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">spec</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::new_self_object_constant is used in 11/sc (<a href="11-sc.html#SP3_5">&#167;3.5</a>), 12/is (<a href="12-is.html#SP8">&#167;8</a>), 14/ds2 (<a href="14-ds2.html#SP19_3_1_1">&#167;19.3.1.1</a>).</p>
<p class="endnote">The function Rvalues::new_nothing_object_constant is used in 10/cad (<a href="10-cad.html#SP1">&#167;1</a>), 11/tc (<a href="11-tc.html#SP3">&#167;3</a>), 16/ic (<a href="16-ic.html#SP9">&#167;9</a>), 25/ci (<a href="25-ci.html#SP3_1_1_1">&#167;3.1.1.1</a>), 25/cp (<a href="25-cp.html#SP5_3_5">&#167;5.3.5</a>).</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>To test for the self/nothing anomalies (that really could be an episode
title from "The Big Bang Theory"),
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rvalues::is_nothing_object_constant</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="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">nothing_object_ANNOT</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rvalues::is_self_object_constant</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="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">self_object_ANNOT</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::is_nothing_object_constant is used in 9/pk (<a href="9-pk.html#SP2_1">&#167;2.1</a>), 9/rk (<a href="9-rk.html#SP1_3">&#167;1.3</a>), 11/bas (<a href="11-bas.html#SP13">&#167;13</a>), 11/sm (<a href="11-sm.html#SP3">&#167;3</a>), 12/ap (<a href="12-ap.html#SP9_11_1">&#167;9.11.1</a>), 14/sp (<a href="14-sp.html#SP3">&#167;3</a>, <a href="14-sp.html#SP4">&#167;4</a>), 14/ds2 (<a href="14-ds2.html#SP19">&#167;19</a>).</p>
<p class="endnote">The function Rvalues::is_self_object_constant is used in 14/lv (<a href="14-lv.html#SP6">&#167;6</a>, <a href="14-lv.html#SP14_3_1">&#167;14.3.1</a>), 14/ds2 (<a href="14-ds2.html#SP11_9_1_2_3">&#167;11.9.1.2.3</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Literals as rvalues. </b>Notation such as "24 kg" is converted inside Inform into a suitable integer,
perhaps 24000, and the following turns that into an rvalue:
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_encoded_notation</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="reserved">int</span><span class="plain"> </span><span class="identifier">encoded_value</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">ParseTree::new_with_words</span><span class="plain">(</span><span class="constant">CONSTANT_NT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">explicit_literal_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">constant_number_ANNOT</span><span class="plain">, </span><span class="identifier">encoded_value</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rvalues::to_encoded_notation</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="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">explicit_literal_ANNOT</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">constant_number_ANNOT</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> 0;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::from_encoded_notation is used in 10/pl (<a href="10-pl.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Rvalues::to_encoded_notation is used in <a href="#SP20">&#167;20</a>, 5/lp (<a href="5-lp.html#SP34_4">&#167;34.4</a>), 15/ma (<a href="15-ma.html#SP8_2">&#167;8.2</a>).</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>We can also convert to and from integers, but there we use an integer
annotation, not a pointer one.
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_int</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">wording</span><span class="plain"> </span><span class="identifier">W</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">ParseTree::new_with_words</span><span class="plain">(</span><span class="constant">CONSTANT_NT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">K_number</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">explicit_literal_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">constant_number_ANNOT</span><span class="plain">, </span><span class="identifier">n</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rvalues::to_int</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="reserved">if</span><span class="plain"> (</span><span class="identifier">spec</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> 0;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">explicit_literal_ANNOT</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">constant_number_ANNOT</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> 0;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::from_int is used in 6/rlt (<a href="6-rlt.html#SP26_1">&#167;26.1</a>), 10/pl (<a href="10-pl.html#SP1">&#167;1</a>), 16/ic (<a href="16-ic.html#SP12_1">&#167;12.1</a>, <a href="16-ic.html#SP12_3_1">&#167;12.3.1</a>, <a href="16-ic.html#SP12_3_2">&#167;12.3.2</a>), 20/eq (<a href="20-eq.html#SP50_3_1">&#167;50.3.1</a>), 25/cii (<a href="25-cii.html#SP3_5_4_1">&#167;3.5.4.1</a>, <a href="25-cii.html#SP3_7_2">&#167;3.7.2</a>).</p>
<p class="endnote">The function Rvalues::to_int is used in <a href="#SP24_1">&#167;24.1</a>, 13/ca (<a href="13-ca.html#SP1_12">&#167;1.12</a>), 19/tb (<a href="19-tb.html#SP26_2">&#167;26.2</a>), 20/eq (<a href="20-eq.html#SP41_2_1">&#167;41.2.1</a>, <a href="20-eq.html#SP50_3_1">&#167;50.3.1</a>).</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>Internally we represent parsed reals as unsigned integers holding their
IEEE-754 representations; I just don't sufficiently trust C's implementation
of <code class="display"><span class="extract">float</span></code> to be consistent across all Inform's platforms to use it.
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_IEEE_754</span><span class="plain">(</span><span class="reserved">unsigned</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">wording</span><span class="plain"> </span><span class="identifier">W</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">ParseTree::new_with_words</span><span class="plain">(</span><span class="constant">CONSTANT_NT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">K_real_number</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">explicit_literal_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">constant_number_ANNOT</span><span class="plain">, (</span><span class="reserved">int</span><span class="plain">) </span><span class="identifier">n</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">unsigned</span><span class="plain"> </span><span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rvalues::to_IEEE_754</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="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_CONSTANT_of_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">K_real_number</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> (</span><span class="reserved">unsigned</span><span class="plain"> </span><span class="reserved">int</span><span class="plain">) </span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">constant_number_ANNOT</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> 0</span><span class="identifier">x7F800001</span><span class="plain">; </span> <span class="comment">which is a NaN value</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::from_IEEE_754 is used in 10/pl (<a href="10-pl.html#SP5">&#167;5</a>).</p>
<p class="endnote">The function Rvalues::to_IEEE_754 appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>And exactly similarly, truth states:
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_boolean</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">flag</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">ParseTree::new_with_words</span><span class="plain">(</span><span class="constant">CONSTANT_NT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">K_truth_state</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">explicit_literal_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">constant_number_ANNOT</span><span class="plain">, </span><span class="identifier">flag</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rvalues::to_boolean</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="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_CONSTANT_of_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">K_truth_state</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">constant_number_ANNOT</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::from_boolean is used in 10/pl (<a href="10-pl.html#SP3">&#167;3</a>).</p>
<p class="endnote">The function Rvalues::to_boolean appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>And Unicode character values.
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_Unicode_point</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">code_point</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">ParseTree::new_with_words</span><span class="plain">(</span><span class="constant">CONSTANT_NT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">K_unicode_character</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">explicit_literal_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">constant_number_ANNOT</span><span class="plain">, </span><span class="identifier">code_point</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rvalues::to_Unicode_point</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="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_CONSTANT_of_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">K_unicode_character</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">constant_number_ANNOT</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> 0;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::from_Unicode_point is used in 5/ut (<a href="5-ut.html#SP4">&#167;4</a>).</p>
<p class="endnote">The function Rvalues::to_Unicode_point is used in 26/ct (<a href="26-ct.html#SP4">&#167;4</a>).</p>
<p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>In the traditional Inform world model, time is measured in minutes,
reduced modulo 1440, the number of minutes in a day.
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_time</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">minutes_since_midnight</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">ParseTree::new_with_words</span><span class="plain">(</span><span class="constant">CONSTANT_NT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="functiontext">PL::TimesOfDay::kind</span><span class="plain">());</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">explicit_literal_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">constant_number_ANNOT</span><span class="plain">, </span><span class="identifier">minutes_since_midnight</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rvalues::to_time</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="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_CONSTANT_of_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="functiontext">PL::TimesOfDay::kind</span><span class="plain">()))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">constant_number_ANNOT</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> 0;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::from_time is used in 5/tod (<a href="5-tod.html#SP6">&#167;6</a>).</p>
<p class="endnote">The function Rvalues::to_time appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. </b>For obscure timing reasons, we store literal lists as just their wordings
together with their kinds:
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_wording_of_list</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">wording</span><span class="plain"> </span><span class="identifier">W</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">ParseTree::new_with_words</span><span class="plain">(</span><span class="constant">CONSTANT_NT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::from_wording_of_list is used in 18/lc (<a href="18-lc.html#SP4">&#167;4</a>).</p>
<p class="inwebparagraph"><a id="SP14"></a><b>&#167;14. </b>Text mostly comes from wordings:
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_wording</span><span class="plain">(</span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="identifier">ParseTree::new_with_words</span><span class="plain">(</span><span class="constant">CONSTANT_NT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">K_text</span><span class="plain">);</span>
<span class="reserved">return</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 Rvalues::from_wording is used in <a href="#SP15">&#167;15</a>, 9/tfa (<a href="9-tfa.html#SP11">&#167;11</a>), 10/pl (<a href="10-pl.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP15"></a><b>&#167;15. </b>It's convenient to have a version for text where square brackets should
be interpreted literally, not as escapes for a text substitution:
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_unescaped_wording</span><span class="plain">(</span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec</span><span class="plain"> = </span><span class="functiontext">Rvalues::from_wording</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">text_unescaped_ANNOT</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">spec</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::from_unescaped_wording appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP16"></a><b>&#167;16. </b></p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_iname</span><span class="plain">(</span><span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">I</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">ParseTree::new</span><span class="plain">(</span><span class="constant">CONSTANT_NT</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">K_text</span><span class="plain">);</span>
<span class="identifier">ParseTree::annotate_int</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">explicit_literal_ANNOT</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_explicit_iname</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">);</span>
<span class="reserved">return</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 Rvalues::from_iname appears nowhere else.</p>
<p class="inwebparagraph"><a id="SP17"></a><b>&#167;17. Pairs. </b>We can also form an r-value by combining two existing values; note that in
Inform, unlike in (say) Perl, a tuple of l-values is only an r-value, not
an l-value.
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::from_pair</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">Y</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">X</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">X</span><span class="plain"> = </span><span class="functiontext">Specifications::new_UNKNOWN</span><span class="plain">(</span><span class="identifier">EMPTY_WORDING</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Y</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">Y</span><span class="plain"> = </span><span class="functiontext">Specifications::new_UNKNOWN</span><span class="plain">(</span><span class="identifier">EMPTY_WORDING</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">kX</span><span class="plain"> = </span><span class="functiontext">Specifications::to_true_kind_disambiguated</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">kY</span><span class="plain"> = </span><span class="functiontext">Specifications::to_true_kind_disambiguated</span><span class="plain">(</span><span class="identifier">Y</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">Kinds::pair_kind</span><span class="plain">(</span><span class="identifier">kX</span><span class="plain">, </span><span class="identifier">kY</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">ParseTree::new</span><span class="plain">(</span><span class="constant">CONSTANT_NT</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">spec</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain"> = </span><span class="identifier">X</span><span class="plain">; </span><span class="identifier">spec</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain"> = </span><span class="identifier">Y</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rvalues::to_pair</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">pair</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> **</span><span class="identifier">X</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> **</span><span class="identifier">Y</span><span class="plain">) {</span>
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">pair</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">;</span>
<span class="plain">*</span><span class="identifier">Y</span><span class="plain"> = </span><span class="identifier">pair</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::from_pair is used in 10/varc (<a href="10-varc.html#SP7">&#167;7</a>).</p>
<p class="endnote">The function Rvalues::to_pair is used in 12/is (<a href="12-is.html#SP7_3">&#167;7.3</a>).</p>
<p class="inwebparagraph"><a id="SP18"></a><b>&#167;18. Constant descriptions. </b>Note that whenever we change the proposition, the kind of the constant
may in principle change, since that depends on the free variable's kind
in the proposition.
</p>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Rvalues::constant_description</span><span class="plain">(</span><span class="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">, </span><span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">con</span><span class="plain"> = </span><span class="identifier">ParseTree::new_with_words</span><span class="plain">(</span><span class="constant">CONSTANT_NT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_kind_of_value</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">,</span>
<span class="identifier">Kinds::unary_construction</span><span class="plain">(</span><span class="identifier">CON_description</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">));</span>
<span class="functiontext">Rvalues::set_constant_description_proposition</span><span class="plain">(</span><span class="identifier">con</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">con</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rvalues::set_constant_description_proposition</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="reserved">pcalc_prop</span><span class="plain"> *</span><span class="identifier">prop</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">CON_description</span><span class="plain">)) {</span>
<span class="identifier">ParseTree::set_proposition</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">prop</span><span class="plain">);</span>
<span class="identifier">ParseTree::set_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">,</span>
<span class="identifier">Kinds::unary_construction</span><span class="plain">(</span><span class="identifier">CON_description</span><span class="plain">,</span>
<span class="functiontext">Calculus::Variables::infer_kind_of_variable_0</span><span class="plain">(</span><span class="identifier">prop</span><span class="plain">)));</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"set constant description proposition wrongly"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::constant_description is used in 14/ds (<a href="14-ds.html#SP1">&#167;1</a>).</p>
<p class="endnote">The function Rvalues::set_constant_description_proposition is used in 14/ds (<a href="14-ds.html#SP2">&#167;2</a>).</p>
<p class="inwebparagraph"><a id="SP19"></a><b>&#167;19. Testing. </b></p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rvalues::is_CONSTANT_construction</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_constructor</span><span class="plain"> *</span><span class="identifier">con</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">CONSTANT_NT</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">ParseTree::get_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) == </span><span class="identifier">con</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rvalues::is_CONSTANT_of_kind</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</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">CONSTANT_NT</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">ParseTree::get_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">), </span><span class="identifier">K</span><span class="plain">)))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::is_CONSTANT_construction is used in <a href="#SP18">&#167;18</a>, <a href="#SP21">&#167;21</a>, <a href="#SP23">&#167;23</a>, 9/tc (<a href="9-tc.html#SP4_5">&#167;4.5</a>), 9/ma (<a href="9-ma.html#SP3_2">&#167;3.2</a>, <a href="9-ma.html#SP3_3_18">&#167;3.3.18</a>, <a href="9-ma.html#SP3_3_25">&#167;3.3.25</a>, <a href="9-ma.html#SP3_3_41">&#167;3.3.41</a>, <a href="9-ma.html#SP3_3_41_4">&#167;3.3.41.4</a>, <a href="9-ma.html#SP3_3_41_7">&#167;3.3.41.7</a>), 9/pd (<a href="9-pd.html#SP5_11_1">&#167;5.11.1</a>), 10/cad (<a href="10-cad.html#SP3">&#167;3</a>, <a href="10-cad.html#SP5">&#167;5</a>), 11/pr (<a href="11-pr.html#SP35_2">&#167;35.2</a>), 11/sc (<a href="11-sc.html#SP3_3">&#167;3.3</a>, <a href="11-sc.html#SP3_6">&#167;3.6</a>), 11/sm (<a href="11-sm.html#SP17">&#167;17</a>, <a href="11-sm.html#SP18">&#167;18</a>), 12/dtd (<a href="12-dtd.html#SP18">&#167;18</a>), 14/sp (<a href="14-sp.html#SP3">&#167;3</a>), 14/lv (<a href="14-lv.html#SP10">&#167;10</a>), 14/ds (<a href="14-ds.html#SP1">&#167;1</a>, <a href="14-ds.html#SP2">&#167;2</a>), 14/ds2 (<a href="14-ds2.html#SP10_1_1_3_1_3">&#167;10.1.1.3.1.3</a>, <a href="14-ds2.html#SP11_9_1_1_2_1">&#167;11.9.1.1.2.1</a>, <a href="14-ds2.html#SP11_9_1_1_3_1_1">&#167;11.9.1.1.3.1.1</a>, <a href="14-ds2.html#SP11_9_1_1_5_1">&#167;11.9.1.1.5.1</a>, <a href="14-ds2.html#SP11_9_1_1_5_1_2">&#167;11.9.1.1.5.1.2</a>, <a href="14-ds2.html#SP13">&#167;13</a>, <a href="14-ds2.html#SP19_3">&#167;19.3</a>), 15/pr (<a href="15-pr.html#SP5_2">&#167;5.2</a>), 21/rl (<a href="21-rl.html#SP6">&#167;6</a>), 21/rps (<a href="21-rps.html#SP2">&#167;2</a>), 21/ac (<a href="21-ac.html#SP11">&#167;11</a>), 22/pav (<a href="22-pav.html#SP4">&#167;4</a>), 24/lv (<a href="24-lv.html#SP34">&#167;34</a>), 25/cii (<a href="25-cii.html#SP3_1_1_4_12">&#167;3.1.1.4.12</a>).</p>
<p class="endnote">The function Rvalues::is_CONSTANT_of_kind is used in <a href="#SP9">&#167;9</a>, <a href="#SP10">&#167;10</a>, <a href="#SP11">&#167;11</a>, <a href="#SP12">&#167;12</a>, 5/lp (<a href="5-lp.html#SP34_4">&#167;34.4</a>), 9/tfa (<a href="9-tfa.html#SP7_2_1">&#167;7.2.1</a>), 9/tc (<a href="9-tc.html#SP2">&#167;2</a>), 9/ma (<a href="9-ma.html#SP3_3_26_1_1">&#167;3.3.26.1.1</a>, <a href="9-ma.html#SP3_3_41_6">&#167;3.3.41.6</a>), 10/aots (<a href="10-aots.html#SP10">&#167;10</a>), 10/cad (<a href="10-cad.html#SP3">&#167;3</a>, <a href="10-cad.html#SP5">&#167;5</a>), 10/teav (<a href="10-teav.html#SP12_2">&#167;12.2</a>), 10/cap (<a href="10-cap.html#SP12_1">&#167;12.1</a>), 12/is (<a href="12-is.html#SP7_1">&#167;7.1</a>), 14/ds2 (<a href="14-ds2.html#SP17">&#167;17</a>, <a href="14-ds2.html#SP19_5_2">&#167;19.5.2</a>), 17/rs (<a href="17-rs.html#SP11">&#167;11</a>), 19/tod (<a href="19-tod.html#SP2_1">&#167;2.1</a>), 21/fao (<a href="21-fao.html#SP9">&#167;9</a>, <a href="21-fao.html#SP10">&#167;10</a>), 25/ci (<a href="25-ci.html#SP4_2">&#167;4.2</a>), 25/cii (<a href="25-cii.html#SP3_1_1_4_6">&#167;3.1.1.4.6</a>, <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#SP3_5_8_1">&#167;3.5.8.1</a>, <a href="25-cii.html#SP3_7_3">&#167;3.7.3</a>), 26/uo (<a href="26-uo.html#SP7">&#167;7</a>).</p>
<p class="inwebparagraph"><a id="SP20"></a><b>&#167;20. </b>Our most elaborate test is a finicky one, checking if two constant values
are equal at compile time &mdash; which is needed when seeing how to mesh table
continuations together, and in rare cases to help the typechecker. This
doesn't need to be especially rapid.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="identifier">COMPARE_CONSTANTS_USING</span><span class="plain">(</span><span class="identifier">DATA</span><span class="plain">, </span><span class="identifier">STRUCTURE</span><span class="plain">, </span><span class="identifier">FETCH</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">K1</span><span class="plain">) == </span><span class="identifier">DATA</span><span class="plain">) {</span>
<span class="identifier">STRUCTURE</span><span class="plain"> *</span><span class="identifier">x1</span><span class="plain"> = </span><span class="identifier">FETCH</span><span class="plain">(</span><span class="identifier">spec1</span><span class="plain">);</span>
<span class="identifier">STRUCTURE</span><span class="plain"> *</span><span class="identifier">x2</span><span class="plain"> = </span><span class="identifier">FETCH</span><span class="plain">(</span><span class="identifier">spec2</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">x1</span><span class="plain"> == </span><span class="identifier">x2</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="definitionkeyword">define</span> <span class="identifier">KCOMPARE_CONSTANTS_USING</span><span class="plain">(</span><span class="identifier">DATA</span><span class="plain">, </span><span class="identifier">STRUCTURE</span><span class="plain">, </span><span class="identifier">FETCH</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K1</span><span class="plain">, </span><span class="identifier">K_</span><span class="plain">##</span><span class="identifier">DATA</span><span class="plain">)) {</span>
<span class="identifier">STRUCTURE</span><span class="plain"> *</span><span class="identifier">x1</span><span class="plain"> = </span><span class="identifier">FETCH</span><span class="plain">(</span><span class="identifier">spec1</span><span class="plain">);</span>
<span class="identifier">STRUCTURE</span><span class="plain"> *</span><span class="identifier">x2</span><span class="plain"> = </span><span class="identifier">FETCH</span><span class="plain">(</span><span class="identifier">spec2</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">x1</span><span class="plain"> == </span><span class="identifier">x2</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="definitionkeyword">define</span> <span class="identifier">KKCOMPARE_CONSTANTS_USING</span><span class="plain">(</span><span class="identifier">DATA</span><span class="plain">, </span><span class="identifier">STRUCTURE</span><span class="plain">, </span><span class="identifier">FETCH</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">K1</span><span class="plain">, </span><span class="identifier">K_</span><span class="plain">##</span><span class="identifier">DATA</span><span class="plain">)) {</span>
<span class="identifier">STRUCTURE</span><span class="plain"> *</span><span class="identifier">x1</span><span class="plain"> = </span><span class="identifier">FETCH</span><span class="plain">(</span><span class="identifier">spec1</span><span class="plain">);</span>
<span class="identifier">STRUCTURE</span><span class="plain"> *</span><span class="identifier">x2</span><span class="plain"> = </span><span class="identifier">FETCH</span><span class="plain">(</span><span class="identifier">spec2</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">x1</span><span class="plain"> == </span><span class="identifier">x2</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="definitionkeyword">define</span> <span class="identifier">KCOMPARE_CONSTANTS</span><span class="plain">(</span><span class="identifier">DATA</span><span class="plain">, </span><span class="identifier">STRUCTURE</span><span class="plain">)</span>
<span class="identifier">KCOMPARE_CONSTANTS_USING</span><span class="plain">(</span><span class="identifier">DATA</span><span class="plain">, </span><span class="identifier">STRUCTURE</span><span class="plain">, </span><span class="identifier">Rvalues::to_</span><span class="plain">##</span><span class="identifier">STRUCTURE</span><span class="plain">)</span>
</pre>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Rvalues::compare_CONSTANT</span><span class="plain">(</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec1</span><span class="plain">, </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">spec2</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec1</span><span class="plain">, </span><span class="constant">CONSTANT_NT</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::is</span><span class="plain">(</span><span class="identifier">spec2</span><span class="plain">, </span><span class="constant">CONSTANT_NT</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K1</span><span class="plain"> = </span><span class="identifier">ParseTree::get_kind_of_value</span><span class="plain">(</span><span class="identifier">spec1</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K2</span><span class="plain"> = </span><span class="identifier">ParseTree::get_kind_of_value</span><span class="plain">(</span><span class="identifier">spec2</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">K1</span><span class="plain">, </span><span class="identifier">K2</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">K2</span><span class="plain">, </span><span class="identifier">K1</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K1</span><span class="plain">, </span><span class="identifier">K_text</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::match_perhaps_quoted</span><span class="plain">(</span>
<span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">spec1</span><span class="plain">), </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">spec2</span><span class="plain">))) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">Kinds::Behaviour::get_constant_compilation_method</span><span class="plain">(</span><span class="identifier">K1</span><span class="plain">)) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LITERAL_CCM</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::to_encoded_notation</span><span class="plain">(</span><span class="identifier">spec1</span><span class="plain">) == </span><span class="functiontext">Rvalues::to_encoded_notation</span><span class="plain">(</span><span class="identifier">spec2</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="reserved">case</span><span class="plain"> </span><span class="identifier">NAMED_CONSTANT_CCM</span><span class="plain">: {</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I1</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_instance</span><span class="plain">(</span><span class="identifier">spec1</span><span class="plain">);</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I2</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_instance</span><span class="plain">(</span><span class="identifier">spec2</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">I1</span><span class="plain"> == </span><span class="identifier">I2</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">SPECIAL_CCM</span><span class="plain">: {</span>
<span class="identifier">COMPARE_CONSTANTS_USING</span><span class="plain">(</span><span class="identifier">CON_activity</span><span class="plain">,</span><span class="reserved"> activity</span><span class="plain">, </span><span class="functiontext">Rvalues::to_activity</span><span class="plain">)</span>
<span class="identifier">KKCOMPARE_CONSTANTS_USING</span><span class="plain">(</span><span class="identifier">object</span><span class="plain">, </span><span class="reserved">instance</span><span class="plain">, </span><span class="functiontext">Rvalues::to_object_instance</span><span class="plain">)</span>
<span class="identifier">COMPARE_CONSTANTS_USING</span><span class="plain">(</span><span class="identifier">CON_phrase</span><span class="plain">, </span><span class="reserved">constant_phrase</span><span class="plain">, </span><span class="functiontext">Rvalues::to_constant_phrase</span><span class="plain">)</span>
<span class="identifier">COMPARE_CONSTANTS_USING</span><span class="plain">(</span><span class="identifier">CON_property</span><span class="plain">, </span><span class="reserved">property</span><span class="plain">, </span><span class="functiontext">Rvalues::to_property</span><span class="plain">)</span>
<span class="identifier">COMPARE_CONSTANTS_USING</span><span class="plain">(</span><span class="identifier">CON_rule</span><span class="plain">, </span><span class="reserved">rule</span><span class="plain">, </span><span class="functiontext">Rvalues::to_rule</span><span class="plain">)</span>
<span class="identifier">COMPARE_CONSTANTS_USING</span><span class="plain">(</span><span class="identifier">CON_rulebook</span><span class="plain">, </span><span class="reserved">rulebook</span><span class="plain">, </span><span class="functiontext">Rvalues::to_rulebook</span><span class="plain">)</span>
<span class="identifier">COMPARE_CONSTANTS_USING</span><span class="plain">(</span><span class="identifier">CON_table_column</span><span class="plain">, </span><span class="reserved">table_column</span><span class="plain">, </span><span class="functiontext">Rvalues::to_table_column</span><span class="plain">)</span>
<span class="identifier">KCOMPARE_CONSTANTS</span><span class="plain">(</span><span class="reserved">equation</span><span class="plain">, </span><span class="reserved">equation</span><span class="plain">)</span>
<span class="identifier">COMPARE_CONSTANTS_USING</span><span class="plain">(</span><span class="identifier">CON_relation</span><span class="plain">, </span><span class="reserved">binary_predicate</span><span class="plain">, </span><span class="functiontext">Rvalues::to_binary_predicate</span><span class="plain">)</span>
<span class="identifier">KCOMPARE_CONSTANTS</span><span class="plain">(</span><span class="reserved">rulebook_outcome</span><span class="plain">, </span><span class="reserved">named_rulebook_outcome</span><span class="plain">)</span>
<span class="identifier">KCOMPARE_CONSTANTS</span><span class="plain">(</span><span class="reserved">table</span><span class="plain">, </span><span class="reserved">table</span><span class="plain">)</span>
<span class="identifier">KCOMPARE_CONSTANTS</span><span class="plain">(</span><span class="reserved">use_option</span><span class="plain">, </span><span class="reserved">use_option</span><span class="plain">)</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="identifier">KCOMPARE_CONSTANTS</span><span class="plain">(</span><span class="identifier">action_name</span><span class="plain">, </span><span class="identifier">action_name</span><span class="plain">)</span>
<span class="identifier">KCOMPARE_CONSTANTS</span><span class="plain">(</span><span class="identifier">scene</span><span class="plain">, </span><span class="identifier">scene</span><span class="plain">)</span>
<span class="identifier">KCOMPARE_CONSTANTS</span><span class="plain">(</span><span class="identifier">understanding</span><span class="plain">, </span><span class="identifier">grammar_verb</span><span class="plain">)</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::compare_CONSTANT is used in 14/ds2 (<a href="14-ds2.html#SP11_6">&#167;11.6</a>), 16/in (<a href="16-in.html#SP19">&#167;19</a>), 16/cmw (<a href="16-cmw.html#SP1_2_2_1_1">&#167;1.2.2.1.1</a>), 19/tb (<a href="19-tb.html#SP27_1_3_1_1">&#167;27.1.3.1.1</a>), 25/cp (<a href="25-cp.html#SP5_3_5">&#167;5.3.5</a>).</p>
<p class="inwebparagraph"><a id="SP21"></a><b>&#167;21. Pretty-printing. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rvalues::write_out_in_English</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</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="reserved">switch</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">PHRASE_TO_DECIDE_VALUE_NT</span><span class="plain">: {</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">dtr</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">dtr</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"a phrase"</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">"an instruction to work out "</span><span class="plain">);</span>
<span class="identifier">Kinds::Textual::write_articled</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">dtr</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CONSTANT_NT</span><span class="plain">: {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">W</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">CON_property</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"the name of a property"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%+W"</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"a nameless "</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">dtr</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="identifier">Kinds::Textual::write</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">dtr</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::write_out_in_English is used in 14/sp (<a href="14-sp.html#SP6">&#167;6</a>).</p>
<p class="inwebparagraph"><a id="SP22"></a><b>&#167;22. </b>And for the log:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rvalues::log</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="reserved">switch</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CONSTANT_NT</span><span class="plain">: {</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_instance</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">I</span><span class="plain">) </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"(%~I)"</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">Rvalues::is_object</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">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">self_object_ANNOT</span><span class="plain">)) </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"(-self-)"</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">nothing_object_ANNOT</span><span class="plain">)) </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"(-nothing-)"</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"($O)"</span><span class="plain">, </span><span class="functiontext">Rvalues::to_instance</span><span class="plain">(</span><span class="identifier">spec</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">The function Rvalues::log is used in 7/ptu (<a href="7-ptu.html#SP17_1">&#167;17.1</a>).</p>
<p class="inwebparagraph"><a id="SP23"></a><b>&#167;23. Compilation. </b>First: clearly everything in this family evaluates, but what kind does the
result have?
</p>
<pre class="display">
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">Rvalues::to_kind</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="reserved">if</span><span class="plain"> (</span><span class="identifier">spec</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">"Rvalues::to_kind on NULL"</span><span class="plain">);</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CONSTANT_NT</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_object</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Work out the kind for a constant object</span> <span class="cwebmacronumber">23.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">CON_relation</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Work out the kind for a constant relation</span> <span class="cwebmacronumber">23.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">CON_property</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Work out the kind for a constant property name</span> <span class="cwebmacronumber">23.3</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">CON_phrase</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Work out the kind for a constant phrase</span> <span class="cwebmacronumber">23.6</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">CON_list_of</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Work out the kind for a constant list</span> <span class="cwebmacronumber">23.4</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="identifier">CON_table_column</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Work out the kind for a table column</span> <span class="cwebmacronumber">23.5</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::get_kind_of_value</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">PHRASE_TO_DECIDE_VALUE_NT</span><span class="plain">:</span>
&lt;<span class="cwebmacro">Work out the kind returned by a phrase</span> <span class="cwebmacronumber">23.7</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"unknown evaluating VALUE type"</span><span class="plain">); </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::to_kind is used in 4/am (<a href="4-am.html#SP25">&#167;25</a>), 5/lp (<a href="5-lp.html#SP34_5">&#167;34.5</a>), 11/sm (<a href="11-sm.html#SP10_4">&#167;10.4</a>), 14/sp (<a href="14-sp.html#SP1">&#167;1</a>), 14/lv (<a href="14-lv.html#SP12">&#167;12</a>), 15/ma (<a href="15-ma.html#SP8_2">&#167;8.2</a>).</p>
<p class="inwebparagraph"><a id="SP23_1"></a><b>&#167;23.1. </b>This is trickier than it looks. What kind shall we say that the constants
"nothing", "Cobbled Crawl", or "animal" have? The answer is the
narrowest we can: "nothing" comes out as "object", "Cobbled Crawl"
as "room" (a kind of object), "animal" as itself (ditto).
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Work out the kind for a constant object</span> <span class="cwebmacronumber">23.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">self_object_ANNOT</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">K_object</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">, </span><span class="constant">nothing_object_ANNOT</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">K_object</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_instance</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">I</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Instances::to_kind</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP23">&#167;23</a>.</p>
<p class="inwebparagraph"><a id="SP23_2"></a><b>&#167;23.2. </b>Not a base kind:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Work out the kind for a constant relation</span> <span class="cwebmacronumber">23.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_binary_predicate</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">BinaryPredicates::kind</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP23">&#167;23</a>.</p>
<p class="inwebparagraph"><a id="SP23_3"></a><b>&#167;23.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Work out the kind for a constant property name</span> <span class="cwebmacronumber">23.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_property</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">prn</span><span class="plain">-</span><span class="element">&gt;either_or</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">Kinds::unary_construction</span><span class="plain">(</span><span class="identifier">CON_property</span><span class="plain">, </span><span class="identifier">K_truth_state</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Kinds::unary_construction</span><span class="plain">(</span><span class="identifier">CON_property</span><span class="plain">, </span><span class="functiontext">Properties::Valued::kind</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">));</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP23">&#167;23</a>.</p>
<p class="inwebparagraph"><a id="SP23_4"></a><b>&#167;23.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Work out the kind for a constant list</span> <span class="cwebmacronumber">23.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Lists::kind_of_list_at</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">));</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP23">&#167;23</a>.</p>
<p class="inwebparagraph"><a id="SP23_5"></a><b>&#167;23.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Work out the kind for a table column</span> <span class="cwebmacronumber">23.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Kinds::unary_construction</span><span class="plain">(</span><span class="identifier">CON_table_column</span><span class="plain">,</span>
<span class="functiontext">Tables::Columns::get_kind</span><span class="plain">(</span><span class="functiontext">Rvalues::to_table_column</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">)));</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP23">&#167;23</a>.</p>
<p class="inwebparagraph"><a id="SP23_6"></a><b>&#167;23.6. </b>A timing issue here means that the kind will be vague until the second
assertion traverse:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Work out the kind for a constant phrase</span> <span class="cwebmacronumber">23.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Phrases::Constants::kind</span><span class="plain">(</span><span class="functiontext">Rvalues::to_constant_phrase</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">));</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP23">&#167;23</a>.</p>
<p class="inwebparagraph"><a id="SP23_7"></a><b>&#167;23.7. </b>This too is tricky. Some phrases to decide values are unambiguous. If
they say they are "To decide a rule: ...", then clearly the return value
will be a rule. But others are "polymorphic" &mdash; Greek for many-shaped,
but in this context, it means that the return value's kind depends on the
kinds of its arguments; addition is like this, for instance.
</p>
<p class="inwebparagraph">Compounding the problem is that we don't actually know which phrase will be
invoked &mdash; we only have a list of possibilities. All of them return values,
but those may have different kinds, and some may be polymorphic.
</p>
<p class="inwebparagraph">So what are we to do? First, we find the "deciding invocation": the first
entry in the list which has been passed by the type-checker, or if none of
them has, then the first entry of all. If the deciding invocation is of a
phrase with an unambiguous kind, then that's of course the answer. If it is
polymorphic, then we look to see if typechecking has already resolved the
difficulty by showing the result, and if so, then that's the answer. The
worst case, then, is when we have a polymorphic phrase and typechecking
hasn't yet sorted matters out &mdash; in that event we return simply "value"
as the kind, an extremely weak if certainly true answer.
</p>
<p class="inwebparagraph">We resort to returning <code class="display"><span class="extract">NULL</span></code>, an unknown kind, only when the invocation list
is empty. This should never happen except possibly after recovering from
some problem message.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Work out the kind returned by a phrase</span> <span class="cwebmacronumber">23.7</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">deciding_inv</span><span class="plain"> = </span><span class="identifier">spec</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">deciding_inv</span><span class="plain">) {</span>
<span class="reserved">phrase</span><span class="plain"> *</span><span class="identifier">ph</span><span class="plain"> = </span><span class="identifier">ParseTree::get_phrase_invoked</span><span class="plain">(</span><span class="identifier">deciding_inv</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ph</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">Phrases::TypeData::get_mor</span><span class="plain">(&amp;(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">&gt;type_data</span><span class="plain">)) == </span><span class="constant">DECIDES_VALUE_MOR</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Phrases::TypeData::return_decided_dimensionally</span><span class="plain">(&amp;(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">&gt;type_data</span><span class="plain">))) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_kind_resulting</span><span class="plain">(</span><span class="identifier">deciding_inv</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::get_kind_resulting</span><span class="plain">(</span><span class="identifier">deciding_inv</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K_value</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::get_kind_resulting</span><span class="plain">(</span><span class="identifier">deciding_inv</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">ParseTree::get_kind_resulting</span><span class="plain">(</span><span class="identifier">deciding_inv</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">Phrases::TypeData::get_return_kind</span><span class="plain">(&amp;(</span><span class="identifier">ph</span><span class="plain">-</span><span class="element">&gt;type_data</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Behaviour::definite</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">K_value</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP23">&#167;23</a>.</p>
<p class="inwebparagraph"><a id="SP24"></a><b>&#167;24. </b>And so to the code for compiling constants.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Rvalues::compile</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_found</span><span class="plain">) {</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">ParseTree::get_type</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">)) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">PHRASE_TO_DECIDE_VALUE_NT</span><span class="plain">:</span>
<span class="functiontext">Invocations::Compiler::compile_invocation_list</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">,</span>
<span class="identifier">spec_found</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">));</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CONSTANT_NT</span><span class="plain">: {</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">kind_of_constant</span><span class="plain"> = </span><span class="identifier">ParseTree::get_kind_of_value</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">ccm</span><span class="plain"> = </span><span class="identifier">Kinds::Behaviour::get_constant_compilation_method</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">);</span>
<span class="reserved">switch</span><span class="plain">(</span><span class="identifier">ccm</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NONE_CCM</span><span class="plain">: </span> <span class="comment">constant values of this kind cannot exist</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"SP: $P; kind: $u\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">spec_found</span><span class="plain">, </span><span class="identifier">kind_of_constant</span><span class="plain">);</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Tried to compile CONSTANT SP for a disallowed kind"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">LITERAL_CCM</span><span class="plain">: </span>&lt;<span class="cwebmacro">Compile a literal-compilation-mode constant</span> <span class="cwebmacronumber">24.1</span>&gt;<span class="plain">; </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">NAMED_CONSTANT_CCM</span><span class="plain">: </span>&lt;<span class="cwebmacro">Compile a quantitative-compilation-mode constant</span> <span class="cwebmacronumber">24.2</span>&gt;<span class="plain">; </span><span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">SPECIAL_CCM</span><span class="plain">: </span>&lt;<span class="cwebmacro">Compile a special-compilation-mode constant</span> <span class="cwebmacronumber">24.3</span>&gt;<span class="plain">; </span><span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Rvalues::compile is used in 14/cfs (<a href="14-cfs.html#SP7">&#167;7</a>).</p>
<p class="inwebparagraph"><a id="SP24_1"></a><b>&#167;24.1. </b>There are three basic compilation modes.
</p>
<p class="inwebparagraph">Here, the literal-parser is used to resolve the text of the SP to an integer.
I6 is typeless, of course, so it doesn't matter that this is not necessarily
a number: all that matters is that the correct integer value is compiled.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Compile a literal-compilation-mode constant</span> <span class="cwebmacronumber">24.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_int</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Holsters::data_acceptable</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">))</span>
<span class="identifier">Holsters::holster_pair</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">N</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP24">&#167;24</a>.</p>
<p class="inwebparagraph"><a id="SP24_2"></a><b>&#167;24.2. </b>Whereas here, an instance is attached.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Compile a quantitative-compilation-mode constant</span> <span class="cwebmacronumber">24.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="identifier">ParseTree::get_constant_instance</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">);</span>
<span class="reserved">if</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">Holsters::data_acceptable</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">)) {</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Instances::emitted_iname</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">N</span><span class="plain">) </span><span class="functiontext">Emit::holster</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no iname for instance"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no instance"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP24">&#167;24</a>.</p>
<p class="inwebparagraph"><a id="SP24_3"></a><b>&#167;24.3. </b>Otherwise there are just miscellaneous different things to do in different
kinds of value:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Compile a special-compilation-mode constant</span> <span class="cwebmacronumber">24.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Plugins::Call::compile_constant</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">kind_of_constant</span><span class="plain">, </span><span class="identifier">spec_found</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">) == </span><span class="identifier">CON_activity</span><span class="plain">) {</span>
<span class="reserved">activity</span><span class="plain"> *</span><span class="identifier">act</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_activity</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">);</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Activities::iname</span><span class="plain">(</span><span class="identifier">act</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain">) </span><span class="functiontext">Emit::holster</span><span class="plain">(</span><span class="identifier">VH</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="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">) == </span><span class="identifier">CON_combination</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">NC</span><span class="plain"> = 0;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">term</span><span class="plain"> = </span><span class="identifier">spec_found</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">; </span><span class="identifier">term</span><span class="plain">; </span><span class="identifier">term</span><span class="plain"> = </span><span class="identifier">term</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">) </span><span class="identifier">NC</span><span class="plain">++;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">NT</span><span class="plain"> = 0, </span><span class="identifier">downs</span><span class="plain"> = 0;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">term</span><span class="plain"> = </span><span class="identifier">spec_found</span><span class="plain">-</span><span class="element">&gt;down</span><span class="plain">; </span><span class="identifier">term</span><span class="plain">; </span><span class="identifier">term</span><span class="plain"> = </span><span class="identifier">term</span><span class="plain">-</span><span class="element">&gt;next</span><span class="plain">) {</span>
<span class="identifier">NT</span><span class="plain">++;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">NT</span><span class="plain"> &lt; </span><span class="identifier">NC</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">SEQUENTIAL_BIP</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="identifier">downs</span><span class="plain">++;</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">term</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">downs</span><span class="plain"> &gt; 0) { </span><span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">()); </span><span class="identifier">downs</span><span class="plain">--; }</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">, </span><span class="identifier">K_equation</span><span class="plain">)) {</span>
<span class="reserved">equation</span><span class="plain"> *</span><span class="identifier">eqn</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_equation</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">);</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Equations::identifier</span><span class="plain">(</span><span class="identifier">eqn</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain">) </span><span class="functiontext">Emit::holster</span><span class="plain">(</span><span class="identifier">VH</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="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">) == </span><span class="identifier">CON_description</span><span class="plain">) {</span>
<span class="functiontext">Calculus::Deferrals::compile_multiple_use_proposition</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">,</span>
<span class="identifier">spec_found</span><span class="plain">, </span><span class="identifier">Kinds::unary_construction_material</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">));</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">) == </span><span class="identifier">CON_list_of</span><span class="plain">) {</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Lists::compile_literal_list</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain">) </span><span class="functiontext">Emit::holster</span><span class="plain">(</span><span class="identifier">VH</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="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">) == </span><span class="identifier">CON_phrase</span><span class="plain">) {</span>
<span class="reserved">constant_phrase</span><span class="plain"> *</span><span class="identifier">cphr</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_constant_phrase</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">);</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Phrases::Constants::compile</span><span class="plain">(</span><span class="identifier">cphr</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain">) </span><span class="functiontext">Emit::holster</span><span class="plain">(</span><span class="identifier">VH</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="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">, </span><span class="constant">self_object_ANNOT</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Holsters::data_acceptable</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">)) {</span>
<span class="functiontext">Emit::holster</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">SELF_HL</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">, </span><span class="constant">nothing_object_ANNOT</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Holsters::data_acceptable</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">))</span>
<span class="identifier">Holsters::holster_pair</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">instance</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_instance</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">I</span><span class="plain">) {</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">Instances::emitted_iname</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">N</span><span class="plain">) </span><span class="functiontext">Emit::holster</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">N</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">NB</span><span class="plain"> = </span><span class="functiontext">Routines::Compile::line_being_compiled</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">NB</span><span class="plain">) </span><span class="functiontext">Instances::note_usage</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">NB</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">) == </span><span class="identifier">CON_property</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Compile property constants</span> <span class="cwebmacronumber">24.3.1</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">) == </span><span class="identifier">CON_relation</span><span class="plain">) {</span>
<span class="reserved">binary_predicate</span><span class="plain"> *</span><span class="identifier">bp</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_binary_predicate</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">);</span>
<span class="functiontext">BinaryPredicates::mark_as_needed</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">N</span><span class="plain"> = </span><span class="functiontext">BinaryPredicates::iname</span><span class="plain">(</span><span class="identifier">bp</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">N</span><span class="plain">) </span><span class="functiontext">Emit::holster</span><span class="plain">(</span><span class="identifier">VH</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="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">) == </span><span class="identifier">CON_rule</span><span class="plain">) {</span>
<span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_rule</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">);</span>
<span class="functiontext">Emit::holster</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="functiontext">Rules::iname</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">));</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">) == </span><span class="identifier">CON_rulebook</span><span class="plain">) {</span>
<span class="reserved">rulebook</span><span class="plain"> *</span><span class="identifier">rb</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_rulebook</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Holsters::data_acceptable</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">))</span>
<span class="identifier">Holsters::holster_pair</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">rb</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">, </span><span class="identifier">K_rulebook_outcome</span><span class="plain">)) {</span>
<span class="reserved">named_rulebook_outcome</span><span class="plain"> *</span><span class="identifier">rbno</span><span class="plain"> =</span>
<span class="functiontext">Rvalues::to_named_rulebook_outcome</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">);</span>
<span class="functiontext">Emit::holster</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">rbno</span><span class="plain">-</span><span class="element">&gt;nro_iname</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">, </span><span class="identifier">K_table</span><span class="plain">)) {</span>
<span class="reserved">table</span><span class="plain"> *</span><span class="identifier">t</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_table</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">);</span>
<span class="functiontext">Emit::holster</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="functiontext">Tables::identifier</span><span class="plain">(</span><span class="identifier">t</span><span class="plain">));</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">) == </span><span class="identifier">CON_table_column</span><span class="plain">) {</span>
<span class="reserved">table_column</span><span class="plain"> *</span><span class="identifier">tc</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_table_column</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Holsters::data_acceptable</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">))</span>
<span class="identifier">Holsters::holster_pair</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="functiontext">Tables::Columns::get_id</span><span class="plain">(</span><span class="identifier">tc</span><span class="plain">));</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">, </span><span class="identifier">K_text</span><span class="plain">)) {</span>
<span class="functiontext">Strings::compile_general</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">spec_found</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</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">kind_of_constant</span><span class="plain">, </span><span class="identifier">K_understanding</span><span class="plain">))) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::empty</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">)))</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"Text no longer available for CONSTANT/UNDERSTANDING"</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">PL::Parsing::compile_understanding</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="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">spec_found</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">Holsters::data_acceptable</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">)) {</span>
<span class="identifier">Holsters::holster_pair</span><span class="plain">(</span><span class="identifier">VH</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">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">, </span><span class="identifier">K_use_option</span><span class="plain">)) {</span>
<span class="reserved">use_option</span><span class="plain"> *</span><span class="identifier">uo</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_use_option</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Holsters::data_acceptable</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">))</span>
<span class="identifier">Holsters::holster_pair</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, (</span><span class="identifier">inter_t</span><span class="plain">) </span><span class="identifier">uo</span><span class="plain">-&gt;</span><span class="identifier">allocation_id</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">, </span><span class="identifier">K_verb</span><span class="plain">)) {</span>
<span class="identifier">verb_form</span><span class="plain"> *</span><span class="identifier">vf</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_verb_form</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">);</span>
<span class="functiontext">Emit::holster</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">Verbs::form_iname</span><span class="plain">(</span><span class="identifier">vf</span><span class="plain">));</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">kind_of_constant</span><span class="plain">, </span><span class="identifier">K_response</span><span class="plain">)) {</span>
<span class="reserved">rule</span><span class="plain"> *</span><span class="identifier">R</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_rule</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">, </span><span class="constant">response_code_ANNOT</span><span class="plain">);</span>
<span class="identifier">inter_name</span><span class="plain"> *</span><span class="identifier">iname</span><span class="plain"> = </span><span class="functiontext">Strings::response_constant_iname</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">iname</span><span class="plain">) </span><span class="functiontext">Emit::holster</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">iname</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Holsters::holster_pair</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</span>
<span class="functiontext">Rules::now_rule_needs_response</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">, </span><span class="identifier">c</span><span class="plain">, </span><span class="identifier">EMPTY_WORDING</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Kov is $u\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">kind_of_constant</span><span class="plain">);</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no special ccm provided"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP24">&#167;24</a>.</p>
<p class="inwebparagraph"><a id="SP24_3_1"></a><b>&#167;24.3.1. </b>The interesting, read "unfortunate", case is that of constant property
names. The curiosity here is that it's legal to store the nameless negation
of an either/or property in a "property" constant. This is purely so that
the following ungainly syntax works:
</p>
<blockquote>
<p>change X to not P;</p>
</blockquote>
<p class="inwebparagraph">Recall that in Inform 6 syntax, an attribute <code class="display"><span class="extract">attr</span></code> can be negated in sense
in several contexts by using a tilde: <code class="display"><span class="extract">~attr</span></code>.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Compile property constants</span> <span class="cwebmacronumber">24.3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">prn</span><span class="plain"> = </span><span class="functiontext">Rvalues::to_property</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prn</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">"PROPERTY SP with null property"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Properties::is_either_or</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">)) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">parity</span><span class="plain"> = 1;</span>
<span class="reserved">property</span><span class="plain"> *</span><span class="identifier">prn_to_eval</span><span class="plain"> = </span><span class="identifier">prn</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">negated</span><span class="plain">-</span><span class="identifier">clause</span><span class="plain">&gt;(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">spec_found</span><span class="plain">))) </span><span class="identifier">parity</span><span class="plain"> = -1;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Properties::EitherOr::stored_in_negation</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">)) {</span>
<span class="identifier">parity</span><span class="plain"> = -</span><span class="identifier">parity</span><span class="plain">;</span>
<span class="identifier">prn_to_eval</span><span class="plain"> = </span><span class="functiontext">Properties::EitherOr::get_negation</span><span class="plain">(</span><span class="identifier">prn_to_eval</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Holsters::data_acceptable</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">parity</span><span class="plain"> == 1) {</span>
<span class="functiontext">Emit::holster</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="functiontext">Properties::iname</span><span class="plain">(</span><span class="identifier">prn_to_eval</span><span class="plain">));</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Problems::Issue::sentence_problem</span><span class="plain">(</span><span class="functiontext">Task::syntax_tree</span><span class="plain">(), </span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">Untestable</span><span class="plain">),</span>
<span class="string">"this refers to an either-or property with a negative "</span>
<span class="string">"that I can't unravel'"</span><span class="plain">,</span>
<span class="string">"which normally never happens. (Are you using 'change' "</span>
<span class="string">"instead of 'now'?"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Holsters::data_acceptable</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">)) {</span>
<span class="functiontext">Emit::holster</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="functiontext">Properties::iname</span><span class="plain">(</span><span class="identifier">prn</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="#SP24_3">&#167;24.3</a>.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="14-sp.html">Back to 'Specifications'</a></li><li><a href="14-lv.html">Continue with 'Lvalues'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>