1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 16:44:21 +03:00
inform7/docs/core-module/25-cii.html
2020-04-07 01:06:09 +01:00

2982 lines
293 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>25/ciac</title>
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<nav role="navigation">
<h1><a href="../webs.html">Sources</a></h1>
<ul>
<li><a href="../compiler.html"><b>compiler tools</b></a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul>
<h2>Compiler Webs</h2>
<ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
</ul>
<h2>Inbuild Modules</h2>
<ul>
<li><a href="../inbuild-module/index.html">inbuild</a></li>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../html-module/index.html">html</a></li>
</ul>
<h2>Inform7 Modules</h2>
<ul>
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="../index-module/index.html">index</a></li>
</ul>
<h2>Inter Modules</h2>
<ul>
<li><a href="../inter-module/index.html">inter</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul>
<h2>Foundation</h2>
<ul>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of '25/cii' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Modules</a></li><li><a href="index.html">core</a></li><li><a href="index.html#25">Chapter 25: Compilation</a></li><li><b>Compile Invocations Inline</b></li></ul><p class="purpose">Here we generate Inform 6 code to execute the phrase(s) called for by an invocation list.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. CSI: Inline</a></li><li><a href="#SP3_2">&#167;3.2. Commands about kinds</a></li><li><a href="#SP3_3">&#167;3.3. Typographic commands</a></li><li><a href="#SP3_4">&#167;3.4. Label or counter commands</a></li><li><a href="#SP3_1_1_4">&#167;3.1.1.4. Token annotations</a></li><li><a href="#SP3_5">&#167;3.5. High-level commands</a></li><li><a href="#SP3_6">&#167;3.6. Miscellaneous commands</a></li><li><a href="#SP3_7">&#167;3.7. Primitive definitions</a></li><li><a href="#SP6">&#167;6. Parsing the invocation operands</a></li><li><a href="#SP8">&#167;8. I7 expression evaluation</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. CSI: Inline. </b>The new criminal forensics show. Jack "The Invoker" Flathead, lonely but
brilliant scene of crime officer, tells it like it is, and as serial killers
stalk the troubled streets of Inline, Missouri, ... Oh, very well: this is
the code which turns an inline phrase definition into I6 code. For example:
</p>
<blockquote>
<p>To adjust (N - a number): (- AdjustThis({N}, 1); -).</p>
</blockquote>
<p class="inwebparagraph">That sounds like an elementary matter of copying it out, but we need to
expand material in curly braces, according to what amounts to a
mini-language. So:
</p>
<blockquote>
<p>adjust 16;</p>
</blockquote>
<p class="inwebparagraph">would expand to
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">AdjustThis(16, 1);</span>
</pre>
<p class="inwebparagraph">The exact definition of this mini-language has been the subject of some
speculation ever since the early days of the I7 Public Beta: but the exotic
features it contains were never meant to be used anywhere except by the
Standard Rules. They may change without warning.
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">MAX_INLINE_DEFN_LENGTH</span><span class="plain"> </span><span class="constant">1024</span>
</pre>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">csi_state</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">source_location</span><span class="plain"> *</span><span class="identifier">where_from</span><span class="plain">;</span>
<span class="reserved">struct</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="reserved">struct</span><span class="plain"> </span><span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">tokens_packet</span><span class="plain"> *</span><span class="identifier">tokens</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">local_variable</span><span class="plain"> **</span><span class="identifier">my_vars</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">csi_state</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Invocations::Inline::csi_inline_outer</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">inv</span><span class="plain">, </span><span class="identifier">source_location</span><span class="plain"> *</span><span class="identifier">where_from</span><span class="plain">, </span><span class="reserved">tokens_packet</span><span class="plain"> *</span><span class="identifier">tokens</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">inv</span><span class="plain">);</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">my_vars</span><span class="plain">[10]; </span><span class="comment">the "my" variables 0 to 9</span>
&lt;<span class="cwebmacro">Start with all of the implicit my-variables unused</span> <span class="cwebmacronumber">1.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Create any new local variables explicitly called for</span> <span class="cwebmacronumber">1.2</span>&gt;<span class="plain">;</span>
<span class="reserved">csi_state</span><span class="plain"> </span><span class="identifier">CSIS</span><span class="plain">;</span>
<span class="identifier">CSIS</span><span class="plain">.</span><span class="element">where_from</span><span class="plain"> = </span><span class="identifier">where_from</span><span class="plain">;</span>
<span class="identifier">CSIS</span><span class="plain">.</span><span class="element">ph</span><span class="plain"> = </span><span class="identifier">ph</span><span class="plain">;</span>
<span class="identifier">CSIS</span><span class="plain">.</span><span class="element">inv</span><span class="plain"> = </span><span class="identifier">inv</span><span class="plain">;</span>
<span class="identifier">CSIS</span><span class="plain">.</span><span class="element">tokens</span><span class="plain"> = </span><span class="identifier">tokens</span><span class="plain">;</span>
<span class="identifier">CSIS</span><span class="plain">.</span><span class="element">my_vars</span><span class="plain"> = </span><span class="identifier">my_vars</span><span class="plain">;</span>
<span class="identifier">inter_schema</span><span class="plain"> *</span><span class="identifier">tail_schema</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Expand those into streams</span> <span class="cwebmacronumber">1.3</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Phrases::TypeData::block_follows</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">)) </span>&lt;<span class="cwebmacro">Open a code block</span> <span class="cwebmacronumber">1.4</span>&gt;
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Release any variables created inline</span> <span class="cwebmacronumber">1.5</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="identifier">inline_mor</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Invocations::Inline::csi_inline_outer is used in 25/ci (<a href="25-ci.html#SP4_1">&#167;4.1</a>).</p>
<p class="endnote">The structure csi_state is private to this section.</p>
<p class="inwebparagraph"><a id="SP1_1"></a><b>&#167;1.1. </b>Inline invocations, unlike invocations by function call, are allowed to
create new local variables. There are two ways they can do this: implicitly,
that is, from <code class="display"><span class="extract">{-my:...}</span></code> bracings in the definition, in which case the
user never knows about these hidden locals:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Start with all of the implicit my-variables unused</span> <span class="cwebmacronumber">1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;10; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">my_vars</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP1_2"></a><b>&#167;1.2. </b>...And explicitly, where the phrase typed by the user actually names the
variable(s) to be created, as here:
</p>
<blockquote>
<p>repeat with the item count running from 1 to 4:</p>
</blockquote>
<p class="inwebparagraph">where "item count" needs to be created as a number variable. (The type
checker has already done all of the work to decide what kind it has.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Create any new local variables explicitly called for</span> <span class="cwebmacronumber">1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="functiontext">Invocations::get_no_tokens</span><span class="plain">(</span><span class="identifier">inv</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">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[</span><span class="identifier">i</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">Invocations::get_token_variable_kind</span><span class="plain">(</span><span class="identifier">inv</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">K</span><span class="plain">) </span>&lt;<span class="cwebmacro">Create a local at this token</span> <span class="cwebmacronumber">1.2.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP1_2_1"></a><b>&#167;1.2.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Create a local at this token</span> <span class="cwebmacronumber">1.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="functiontext">LocalVariables::new</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">), </span><span class="identifier">K</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Phrases::TypeData::block_follows</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">) == </span><span class="constant">LOOP_BODY_BLOCK_FOLLOWS</span><span class="plain">)</span>
<span class="functiontext">Frames::Blocks::set_scope_to_block_about_to_open</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="functiontext">Frames::Blocks::set_variable_scope</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">);</span>
<span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] =</span>
<span class="functiontext">Lvalues::new_LOCAL_VARIABLE</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">), </span><span class="identifier">lvar</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Behaviour::uses_pointer_values</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)) {</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">lvar_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="constant">8</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">STORE_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">Produce::ref_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">lvar_s</span><span class="plain">);</span>
<span class="functiontext">Frames::emit_allocation</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1_2">&#167;1.2</a>.</p>
<p class="inwebparagraph"><a id="SP1_3"></a><b>&#167;1.3. </b>Most phrases don't have tail definitions, so we only open such a stream
if we have to. All phrases have heads, but no opening is needed, since the
head goes to <code class="display"><span class="extract">OUT</span></code>.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Expand those into streams</span> <span class="cwebmacronumber">1.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Invocations::Inline::csi_inline_inner</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="functiontext">Phrases::get_inter_head</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">), &amp;</span><span class="identifier">CSIS</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Phrases::get_inter_tail</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">)) </span><span class="identifier">tail_schema</span><span class="plain"> = </span><span class="functiontext">Phrases::get_inter_tail</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP1_4"></a><b>&#167;1.4. </b>Suppose there's a phrase with both head and tail. Then the tail won't appear
until much later on, when the new code block finishes. We won't live to see it;
in this routine, all we do is write the head. So we pass the tailpiece to
the code block handler, to be spliced in later on. (This is why we never close
the <code class="display"><span class="extract">TAIL</span></code> stream: that happens when the block closes.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Open a code block</span> <span class="cwebmacronumber">1.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">val</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Invocations::get_no_tokens</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">val</span><span class="plain"> = </span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[0];</span>
<span class="functiontext">Frames::Blocks::supply_val_and_stream</span><span class="plain">(</span><span class="identifier">val</span><span class="plain">, </span><span class="identifier">tail_schema</span><span class="plain">, </span><span class="identifier">CSIS</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP1_5"></a><b>&#167;1.5. </b>As we will see (in the discussion of <code class="display"><span class="extract">{-my:...}</span></code> below), any variables made
as scratch values for the invocation are deallocated as soon as we're finished,
unless a code block is opened: if it is, then they're deallocated when it ends.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Release any variables created inline</span> <span class="cwebmacronumber">1.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;10; </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">my_vars</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">])</span>
<span class="functiontext">LocalVariables::deallocate</span><span class="plain">(</span><span class="identifier">my_vars</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>We can now forget about heads and tails, and work on expanding a single
inline definition into a single stream. Often this just involves copying it,
but there are two ways to escape from that transcription: with a "bracing",
or with a fragment of Inform 7 source text inside <code class="display"><span class="extract">(+</span></code> and <code class="display"><span class="extract">+)</span></code>.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Invocations::Inline::csi_inline_inner</span><span class="plain">(</span><span class="identifier">value_holster</span><span class="plain"> *</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">inter_schema</span><span class="plain"> *</span><span class="identifier">sch</span><span class="plain">, </span><span class="reserved">csi_state</span><span class="plain"> *</span><span class="identifier">CSIS</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VH</span><span class="plain">-&gt;</span><span class="identifier">vhmode_wanted</span><span class="plain"> == </span><span class="identifier">INTER_VAL_VHMODE</span><span class="plain">) </span><span class="identifier">VH</span><span class="plain">-&gt;</span><span class="identifier">vhmode_provided</span><span class="plain"> = </span><span class="identifier">INTER_VAL_VHMODE</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">VH</span><span class="plain">-&gt;</span><span class="identifier">vhmode_provided</span><span class="plain"> = </span><span class="identifier">INTER_VOID_VHMODE</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">to_code</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">to_val</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">VH</span><span class="plain">-&gt;</span><span class="identifier">vhmode_wanted</span><span class="plain"> == </span><span class="identifier">INTER_VAL_VHMODE</span><span class="plain">) { </span><span class="identifier">to_val</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">; </span><span class="identifier">to_code</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">; }</span>
<span class="identifier">EmitInterSchemas::emit</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">sch</span><span class="plain">, </span><span class="identifier">CSIS</span><span class="plain">, </span><span class="identifier">to_code</span><span class="plain">, </span><span class="identifier">to_val</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">,</span>
<span class="plain">&amp;</span><span class="functiontext">Invocations::Inline::csi_inline_inner_inner</span><span class="plain">, &amp;</span><span class="functiontext">Invocations::Inline::compile_I7_expression_from_text</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Invocations::Inline::csi_inline_inner is used in <a href="#SP1_3">&#167;1.3</a>, 24/pb (<a href="24-pb.html#SP14">&#167;14</a>).</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Invocations::Inline::csi_inline_inner_inner</span><span class="plain">(</span><span class="identifier">value_holster</span><span class="plain"> *</span><span class="identifier">VH</span><span class="plain">,</span>
<span class="identifier">inter_schema_token</span><span class="plain"> *</span><span class="identifier">sche</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">CSIS_s</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">prim_cat</span><span class="plain">) {</span>
<span class="reserved">csi_state</span><span class="plain"> *</span><span class="identifier">CSIS</span><span class="plain"> = (</span><span class="reserved">csi_state</span><span class="plain"> *) </span><span class="identifier">CSIS_s</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">CSIS</span><span class="plain">-&gt;</span><span class="element">ph</span><span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">inv</span><span class="plain"> = </span><span class="identifier">CSIS</span><span class="plain">-&gt;</span><span class="element">inv</span><span class="plain">;</span>
<span class="reserved">tokens_packet</span><span class="plain"> *</span><span class="identifier">tokens</span><span class="plain"> = </span><span class="identifier">CSIS</span><span class="plain">-&gt;</span><span class="element">tokens</span><span class="plain">;</span>
<span class="reserved">local_variable</span><span class="plain"> **</span><span class="identifier">my_vars</span><span class="plain"> = </span><span class="identifier">CSIS</span><span class="plain">-&gt;</span><span class="identifier">my_vars</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> != </span><span class="identifier">no_ISINC</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">primitive_definition_ISINC</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Expand an entirely internal-made definition</span> <span class="cwebmacronumber">3.7</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Expand a bracing containing a kind command</span> <span class="cwebmacronumber">3.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Expand a bracing containing a typographic command</span> <span class="cwebmacronumber">3.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Expand a bracing containing a label or counter command</span> <span class="cwebmacronumber">3.4</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Expand a bracing containing a high-level command</span> <span class="cwebmacronumber">3.5</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Expand a bracing containing a miscellaneous command</span> <span class="cwebmacronumber">3.6</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">BRW</span><span class="plain"> = </span><span class="identifier">Feeds::feed_stream</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">bracing</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Expand a bracing containing natural language text</span> <span class="cwebmacronumber">3.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Invocations::Inline::csi_inline_inner_inner is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>We'll take the easier, outward-facing syntax first: the bracings which
are part of the public Inform language. There are four ways this can go:
</p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">OPTS_INSUB</span><span class="plain"> </span><span class="constant">1</span><span class="plain"> </span><span class="comment">the text "phrase options"</span>
<span class="definitionkeyword">define</span> <span class="constant">OPT_INSUB</span><span class="plain"> </span><span class="constant">2</span><span class="plain"> </span><span class="comment">the name of a specific phrase option</span>
<span class="definitionkeyword">define</span> <span class="constant">LOCAL_INSUB</span><span class="plain"> </span><span class="constant">3</span><span class="plain"> </span><span class="comment">the name of a token</span>
<span class="definitionkeyword">define</span> <span class="constant">PROBLEM_INSUB</span><span class="plain"> </span><span class="constant">4</span><span class="plain"> </span><span class="comment">the syntax was wrong, so do nothing</span>
</pre>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>Suppose we are invoking the following inline phrase definition:
</p>
<blockquote>
<p>To print (something - text) : (- print (PrintI6Text) {something}; -).</p>
</blockquote>
<p class="inwebparagraph">Here the inline definition is <code class="display"><span class="extract">"print (PrintI6Text) {something};"</span></code> and the
bracing, <code class="display"><span class="extract">{something}</span></code>, stands for something to be substituted in. This is
usually the name of one of the tokens in the phrase preamble, as it is here.
The name of any individual phrase option (valid in the phrase now being
invoked) expands to true or false according to whether it has been used;
the fixed text "phrase options" expands to the whole bitmap.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">inline</span><span class="plain">-</span><span class="identifier">substitution</span><span class="plain">&gt; ::=</span>
<span class="reserved">phrase</span><span class="plain"> </span><span class="identifier">options</span><span class="plain"> | ==&gt; </span><span class="constant">OPTS_INSUB</span>
<span class="plain">&lt;</span><span class="reserved">phrase</span><span class="plain">-</span><span class="identifier">option</span><span class="plain">&gt; | ==&gt; </span><span class="constant">OPT_INSUB</span><span class="plain">; &lt;&lt;</span><span class="identifier">opt</span><span class="plain">&gt;&gt; = </span><span class="identifier">R</span><span class="plain">[1]</span>
<span class="plain">&lt;</span><span class="identifier">name</span><span class="plain">-</span><span class="identifier">local</span><span class="plain">-</span><span class="identifier">to</span><span class="plain">-</span><span class="identifier">inline</span><span class="plain">-</span><span class="identifier">stack</span><span class="plain">-</span><span class="identifier">frame</span><span class="plain">&gt; | ==&gt; </span><span class="constant">LOCAL_INSUB</span><span class="plain">; &lt;&lt;</span><span class="identifier">local_variable:var</span><span class="plain">&gt;&gt; = </span><span class="identifier">RP</span><span class="plain">[1]</span>
<span class="plain">... ==&gt; </span>&lt;<span class="cwebmacro">Issue PM_BadInlineExpansion problem</span> <span class="cwebmacronumber">5.2</span>&gt;
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP5_1"></a><b>&#167;5.1. </b>This matches one of the token names in the preamble to the inline definition.
</p>
<pre class="display">
<span class="plain">&lt;</span><span class="identifier">name</span><span class="plain">-</span><span class="identifier">local</span><span class="plain">-</span><span class="identifier">to</span><span class="plain">-</span><span class="identifier">inline</span><span class="plain">-</span><span class="identifier">stack</span><span class="plain">-</span><span class="identifier">frame</span><span class="plain">&gt; </span><span class="identifier">internal</span><span class="plain"> {</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> =</span>
<span class="functiontext">LocalVariables::parse</span><span class="plain">(&amp;(</span><span class="identifier">ph_being_parsed</span><span class="plain">-&gt;</span><span class="element">stack_frame</span><span class="plain">), </span><span class="identifier">W</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain">) {</span>
<span class="plain">*</span><span class="identifier">XP</span><span class="plain"> = </span><span class="identifier">lvar</span><span class="plain">; </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP5_2"></a><b>&#167;5.2. </b>In my first draft of Inform, this paragraph made reference to "meddling
charlatans" and what they "deserve". I'm a better person now.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Issue PM_BadInlineExpansion problem</span> <span class="cwebmacronumber">5.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="plain">*</span><span class="identifier">X</span><span class="plain"> = </span><span class="constant">PROBLEM_INSUB</span><span class="plain">;</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">W</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_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">PM_BadInlineExpansion</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but when I looked that phrase up I found that its inline "</span>
<span class="string">"definition included the bracing {%2}. Text written in braces like this, "</span>
<span class="string">"in an inline phrase definition, should be one of the following: a name "</span>
<span class="string">"of one of the tokens in the phrase, or a phrase option, or the text "</span>
<span class="string">"'phrase options' itself. %PThe ability to write inline phrases is really "</span>
<span class="string">"intended only for the Standard Rules and a few other low-level system "</span>
<span class="string">"extensions. A good rule of thumb is: if you can define a phrase without "</span>
<span class="string">"using I6 insertions, do."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP5">&#167;5</a>.</p>
<p class="inwebparagraph"><a id="SP3_1"></a><b>&#167;3.1. </b>Acting on that:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Expand a bracing containing natural language text</span> <span class="cwebmacronumber">3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">phod_being_parsed</span><span class="plain"> = &amp;(</span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">options_data</span><span class="plain">);</span>
<span class="identifier">ph_being_parsed</span><span class="plain"> = </span><span class="identifier">ph</span><span class="plain">;</span>
<span class="plain">&lt;</span><span class="identifier">inline</span><span class="plain">-</span><span class="identifier">substitution</span><span class="plain">&gt;(</span><span class="identifier">BRW</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">current_opts</span><span class="plain"> = </span><span class="functiontext">Invocations::get_phrase_options_bitmap</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">);</span>
<span class="reserved">switch</span><span class="plain"> (&lt;&lt;</span><span class="identifier">r</span><span class="plain">&gt;&gt;) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">OPTS_INSUB:</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</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">current_opts</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="identifier">OPT_INSUB:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_opts</span><span class="plain"> &amp; &lt;&lt;</span><span class="identifier">opt</span><span class="plain">&gt;&gt;) </span><span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">1</span><span class="plain">); </span><span class="reserved">else</span><span class="plain"> </span><span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">0</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="identifier">LOCAL_INSUB:</span><span class="plain"> {</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = &lt;&lt;</span><span class="identifier">local_variable:var</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">tok</span><span class="plain"> = </span><span class="functiontext">LocalVariables::get_parameter_number</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tok</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) </span>&lt;<span class="cwebmacro">Expand a bracing containing a token name</span> <span class="cwebmacronumber">3.1.1</span>&gt;<span class="plain">;</span>
<span class="reserved">break</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="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1"></a><b>&#167;3.1.1. </b>At this point, the bracing text is the name of token number <code class="display"><span class="extract">tok</span></code>. Usually
we compile the value of that argument as drawn from the tokens packet, but
the presence of annotations can change what we do.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Expand a bracing containing a token name</span> <span class="cwebmacronumber">3.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">supplied</span><span class="plain"> = </span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[</span><span class="identifier">tok</span><span class="plain">];</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">by_value_not_reference</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">blank_out</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">reference_exists</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">require_to_be_lvalue</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="constant">BEGIN_COMPILATION_MODE</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Take account of any annotation to the inline token</span> <span class="cwebmacronumber">3.1.1.4</span>&gt;<span class="plain">;</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">kind_vars_inline</span><span class="plain">[27];</span>
&lt;<span class="cwebmacro">Work out values for the kind variables in this context</span> <span class="cwebmacronumber">3.1.1.1</span>&gt;<span class="plain">;</span>
<span class="identifier">kind</span><span class="plain"> **</span><span class="identifier">saved</span><span class="plain"> = </span><span class="functiontext">Frames::temporarily_set_kvs</span><span class="plain">(</span><span class="identifier">kind_vars_inline</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">changed</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">kind_required</span><span class="plain"> =</span>
<span class="identifier">Kinds::substitute</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">type_data</span><span class="plain">.</span><span class="element">token_sequence</span><span class="plain">[</span><span class="identifier">tok</span><span class="plain">].</span><span class="element">token_kind</span><span class="plain">,</span>
<span class="identifier">kind_vars_inline</span><span class="plain">, &amp;</span><span class="identifier">changed</span><span class="plain">);</span>
&lt;<span class="cwebmacro">If the token has to be an lvalue, reject it if it isn't</span> <span class="cwebmacronumber">3.1.1.2</span>&gt;<span class="character">;</span>
&lt;<span class="cwebmacro">Compile the token value</span> <span class="cwebmacronumber">3.1.1.3</span>&gt;<span class="plain">;</span>
<span class="functiontext">Frames::temporarily_set_kvs</span><span class="plain">(</span><span class="identifier">saved</span><span class="plain">);</span>
<span class="constant">END_COMPILATION_MODE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1">&#167;3.1</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_1"></a><b>&#167;3.1.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Work out values for the kind variables in this context</span> <span class="cwebmacronumber">3.1.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">kind_vars_inline</span><span class="plain">[0] = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=1; </span><span class="identifier">i</span><span class="plain">&lt;=26; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">kind_vars_inline</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="functiontext">Frames::get_kind_variable</span><span class="plain">(</span><span class="identifier">i</span><span class="plain">);</span>
<span class="identifier">kind_variable_declaration</span><span class="plain"> *</span><span class="identifier">kvd</span><span class="plain"> = </span><span class="identifier">ParseTree::get_kind_variable_declarations</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (; </span><span class="identifier">kvd</span><span class="plain">; </span><span class="identifier">kvd</span><span class="plain">=</span><span class="identifier">kvd</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">) </span><span class="identifier">kind_vars_inline</span><span class="plain">[</span><span class="identifier">kvd</span><span class="plain">-&gt;</span><span class="identifier">kv_number</span><span class="plain">] = </span><span class="identifier">kvd</span><span class="plain">-&gt;</span><span class="identifier">kv_value</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1_1">&#167;3.1.1</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_2"></a><b>&#167;3.1.1.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">If the token has to be an lvalue, reject it if it isn't</span> <span class="cwebmacronumber">3.1.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">require_to_be_lvalue</span><span class="plain">) {</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain"> = </span><span class="functiontext">Lvalues::get_nonlocal_variable_if_any</span><span class="plain">(</span><span class="identifier">supplied</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (((</span><span class="identifier">nlv</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">NonlocalVariables::is_constant</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">))) ||</span>
<span class="plain">(</span><span class="functiontext">ParseTreeUsage::is_lvalue</span><span class="plain">(</span><span class="identifier">supplied</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nlv</span><span class="plain">) </span><span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">nlv</span><span class="plain">-&gt;</span><span class="element">name</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Problems::quote_spec</span><span class="plain">(2, </span><span class="identifier">supplied</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_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">PM_NotAnLvalue</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but that seems to mean changing '%2', which "</span>
<span class="string">"is a constant and can't be altered."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</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="#SP3_1_1">&#167;3.1.1</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_3"></a><b>&#167;3.1.1.3. </b>The noteworthy thing here is the switch of compilation mode on text tokens.
It allows this:
</p>
<blockquote>
<p>let X be 17; write "remember [X]" to the file of Memos;</p>
</blockquote>
<p class="inwebparagraph">to work, the tricky part being that the definition being invoked is:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">FileIO_PutContents({FN}, {T}, false);</span>
</pre>
<p class="inwebparagraph">The <code class="display"><span class="extract">{T}</span></code> bracing is the text one which triggers the mode change. The effect
is to ensure that the token is compiled along with recordings being made of
the current values of any local variables mentioned in it (bearing in mind
that text includes text substitutions). This seems so obviously a good thing
that it's hard to see why it isn't on by default. Well, it would be, except
that then response text changes using "now" would go wrong:
</p>
<blockquote>
<p>now can't exit closed containers rule response (A) is "Pesky [cage].";</p>
</blockquote>
<p class="inwebparagraph">The reference to "cage" in that text is to a local variable on the stack
frame for the can't exit closed containers rule, not to the local stack frame.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Compile the token value</span> <span class="cwebmacronumber">3.1.1.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">kind_required</span><span class="plain">, </span><span class="identifier">K_text</span><span class="plain">))</span>
<span class="identifier">COMPILATION_MODE_ENTER</span><span class="plain">(</span><span class="constant">PERMIT_LOCALS_IN_TEXT_CMODE</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">by_value_not_reference</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">)</span>
<span class="identifier">COMPILATION_MODE_ENTER</span><span class="plain">(</span><span class="constant">DEREFERENCE_POINTERS_CMODE</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">by_value_not_reference</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">COMPILATION_MODE_EXIT</span><span class="plain">(</span><span class="constant">DEREFERENCE_POINTERS_CMODE</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">blank_out</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">)</span>
<span class="identifier">COMPILATION_MODE_ENTER</span><span class="plain">(</span><span class="constant">BLANK_OUT_CMODE</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">blank_out</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">COMPILATION_MODE_EXIT</span><span class="plain">(</span><span class="constant">BLANK_OUT_CMODE</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">reference_exists</span><span class="plain"> == </span><span class="identifier">TRUE</span><span class="plain">) {</span>
<span class="identifier">COMPILATION_MODE_ENTER</span><span class="plain">(</span><span class="identifier">TABLE_EXISTENCE_CMODE_ISSBM</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">reference_exists</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">)</span>
<span class="identifier">COMPILATION_MODE_EXIT</span><span class="plain">(</span><span class="identifier">TABLE_EXISTENCE_CMODE_ISSBM</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">MATCHING</span><span class="plain">, </span><span class="string">"Expanding $P into '%W' with %d, $u%s%s\n"</span><span class="plain">,</span>
<span class="identifier">supplied</span><span class="plain">, </span><span class="identifier">BRW</span><span class="plain">, </span><span class="identifier">tok</span><span class="plain">, </span><span class="identifier">kind_required</span><span class="plain">,</span>
<span class="identifier">changed</span><span class="plain">?</span><span class="string">" (after kind substitution)"</span><span class="plain">:</span><span class="string">""</span><span class="plain">,</span>
<span class="identifier">by_value_not_reference</span><span class="plain">?</span><span class="string">" (by value)"</span><span class="plain">:</span><span class="string">" (by reference)"</span><span class="plain">);</span>
<span class="functiontext">Specifications::Compiler::emit_to_kind</span><span class="plain">(</span><span class="identifier">supplied</span><span class="plain">, </span><span class="identifier">kind_required</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1_1">&#167;3.1.1</a>.</p>
<p class="inwebparagraph"><a id="SP3_2"></a><b>&#167;3.2. Commands about kinds. </b>And that's it for the general machinery, but in another sense we're only just
getting started. We now go through all of the special syntaxes which make
invocation-language so baroque.
</p>
<p class="inwebparagraph">We'll start with a suite of details about kinds:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">{-command:kind name}</span>
&lt;<span class="cwebmacrodefn">Expand a bracing containing a kind command</span> <span class="cwebmacronumber">3.2</span>&gt; =
<span class="identifier">Problems::quote_stream</span><span class="plain">(4, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">new_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "new"</span> <span class="cwebmacronumber">3.2.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">new_list_of_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "new-list-of"</span> <span class="cwebmacronumber">3.2.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">printing_routine_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "printing-routine"</span> <span class="cwebmacronumber">3.2.5</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">ranger_routine_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "ranger-routine"</span> <span class="cwebmacronumber">3.2.6</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">next_routine_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "next-routine"</span> <span class="cwebmacronumber">3.2.3</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">previous_routine_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "previous-routine"</span> <span class="cwebmacronumber">3.2.4</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">strong_kind_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "strong-kind"</span> <span class="cwebmacronumber">3.2.7</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">weak_kind_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "weak-kind"</span> <span class="cwebmacronumber">3.2.8</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_1"></a><b>&#167;3.2.1. </b>The following produces a new value of the given kind. If it's stored as a
word value, this will just be the default value, so <code class="display"><span class="extract">{-new:time}</span></code> will output
540, that being the Inform 6 representation of 9:00 AM. If it's a block value,
we compile code which creates a new value stored on the heap. This comes into
its own when kind variables are in play.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "new"</span> <span class="cwebmacronumber">3.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Invocations::Inline::parse_bracing_operand_as_kind</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">ParseTree::get_kind_variable_declarations</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Behaviour::uses_pointer_values</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)) </span><span class="functiontext">Frames::emit_allocation</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span>&lt;<span class="cwebmacro">Issue an inline no-such-kind problem</span> <span class="cwebmacronumber">3.2.1.2</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Kinds::RunTime::emit_default_value_as_val</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">EMPTY_WORDING</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Issue problem for no natural choice</span> <span class="cwebmacronumber">3.2.1.1</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2">&#167;3.2</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_1_1"></a><b>&#167;3.2.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue problem for no natural choice</span> <span class="cwebmacronumber">3.2.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(2, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_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">PM_NoNaturalDefault2</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"To achieve %1, we'd need to be able to store a default value of "</span>
<span class="string">"the kind '%2', but there's no natural choice for this."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2_1">&#167;3.2.1</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_2"></a><b>&#167;3.2.2. </b>The following complication makes lists of a given description. The inline
definition:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">LIST_OF_TY_Desc({-new:list of K}, {D}, {-strong-kind:K})</span>
</pre>
<p class="inwebparagraph">is not good enough, because it fails if the description D makes reference to
local variables (as it well may); instead we must construe D as a deferred
proposition.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "new-list-of"</span> <span class="cwebmacronumber">3.2.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Invocations::Inline::parse_bracing_operand_as_kind</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">ParseTree::get_kind_variable_declarations</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">));</span>
<span class="functiontext">Calculus::Deferrals::emit_list_of_S</span><span class="plain">(</span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[0], </span><span class="identifier">K</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2">&#167;3.2</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_3"></a><b>&#167;3.2.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "next-routine"</span> <span class="cwebmacronumber">3.2.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Invocations::Inline::parse_bracing_operand_as_kind</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">ParseTree::get_kind_variable_declarations</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">) </span><span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Kinds::Behaviour::get_inc_iname</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">));</span>
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue an inline no-such-kind problem</span> <span class="cwebmacronumber">3.2.1.2</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2">&#167;3.2</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_4"></a><b>&#167;3.2.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "previous-routine"</span> <span class="cwebmacronumber">3.2.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Invocations::Inline::parse_bracing_operand_as_kind</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">ParseTree::get_kind_variable_declarations</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">) </span><span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Kinds::Behaviour::get_dec_iname</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">));</span>
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue an inline no-such-kind problem</span> <span class="cwebmacronumber">3.2.1.2</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2">&#167;3.2</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_5"></a><b>&#167;3.2.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "printing-routine"</span> <span class="cwebmacronumber">3.2.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Invocations::Inline::parse_bracing_operand_as_kind</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">ParseTree::get_kind_variable_declarations</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">) </span><span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Kinds::Behaviour::get_iname</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">));</span>
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue an inline no-such-kind problem</span> <span class="cwebmacronumber">3.2.1.2</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2">&#167;3.2</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_6"></a><b>&#167;3.2.6. </b><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "ranger-routine"</span> <span class="cwebmacronumber">3.2.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Invocations::Inline::parse_bracing_operand_as_kind</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">ParseTree::get_kind_variable_declarations</span><span class="plain">(</span><span class="identifier">inv</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">K</span><span class="plain">, </span><span class="identifier">K_number</span><span class="plain">)) ||</span>
<span class="plain">(</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_time</span><span class="plain">)))</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">GENERATERANDOMNUMBER_HL</span><span class="plain">));</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">) </span><span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">Kinds::Behaviour::get_ranger_iname</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">));</span>
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue an inline no-such-kind problem</span> <span class="cwebmacronumber">3.2.1.2</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2">&#167;3.2</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_7"></a><b>&#167;3.2.7. </b><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "strong-kind"</span> <span class="cwebmacronumber">3.2.7</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Invocations::Inline::parse_bracing_operand_as_kind</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">ParseTree::get_kind_variable_declarations</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">) </span><span class="functiontext">Kinds::RunTime::emit_strong_id_as_val</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue an inline no-such-kind problem</span> <span class="cwebmacronumber">3.2.1.2</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2">&#167;3.2</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_8"></a><b>&#167;3.2.8. </b><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "weak-kind"</span> <span class="cwebmacronumber">3.2.8</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Invocations::Inline::parse_bracing_operand_as_kind</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">ParseTree::get_kind_variable_declarations</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">) </span><span class="functiontext">Kinds::RunTime::emit_weak_id_as_val</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue an inline no-such-kind problem</span> <span class="cwebmacronumber">3.2.1.2</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2">&#167;3.2</a>.</p>
<p class="inwebparagraph"><a id="SP3_2_1_2"></a><b>&#167;3.2.1.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue an inline no-such-kind problem</span> <span class="cwebmacronumber">3.2.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Problems::Issue::inline_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_InlineNew</span><span class="plain">), </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">owner</span><span class="plain">-&gt;</span><span class="identifier">parent_schema</span><span class="plain">-&gt;</span><span class="identifier">converted_from</span><span class="plain">,</span>
<span class="string">"I don't know any kind called '%4'."</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_2_1">&#167;3.2.1</a>, <a href="#SP3_2_3">&#167;3.2.3</a>, <a href="#SP3_2_4">&#167;3.2.4</a>, <a href="#SP3_2_5">&#167;3.2.5</a>, <a href="#SP3_2_6">&#167;3.2.6</a>, <a href="#SP3_2_7">&#167;3.2.7</a>, <a href="#SP3_2_8">&#167;3.2.8</a>, <a href="#SP3_5_8">&#167;3.5.8</a>.</p>
<p class="inwebparagraph"><a id="SP3_3"></a><b>&#167;3.3. Typographic commands. </b>These rather crude commands work on a character-by-character level in the
code we're generating.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Expand a bracing containing a typographic command</span> <span class="cwebmacronumber">3.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">backspace_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "backspace"</span> <span class="cwebmacronumber">3.3.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">erase_ISINC</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">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">open_brace_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "open-brace"</span> <span class="cwebmacronumber">3.3.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">close_brace_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "close-brace"</span> <span class="cwebmacronumber">3.3.3</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_3_1"></a><b>&#167;3.3.1. </b>The first two commands control the stream of text produced in inline
definition expansion, allowing us to back up along it. First, a single
character:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "backspace"</span> <span class="cwebmacronumber">3.3.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_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">PM_BackspaceWithdrawn</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"I attempted to compile %1 using its inline definition, "</span>
<span class="string">"but this contained the invalid annotation '{backspace}', "</span>
<span class="string">"which has been withdrawn. (Inline annotations are no longer "</span>
<span class="string">"allowed to amend the compilation stream to their left.)"</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_3">&#167;3.3</a>.</p>
<p class="inwebparagraph"><a id="SP3_3_2"></a><b>&#167;3.3.2. </b>These should never occur in well-formed inter schemas; a schema would fail
lint if they did.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "open-brace"</span> <span class="cwebmacronumber">3.3.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_3">&#167;3.3</a>.</p>
<p class="inwebparagraph"><a id="SP3_3_3"></a><b>&#167;3.3.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "close-brace"</span> <span class="cwebmacronumber">3.3.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_3">&#167;3.3</a>.</p>
<p class="inwebparagraph"><a id="SP3_4"></a><b>&#167;3.4. Label or counter commands. </b>Here we want to generate unique numbers, or uniquely named labels, on demand.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Expand a bracing containing a label or counter command</span> <span class="cwebmacronumber">3.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">label_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "label"</span> <span class="cwebmacronumber">3.4.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">counter_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "counter"</span> <span class="cwebmacronumber">3.4.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">counter_storage_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "counter-storage"</span> <span class="cwebmacronumber">3.4.3</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">counter_up_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "counter-up"</span> <span class="cwebmacronumber">3.4.4</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">counter_down_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "counter-down"</span> <span class="cwebmacronumber">3.4.5</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">counter_makes_array_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "counter-makes-array"</span> <span class="cwebmacronumber">3.4.6</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_4_1"></a><b>&#167;3.4.1. </b>We can have any number of sets of labels, each with its own base name,
which should be supplied as the argument. For example:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">{-label:pineapple}</span>
</pre>
<p class="inwebparagraph">generates the current label in the "pineapple" set. (Sets don't need to be
declared: they can be mentioned the first time they are used.) These label
names take the form <code class="display"><span class="extract">L_pineapple_0</span></code>, <code class="display"><span class="extract">L_pineapple_1</span></code>, and so on; each named
set has its own counter (0, 1, 2, ...). So this inline definition works
safely:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">jump {-label:leap}; print "Yikes! A trap!"; .{-label:leap}{-counter-up:leap};</span>
</pre>
<p class="inwebparagraph">if a little pointlessly, generating first
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">jump L_leap_0; print "Yikes! A trap!"; .L_leap_0;</span>
</pre>
<p class="inwebparagraph">and then
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">jump L_leap_1; print "Yikes! A trap!"; .L_leap_1;</span>
</pre>
<p class="inwebparagraph">and so on. The point of this is that it guarantees we won't define two labels
with identical names in the same Inform 6 routine, which would fail to compile.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "label"</span> <span class="cwebmacronumber">3.4.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">, </span><span class="string">"."</span><span class="plain">);</span>
<span class="functiontext">JumpLabels::write</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">);</span>
<span class="identifier">Produce::lab</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">Produce::reserve_label</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">L</span><span class="plain">));</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_4">&#167;3.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_4_2"></a><b>&#167;3.4.2. </b>We can also output just the numerical counter:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "counter"</span> <span class="cwebmacronumber">3.4.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</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">JumpLabels::read_counter</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">NOT_APPLICABLE</span><span class="plain">));</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_4">&#167;3.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_4_3"></a><b>&#167;3.4.3. </b>We can also output just the storage array:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "counter-storage"</span> <span class="cwebmacronumber">3.4.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">JumpLabels::storage</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">));</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_4">&#167;3.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_4_4"></a><b>&#167;3.4.4. </b>Or increment it, printing nothing:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "counter-up"</span> <span class="cwebmacronumber">3.4.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">JumpLabels::read_counter</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_4">&#167;3.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_4_5"></a><b>&#167;3.4.5. </b>Or decrement it. (Careful, though: if it decrements below zero, an enigmatic
internal error will halt Inform.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "counter-down"</span> <span class="cwebmacronumber">3.4.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">JumpLabels::read_counter</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_4">&#167;3.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_4_6"></a><b>&#167;3.4.6. </b>We can use counters for anything, not just to generate labels, and one
useful trick is to allocate storage at run-time. Invoking
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">{-counter-makes-array:pineapple}</span>
</pre>
<p class="inwebparagraph">at any time during compilation (once or many times over, it makes no
difference) causes Inform to generate an array called <code class="display"><span class="extract">I7_ST_pineapple</span></code>
guaranteed to contain one entry for each counter value reached. Thus:
</p>
<blockquote>
<p>To remember (N - a number) for later: ...</p>
</blockquote>
<p class="inwebparagraph">might be defined inline as
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">{-counter-makes-array:pineapple}I7_ST_pineapple--&gt;{-counter:pineapple} = {N};</span>
</pre>
<p class="inwebparagraph">and the effect will be to accumulate an array of numbers during compilation.
Note that the value of a counter can also be read in template language,
so with a little care we can get the final extent of the array, too. If more
than one word of storage per count is needed, try:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">{-counter-makes-array:pineapple:3}</span>
</pre>
<p class="inwebparagraph">or similar &mdash; this ensures that the array contains not fewer than three times
as many cells as the final value of the count. (If multiple invocations are
made with different numbers here, the maximum is taken.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "counter-makes-array"</span> <span class="cwebmacronumber">3.4.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">words_per_count</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand2</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">words_per_count</span><span class="plain"> = </span><span class="identifier">Str::atoi</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand2</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="functiontext">JumpLabels::allocate_counter</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">words_per_count</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_4">&#167;3.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_4"></a><b>&#167;3.1.1.4. Token annotations. </b>The next category of invocation commands takes the form of an "annotation"
slightly changing the way a token would normally be compiled, but basically
using the same machinery as if the annotation hadn't been there.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Take account of any annotation to the inline token</span> <span class="cwebmacronumber">3.1.1.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">valid_annotation</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">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">by_reference_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline annotation "by-reference"</span> <span class="cwebmacronumber">3.1.1.4.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">by_reference_blank_out_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline annotation "by-reference-blank-out"</span> <span class="cwebmacronumber">3.1.1.4.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">reference_exists_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline annotation "reference-exists"</span> <span class="cwebmacronumber">3.1.1.4.3</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">lvalue_by_reference_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline annotation "lvalue-by-reference"</span> <span class="cwebmacronumber">3.1.1.4.4</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">by_value_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline annotation "by-value"</span> <span class="cwebmacronumber">3.1.1.4.5</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">box_quotation_text_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline annotation "box-quotation-text"</span> <span class="cwebmacronumber">3.1.1.4.6</span>&gt;<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">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">try_action_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline annotation "try-action"</span> <span class="cwebmacronumber">3.1.1.4.9</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">try_action_silently_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline annotation "try-action-silently"</span> <span class="cwebmacronumber">3.1.1.4.10</span>&gt;<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">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">return_value_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline annotation "return-value"</span> <span class="cwebmacronumber">3.1.1.4.7</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">return_value_from_rule_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline annotation "return-value-from-rule"</span> <span class="cwebmacronumber">3.1.1.4.8</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">property_holds_block_value_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline annotation "property-holds-block-value"</span> <span class="cwebmacronumber">3.1.1.4.11</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">mark_event_used_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline annotation "mark-event-used"</span> <span class="cwebmacronumber">3.1.1.4.12</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> != </span><span class="identifier">no_ISINC</span><span class="plain">) &amp;&amp; (</span><span class="identifier">valid_annotation</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Throw a problem message for an invalid inline annotation</span> <span class="cwebmacronumber">3.1.1.4.13</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1_1">&#167;3.1.1</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_4_1"></a><b>&#167;3.1.1.4.1. </b>This affects only block values. When it's used, the token accepts the pointer
to the block value directly, that is, not copying the data over to a fresh
copy and using that instead. This means a definition like:
</p>
<blockquote>
<p>To zap (L - a list of numbers): (- Zap({-by-reference:L}, 10); -).</p>
</blockquote>
<p class="inwebparagraph">will call <code class="display"><span class="extract">Zap</span></code> on the actual list supplied to it. If <code class="display"><span class="extract">Zap</span></code> chooses to change
this list, the original will change.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline annotation "by-reference"</span> <span class="cwebmacronumber">3.1.1.4.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">by_value_not_reference</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">valid_annotation</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1_1_4">&#167;3.1.1.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_4_2"></a><b>&#167;3.1.1.4.2. </b>And, variedly:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline annotation "by-reference-blank-out"</span> <span class="cwebmacronumber">3.1.1.4.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">by_value_not_reference</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">valid_annotation</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">blank_out</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1_1_4">&#167;3.1.1.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_4_3"></a><b>&#167;3.1.1.4.3. </b>And, variedly:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline annotation "reference-exists"</span> <span class="cwebmacronumber">3.1.1.4.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">by_value_not_reference</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">valid_annotation</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">reference_exists</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1_1_4">&#167;3.1.1.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_4_4"></a><b>&#167;3.1.1.4.4. </b>This is a variant which checks that the reference is to an lvalue, that
is, to something which can be changed. If this weren't done, then
</p>
<blockquote>
<p>remove 2 from {1, 2, 3}</p>
</blockquote>
<p class="inwebparagraph">would compile without problem messages, though it would behave pretty oddly
at run-time.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline annotation "lvalue-by-reference"</span> <span class="cwebmacronumber">3.1.1.4.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">by_value_not_reference</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">valid_annotation</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">require_to_be_lvalue</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1_1_4">&#167;3.1.1.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_4_5"></a><b>&#167;3.1.1.4.5. </b>This is the default, so it's redundant, but clarifies definitions.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline annotation "by-value"</span> <span class="cwebmacronumber">3.1.1.4.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">by_value_not_reference</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">valid_annotation</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1_1_4">&#167;3.1.1.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_4_6"></a><b>&#167;3.1.1.4.6. </b>This is used only for the box statement in I6, which has slightly different
textual requirements than regular I6 text. We could get rid of this by making
a kind for box-quotation-text, and casting regular text to it, but honestly
having this annotation seems the smaller of the two warts.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline annotation "box-quotation-text"</span> <span class="cwebmacronumber">3.1.1.4.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<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">supplied</span><span class="plain">, </span><span class="identifier">K_text</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_spec</span><span class="plain">(2, </span><span class="identifier">supplied</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_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">PM_Misboxed</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"I attempted to compile %1, but the text '%2' supplied to be a "</span>
<span class="string">"boxed quotation wasn't a constant piece of text in double-quotes. "</span>
<span class="string">"I'm afraid that's the only sort of text allowed here."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">COMPILATION_MODE_ENTER</span><span class="plain">(</span><span class="constant">COMPILE_TEXT_TO_QUOT_CMODE</span><span class="plain">);</span>
<span class="identifier">by_value_not_reference</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
<span class="identifier">valid_annotation</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1_1_4">&#167;3.1.1.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_4_7"></a><b>&#167;3.1.1.4.7. </b>Suppose we are invoking:
</p>
<blockquote>
<p>decide on 102;</p>
</blockquote>
<p class="inwebparagraph">from the Standard Rules definition:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">return {-return-value:something};</span>
</pre>
<p class="inwebparagraph">We clearly need to police this: if the phrase is deciding a number, we need
to object to:
</p>
<blockquote>
<p>decide on "fish fingers";</p>
</blockquote>
<p class="inwebparagraph">That's one purpose of this annotation: it checks the value to see if it's
suitable to be returned. But we also might have to cast the value, or
check that it's valid at run-time. For instance, in a phrase to decide a
container, given
</p>
<blockquote>
<p>decide on the item;</p>
</blockquote>
<p class="inwebparagraph">we may need to check "item" at run-time: at compile-time we know it's an
object, but not necessarily that it's a container.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline annotation "return-value"</span> <span class="cwebmacronumber">3.1.1.4.7</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">returning_from_rule</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Handle an inline return</span> <span class="cwebmacronumber">3.1.1.4.7.1</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1_1_4">&#167;3.1.1.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_4_8"></a><b>&#167;3.1.1.4.8. </b>Exactly the same mechanism is needed for rules which produce a value, but
the problem messages are phrased differently if something goes wrong.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline annotation "return-value-from-rule"</span> <span class="cwebmacronumber">3.1.1.4.8</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">returning_from_rule</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Handle an inline return</span> <span class="cwebmacronumber">3.1.1.4.7.1</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1_1_4">&#167;3.1.1.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_4_7_1"></a><b>&#167;3.1.1.4.7.1. </b>So here's the common code:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Handle an inline return</span> <span class="cwebmacronumber">3.1.1.4.7.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">kind_needed</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">returning_from_rule</span><span class="plain">) </span><span class="identifier">kind_needed</span><span class="plain"> = </span><span class="functiontext">Rulebooks::kind_from_context</span><span class="plain">();</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">kind_needed</span><span class="plain"> = </span><span class="functiontext">Frames::get_kind_returned</span><span class="plain">();</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">kind_supplied</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">supplied</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">mor</span><span class="plain"> = </span><span class="functiontext">Phrases::TypeData::get_mor</span><span class="plain">(&amp;(</span><span class="identifier">phrase_being_compiled</span><span class="plain">-&gt;</span><span class="element">type_data</span><span class="plain">));</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">allow_me</span><span class="plain"> = </span><span class="identifier">ALWAYS_MATCH</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">kind_needed</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">kind_needed</span><span class="plain">, </span><span class="identifier">K_nil</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">))</span>
<span class="identifier">allow_me</span><span class="plain"> = </span><span class="identifier">Kinds::Compare::compatible</span><span class="plain">(</span><span class="identifier">kind_supplied</span><span class="plain">, </span><span class="identifier">kind_needed</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">mor</span><span class="plain"> == </span><span class="constant">DECIDES_CONDITION_MOR</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Kinds::Compare::eq</span><span class="plain">(</span><span class="identifier">kind_supplied</span><span class="plain">, </span><span class="identifier">K_truth_state</span><span class="plain">)))</span>
<span class="identifier">allow_me</span><span class="plain"> = </span><span class="identifier">ALWAYS_MATCH</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue a problem for returning a value when none was asked</span> <span class="cwebmacronumber">3.1.1.4.7.1.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">allow_me</span><span class="plain"> == </span><span class="identifier">ALWAYS_MATCH</span><span class="plain">) {</span>
<span class="functiontext">Specifications::Compiler::emit_to_kind</span><span class="plain">(</span><span class="identifier">supplied</span><span class="plain">, </span><span class="identifier">kind_needed</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">allow_me</span><span class="plain"> == </span><span class="identifier">SOMETIMES_MATCH</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Kinds::Compare::le</span><span class="plain">(</span><span class="identifier">kind_needed</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">))) {</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">CHECKKINDRETURNED_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Specifications::Compiler::emit_to_kind</span><span class="plain">(</span><span class="identifier">supplied</span><span class="plain">, </span><span class="identifier">kind_needed</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Kinds::RunTime::I6_classname</span><span class="plain">(</span><span class="identifier">kind_needed</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue a problem for returning a value of the wrong kind</span> <span class="cwebmacronumber">3.1.1.4.7.1.2</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain">; </span><span class="comment">that is, don't use the regular token compiler: we've done it ourselves</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1_1_4_7">&#167;3.1.1.4.7</a>, <a href="#SP3_1_1_4_8">&#167;3.1.1.4.8</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_4_7_1_1"></a><b>&#167;3.1.1.4.7.1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem for returning a value when none was asked</span> <span class="cwebmacronumber">3.1.1.4.7.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind_of</span><span class="plain">(2, </span><span class="identifier">supplied</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">returning_from_rule</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::handmade_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">PM_RuleNotAllowedOutcome</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1 as something to be a successful outcome of a rule, which "</span>
<span class="string">"has the kind %2; but this is not a rule which is allowed to have a value "</span>
<span class="string">"as its outcome."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Problems::Issue::handmade_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">PM_RedundantReturnKOV</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1 as the outcome of a phrase, %2, but in the definition of "</span>
<span class="string">"something which was not a phrase to decide a value."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1_1_4_7_1">&#167;3.1.1.4.7.1</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_4_7_1_2"></a><b>&#167;3.1.1.4.7.1.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a problem for returning a value of the wrong kind</span> <span class="cwebmacronumber">3.1.1.4.7.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(2, </span><span class="identifier">kind_supplied</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(3, </span><span class="identifier">kind_needed</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">returning_from_rule</span><span class="plain">) {</span>
<span class="identifier">Problems::Issue::handmade_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">PM_RuleOutcomeWrongKind</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1 as the outcome of a rule which produces a value, but this "</span>
<span class="string">"was the wrong kind of value: %2 rather than %3."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Problems::Issue::handmade_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">PM_ReturnWrongKind</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1 as the outcome of a phrase to decide a value, but this was "</span>
<span class="string">"the wrong kind of value: %2 rather than %3."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1_1_4_7_1">&#167;3.1.1.4.7.1</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_4_9"></a><b>&#167;3.1.1.4.9. </b><code class="display">
&lt;<span class="cwebmacrodefn">Inline annotation "try-action"</span> <span class="cwebmacronumber">3.1.1.4.9</span>&gt; =
</code></p>
<pre class="displaydefn">
<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">supplied</span><span class="plain">, </span><span class="identifier">K_stored_action</span><span class="plain">)) {</span>
<span class="identifier">action_pattern</span><span class="plain"> *</span><span class="identifier">ap</span><span class="plain"> = </span><span class="identifier">ParseTree::get_constant_action_pattern</span><span class="plain">(</span><span class="identifier">supplied</span><span class="plain">);</span>
<span class="identifier">PL::Actions::Patterns::emit_try</span><span class="plain">(</span><span class="identifier">ap</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">STORED_ACTION_TY_TRY_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_stored_action</span><span class="plain">, </span><span class="identifier">supplied</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">valid_annotation</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="comment">that is, don't use the regular token compiler: we've done it ourselves</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1_1_4">&#167;3.1.1.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_4_10"></a><b>&#167;3.1.1.4.10. </b><code class="display">
&lt;<span class="cwebmacrodefn">Inline annotation "try-action-silently"</span> <span class="cwebmacronumber">3.1.1.4.10</span>&gt; =
</code></p>
<pre class="displaydefn">
<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">supplied</span><span class="plain">, </span><span class="identifier">K_stored_action</span><span class="plain">)) {</span>
<span class="identifier">action_pattern</span><span class="plain"> *</span><span class="identifier">ap</span><span class="plain"> = </span><span class="identifier">ParseTree::get_constant_action_pattern</span><span class="plain">(</span><span class="identifier">supplied</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">PUSH_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">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">KEEP_SILENT_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_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">Produce::ref_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">KEEP_SILENT_HL</span><span class="plain">));</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">1</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">PUSH_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">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">SAY__P_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">PUSH_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">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">SAY__PC_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">CLEARPARAGRAPHING_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">1</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">PL::Actions::Patterns::emit_try</span><span class="plain">(</span><span class="identifier">ap</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">DIVIDEPARAGRAPHPOINT_HL</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">PULL_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">Produce::ref_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">SAY__PC_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">PULL_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">Produce::ref_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">SAY__P_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">ADJUSTPARAGRAPHPOINT_HL</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">PULL_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">Produce::ref_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">KEEP_SILENT_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">STORED_ACTION_TY_TRY_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Specifications::Compiler::emit_as_val</span><span class="plain">(</span><span class="identifier">K_stored_action</span><span class="plain">, </span><span class="identifier">supplied</span><span class="plain">);</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">1</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="identifier">valid_annotation</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="comment">that is, don't use the regular token compiler: we've done it ourselves</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1_1_4">&#167;3.1.1.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_4_11"></a><b>&#167;3.1.1.4.11. </b>Suppose we have a token which is a property name, and we want to know about
the kind of value the property holds. We can't simply take the kind of the
token, because that would be "property name". Instead:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline annotation "property-holds-block-value"</span> <span class="cwebmacronumber">3.1.1.4.11</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">supplied</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="functiontext">Properties::is_either_or</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">))) {</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</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">Properties::Valued::kind</span><span class="plain">(</span><span class="identifier">prn</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Behaviour::uses_pointer_values</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)) {</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">1</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1_1_4">&#167;3.1.1.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_4_12"></a><b>&#167;3.1.1.4.12. </b>This little annotation is used for the phrases about timed rule firing:
</p>
<blockquote>
<p>To (R - rule) in (t - number) turn/turns from now: ...</p>
</blockquote>
<p class="inwebparagraph">has the inline definition:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">SetTimedEvent({-mark-event-used:R}, {t}+1, 0);</span>
</pre>
<p class="inwebparagraph">The annotation makes no difference to how R is compiled, except that it
sneaks in a sanity check (R must be explicitly named and must be an event
rule), and also makes a note for indexing purposes.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline annotation "mark-event-used"</span> <span class="cwebmacronumber">3.1.1.4.12</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Rvalues::is_CONSTANT_construction</span><span class="plain">(</span><span class="identifier">supplied</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">supplied</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="functiontext">Rules::get_I7_definition</span><span class="plain">(</span><span class="identifier">R</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ph</span><span class="plain">) </span><span class="functiontext">Phrases::Timed::note_usage</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_wording</span><span class="plain">(2, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">supplied</span><span class="plain">));</span>
<span class="identifier">Problems::Issue::handmade_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">PM_NonconstantEvent</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"You wrote %1, but '%2' isn't the name of any timed event that "</span>
<span class="string">"I know of. (These need to be set up in a special way, like so - "</span>
<span class="string">"'At the time when stuff happens: ...' creates a timed event "</span>
<span class="string">"called 'stuff happens'.)"</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">}</span>
<span class="identifier">valid_annotation</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1_1_4">&#167;3.1.1.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_1_1_4_13"></a><b>&#167;3.1.1.4.13. </b><code class="display">
&lt;<span class="cwebmacrodefn">Throw a problem message for an invalid inline annotation</span> <span class="cwebmacronumber">3.1.1.4.13</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::quote_stream</span><span class="plain">(2, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">command</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_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">PM_BadInlineTag</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"I attempted to compile %1 using its inline definition, "</span>
<span class="string">"but this contained the invalid annotation '%2'."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_1_1_4">&#167;3.1.1.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_5"></a><b>&#167;3.5. High-level commands. </b>This category is intended for powerful and flexible commands, allowing for
invocations which behave like control statements in other languages. (See
also <code class="display"><span class="extract">{-block}</span></code> above, though that is syntactically a divider rather than
a command, which is why it isn't here.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Expand a bracing containing a high-level command</span> <span class="cwebmacronumber">3.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">my_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "my"</span> <span class="cwebmacronumber">3.5.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">unprotect_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "unprotect"</span> <span class="cwebmacronumber">3.5.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">copy_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "copy"</span> <span class="cwebmacronumber">3.5.4</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">initialise_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "initialise"</span> <span class="cwebmacronumber">3.5.3</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">matches_description_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "matches-description"</span> <span class="cwebmacronumber">3.5.5</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">now_matches_description_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "now-matches-description"</span> <span class="cwebmacronumber">3.5.6</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">arithmetic_operation_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "arithmetic-operation"</span> <span class="cwebmacronumber">3.5.7</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">say_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "say"</span> <span class="cwebmacronumber">3.5.8</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">show_me_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "show-me"</span> <span class="cwebmacronumber">3.5.9</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_1"></a><b>&#167;3.5.1. </b>The <code class="display"><span class="extract">{-my:name}</span></code> command creates a local variable for use in the invocation,
and then prints the variable's name. (If the same variable is created twice,
the second time it's simply printed.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "my"</span> <span class="cwebmacronumber">3.5.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">n</span><span class="plain"> = </span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="constant">0</span><span class="plain">) - </span><span class="character">'0'</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="constant">1</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">n</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">n</span><span class="plain"> &lt; </span><span class="constant">10</span><span class="plain">)) </span>&lt;<span class="cwebmacro">A single digit as the name</span> <span class="cwebmacronumber">3.5.1.1</span>&gt;
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">An Inform 6 identifier as the name</span> <span class="cwebmacronumber">3.5.1.2</span>&gt;<span class="plain">;</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">lvar_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="constant">8</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">prim_cat</span><span class="plain"> == </span><span class="identifier">REF_PRIM_CAT</span><span class="plain">) </span><span class="identifier">Produce::ref_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">lvar_s</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">lvar_s</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5">&#167;3.5</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_1_1"></a><b>&#167;3.5.1.1. </b>In the first form, we don't give an explicit name, but simply a digit from
0 to 9. We're therefore allowed to create up to 10 variables this way, and
the ones we create will be different from those made by any other invocation
(including other invocations of the same phrase). For example:
</p>
<blockquote>
<p>To Throne Room (P - phrase):</p>
</blockquote>
<p class="inwebparagraph">which is a phrase to repeat a single phrase P twice, could be defined thus:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">(- for ({-my:1}=1; {-my:1}&lt;=2; {-my:1}++) {P} -)</span>
</pre>
<p class="inwebparagraph">The variable lasts only until the end of the invocation. In general, given
this:
</p>
<blockquote>
<p>Throne Room say "Village.";</p>
</blockquote>
<blockquote>
<p>Throne Room say "Goons.";</p>
</blockquote>
<p class="inwebparagraph">...Inform will reallocate the same Inform 6 local as <code class="display"><span class="extract">{-my:1}</span></code> in each
invocation, because it safely can. But if the phrase starts a code block,
as in a more elaborate loop, then the variable lasts for the lifetime of
that code block.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">A single digit as the name</span> <span class="cwebmacronumber">3.5.1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">my_vars</span><span class="plain">[</span><span class="identifier">n</span><span class="plain">];</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">my_vars</span><span class="plain">[</span><span class="identifier">n</span><span class="plain">] = </span><span class="functiontext">LocalVariables::new</span><span class="plain">(</span><span class="identifier">EMPTY_WORDING</span><span class="plain">, </span><span class="identifier">K_number</span><span class="plain">);</span>
<span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">my_vars</span><span class="plain">[</span><span class="identifier">n</span><span class="plain">];</span>
&lt;<span class="cwebmacro">Set the kind of the my-variable</span> <span class="cwebmacronumber">3.5.1.1.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Phrases::TypeData::block_follows</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">))</span>
<span class="functiontext">Frames::Blocks::set_scope_to_block_about_to_open</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5_1">&#167;3.5.1</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_1_2"></a><b>&#167;3.5.1.2. </b>The second form is simpler. <code class="display"><span class="extract">{-my:1}</span></code> and such make locals with names like
<code class="display"><span class="extract">tmp_3</span></code>, which we have no control over. Here we get to make a local with
exactly the name we want. This can't be reallocated, of course; it's there
throughout the routine, so there's no question of setting its scope.
For example:
</p>
<blockquote>
<p>To be warned: ...</p>
</blockquote>
<p class="inwebparagraph">could be defined as:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">(- {-my:warn} = true; -)</span>
</pre>
<p class="inwebparagraph">and then
</p>
<blockquote>
<p>To decide if we have been warned: ...</p>
</blockquote>
<p class="inwebparagraph">as
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">({-my:warn})</span>
</pre>
<p class="inwebparagraph">the net result being that if either phrase is used, then <code class="display"><span class="extract">warn</span></code> becomes a
local variable. The second phrase tests if the first has been used.
</p>
<p class="inwebparagraph">Nothing, of course, stops some other invocation from using a variable of
the same name for some quite different purpose, wreaking havoc. This is
why the numbered scheme above is mostly better.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">An Inform 6 identifier as the name</span> <span class="cwebmacronumber">3.5.1.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">lvar</span><span class="plain"> = </span><span class="functiontext">LocalVariables::add_internal_local</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Set the kind of the my-variable</span> <span class="cwebmacronumber">3.5.1.1.1</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5_1">&#167;3.5.1</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_1_1_1"></a><b>&#167;3.5.1.1.1. </b>Finally, it's possible to set the I7 kind of a variable created by <code class="display"><span class="extract">{-my:...}</span></code>,
though there are hardly any circumstances where this is necessary, since I6
is typeless. But in a few cases where I7 is embedded inside I6 inside I7,
or when a block value is needed, or where we need to match against descriptions
(see below) where kind-checking comes into play, it could arise. For example:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">{-my:1:list of numbers}</span>
&lt;<span class="cwebmacrodefn">Set the kind of the my-variable</span> <span class="cwebmacronumber">3.5.1.1.1</span>&gt; =
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand2</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">)</span>
<span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Invocations::Inline::parse_bracing_operand_as_kind</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand2</span><span class="plain">,</span>
<span class="identifier">ParseTree::get_kind_variable_declarations</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">));</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">K</span><span class="plain"> = </span><span class="identifier">K_object</span><span class="plain">;</span>
<span class="functiontext">LocalVariables::set_kind</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5_1_1">&#167;3.5.1.1</a>, <a href="#SP3_5_1_2">&#167;3.5.1.2</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_2"></a><b>&#167;3.5.2. </b>Variables created by phrases are by default protected from being changed
by other phrases. So that, for example, within:
</p>
<blockquote>
<p>repeat with X running from 1 to 5:</p>
</blockquote>
<p class="inwebparagraph">it's a problem message to say something like "let X be 7". This protection
only extends to changes made at the I7 source text level, of course; our own
I6 code can do anything it likes. Protection looks like a good idea,
especially for loop counters like X, but of course it would make phrases
like:
</p>
<blockquote>
<p>let Y be 2;</p>
</blockquote>
<p class="inwebparagraph">unable to make variables, only constants. So the <code class="display"><span class="extract">{-unprotect:...}</span></code> command
lifts the protection on the variable named:
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "unprotect"</span> <span class="cwebmacronumber">3.5.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">v</span><span class="plain"> =</span>
<span class="functiontext">Invocations::Inline::parse_bracing_operand_as_identifier</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">tokens</span><span class="plain">, </span><span class="identifier">my_vars</span><span class="plain">);</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="functiontext">Lvalues::get_local_variable_if_any</span><span class="plain">(</span><span class="identifier">v</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain">) </span><span class="functiontext">LocalVariables::unprotect</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue a no-such-local problem message</span> <span class="cwebmacronumber">3.5.2.1</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5">&#167;3.5</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_3"></a><b>&#167;3.5.3. </b>Something to be careful of is that a variable created with <code class="display"><span class="extract">{-my:...}</span></code>,
or indeed a variable created explicitly by the phrase, may not begin with
contents which are typesafe for the kind you intend it to hold. Usually this
doesn't matter because it is immediately written with some value which is
indeed typesafe, and there's no problem. But if not, try using this:
<code class="display"><span class="extract">{-initialise:var:kind}</span></code> takes the named local variable and gives it the
default value for that kind. If the kind is omitted, the default is to use
the kind of the variable. For example,
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">{-my:1:time}{-initialise:1}</span>
</pre>
<p class="inwebparagraph">Note that this works only for kinds of word value, like "time". For kinds
of block value, like "list of numbers", it does nothing. This may seem odd,
but the point is that locals of that kind are automatically set to their
default values when created, so they are always typesafe anyway.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "initialise"</span> <span class="cwebmacronumber">3.5.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">V</span><span class="plain"> = </span><span class="functiontext">Invocations::Inline::parse_bracing_operand_as_identifier</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">tokens</span><span class="plain">, </span><span class="identifier">my_vars</span><span class="plain">);</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="functiontext">Lvalues::get_local_variable_if_any</span><span class="plain">(</span><span class="identifier">V</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">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand2</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">)</span>
<span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Invocations::Inline::parse_bracing_operand_as_kind</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand2</span><span class="plain">, </span><span class="identifier">ParseTree::get_kind_variable_declarations</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">));</span>
<span class="reserved">else</span>
<span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Behaviour::uses_pointer_values</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Frames::Blocks::inside_a_loop_body</span><span class="plain">()) {</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">BLKVALUECOPY_HL</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">lvar_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="constant">8</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">lvar_s</span><span class="plain">);</span>
<span class="functiontext">Kinds::RunTime::emit_default_value_as_val</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">), </span><span class="string">"value"</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">rv</span><span class="plain"> = </span><span class="identifier">FALSE</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">STORE_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">inter_symbol</span><span class="plain"> *</span><span class="identifier">lvar_s</span><span class="plain"> = </span><span class="functiontext">LocalVariables::declare_this</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">, </span><span class="constant">8</span><span class="plain">);</span>
<span class="identifier">Produce::ref_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">lvar_s</span><span class="plain">);</span>
<span class="identifier">rv</span><span class="plain"> = </span><span class="functiontext">Kinds::RunTime::emit_default_value_as_val</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">V</span><span class="plain">), </span><span class="string">"value"</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">rv</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(2, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_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">PM_NoNaturalDefault</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"To achieve %1, we'd need to be able to store a default value of "</span>
<span class="string">"the kind '%2', but there's no natural choice for this."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5">&#167;3.5</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_4"></a><b>&#167;3.5.4. </b>The <code class="display"><span class="extract">{-copy:...}</span></code> command allows us to copy the content in a token or
variable into any storage item (a local variable, a global, a table entry,
a list entry), regardless of its kind of value. For example:
</p>
<blockquote>
<p>To let (t - nonexisting variable) be (u - value) (assignment operation): ...</p>
</blockquote>
<p class="inwebparagraph">is defined inline as:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">{-unprotect:t}{-copy:t:u}</span>
</pre>
<p class="inwebparagraph">This may look superfluous: for example, in response to
</p>
<blockquote>
<p>let X be 10;</p>
</blockquote>
<p class="inwebparagraph">it generates only something like:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">tmp_0 = 10;</span>
</pre>
<p class="inwebparagraph">which could have been achieved equally well with:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">{-unprotect:t}{t} = {u};</span>
</pre>
<p class="inwebparagraph">But it makes something much more elaborate in response to, say:
</p>
<blockquote>
<p>let Y be the list of people in dark rooms;</p>
</blockquote>
<p class="inwebparagraph">where it's important to keep track of the allocation and deallocation of
dynamic lists, since Y is a block value not a word value. The point of the
<code class="display"><span class="extract">{-copy:to:from}</span></code> command is to hide all that complexity from the definer.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "copy"</span> <span class="cwebmacronumber">3.5.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">copy_form</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">to</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Find what we are copying from, to and how</span> <span class="cwebmacronumber">3.5.4.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Check that we're not copying to something the user isn't allowed to change</span> <span class="cwebmacronumber">3.5.4.2</span>&gt;<span class="plain">;</span>
<span class="reserved">pcalc_term</span><span class="plain"> </span><span class="identifier">pt1</span><span class="plain"> = </span><span class="functiontext">Calculus::Terms::new_constant</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">);</span>
<span class="reserved">pcalc_term</span><span class="plain"> </span><span class="identifier">pt2</span><span class="plain"> = </span><span class="functiontext">Calculus::Terms::new_constant</span><span class="plain">(</span><span class="identifier">from</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="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">to</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="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">);</span>
<span class="identifier">node_type_t</span><span class="plain"> </span><span class="identifier">storage_class</span><span class="plain"> = </span><span class="functiontext">Lvalues::get_storage_form</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">copy_form</span><span class="plain"> != </span><span class="constant">0</span><span class="plain">) </span>&lt;<span class="cwebmacro">Check that increment or decrement make sense</span> <span class="cwebmacronumber">3.5.4.3</span>&gt;<span class="plain">;</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">prototype</span><span class="plain"> = </span><span class="functiontext">Lvalues::interpret_store</span><span class="plain">(</span><span class="identifier">storage_class</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">copy_form</span><span class="plain">);</span>
<span class="reserved">i6_schema</span><span class="plain"> *</span><span class="identifier">sch</span><span class="plain"> = </span><span class="functiontext">Calculus::Schemas::new</span><span class="plain">(</span><span class="string">"%s;"</span><span class="plain">, </span><span class="identifier">prototype</span><span class="plain">);</span>
<span class="identifier">LOGIF</span><span class="plain">(</span><span class="identifier">KIND_CHECKING</span><span class="plain">, </span><span class="string">"Inline copy: %s\n"</span><span class="plain">, </span><span class="identifier">prototype</span><span class="plain">);</span>
<span class="constant">BEGIN_COMPILATION_MODE</span><span class="plain">;</span>
<span class="identifier">COMPILATION_MODE_ENTER</span><span class="plain">(</span><span class="constant">PERMIT_LOCALS_IN_TEXT_CMODE</span><span class="plain">);</span>
<span class="functiontext">Calculus::Schemas::emit_expand_from_terms</span><span class="plain">(</span><span class="identifier">sch</span><span class="plain">, &amp;</span><span class="identifier">pt1</span><span class="plain">, &amp;</span><span class="identifier">pt2</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="constant">END_COMPILATION_MODE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5">&#167;3.5</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_4_1"></a><b>&#167;3.5.4.1. </b>If the <code class="display"><span class="extract">from</span></code> part is prefaced with a plus sign <code class="display"><span class="extract">+</span></code>, the new value is added
to the current value rather than replacing it; if <code class="display"><span class="extract">-</span></code>, it's subtracted. For
example,
</p>
<blockquote>
<p>To increase (S - storage) by (w - value) (assignment operation): ...</p>
</blockquote>
<p class="inwebparagraph">has the inline definition <code class="display"><span class="extract">{-copy:S:+w}</span></code>. Lastly, it's also legal to write
just a <code class="display"><span class="extract">+</span></code> or <code class="display"><span class="extract">-</span></code> sign alone, which increments or decrements. Be wary here,
because <code class="display"><span class="extract">{-copy:S:+}</span></code> adds 1 to S, whereas <code class="display"><span class="extract">{-copy:S:+1}</span></code> adds the value
of the variable {-my:1} to S.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Find what we are copying from, to and how</span> <span class="cwebmacronumber">3.5.4.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">from_p</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">Str::get_first_char</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand2</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> == </span><span class="character">'+'</span><span class="plain">) { </span><span class="identifier">copy_form</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">; </span><span class="identifier">Str::copy_tail</span><span class="plain">(</span><span class="identifier">from_p</span><span class="plain">, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand2</span><span class="plain">, </span><span class="constant">1</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">c</span><span class="plain"> == </span><span class="character">'-'</span><span class="plain">) { </span><span class="identifier">copy_form</span><span class="plain"> = -1; </span><span class="identifier">Str::copy_tail</span><span class="plain">(</span><span class="identifier">from_p</span><span class="plain">, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand2</span><span class="plain">, </span><span class="constant">1</span><span class="plain">); }</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">Str::copy</span><span class="plain">(</span><span class="identifier">from_p</span><span class="plain">, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand2</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">from_p</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">copy_form</span><span class="plain"> != </span><span class="constant">0</span><span class="plain">))</span>
<span class="identifier">from</span><span class="plain"> = </span><span class="functiontext">Rvalues::from_int</span><span class="plain">(1, </span><span class="identifier">EMPTY_WORDING</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">Str::len</span><span class="plain">(</span><span class="identifier">from_p</span><span class="plain">) &gt; </span><span class="constant">0</span><span class="plain">)</span>
<span class="identifier">from</span><span class="plain"> = </span><span class="functiontext">Invocations::Inline::parse_bracing_operand_as_identifier</span><span class="plain">(</span><span class="identifier">from_p</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">tokens</span><span class="plain">, </span><span class="identifier">my_vars</span><span class="plain">);</span>
<span class="identifier">to</span><span class="plain"> = </span><span class="functiontext">Invocations::Inline::parse_bracing_operand_as_identifier</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">tokens</span><span class="plain">, </span><span class="identifier">my_vars</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">to</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">from</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) {</span>
<span class="identifier">Problems::quote_stream</span><span class="plain">(4, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">);</span>
<span class="identifier">Problems::quote_stream</span><span class="plain">(5, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand2</span><span class="plain">);</span>
<span class="functiontext">Problems::Issue::inline_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_InlineCopy</span><span class="plain">), </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">owner</span><span class="plain">-&gt;</span><span class="identifier">parent_schema</span><span class="plain">-&gt;</span><span class="identifier">converted_from</span><span class="plain">,</span>
<span class="string">"The command to {-copy:...}, which asks to copy '%5' into '%4', has "</span>
<span class="string">"gone wrong: I couldn't work those out."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">from_p</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5_4">&#167;3.5.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_4_2"></a><b>&#167;3.5.4.2. </b>Use of <code class="display"><span class="extract">{-copy:...}</span></code> will produce problem messages if the target is a protected
local variable, or a global which isn't allowed to change in play (such as the
story title).
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Check that we're not copying to something the user isn't allowed to change</span> <span class="cwebmacronumber">3.5.4.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain"> = </span><span class="functiontext">Lvalues::get_nonlocal_variable_if_any</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">nlv</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">NonlocalVariables::must_be_constant</span><span class="plain">(</span><span class="identifier">nlv</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">nlv</span><span class="plain">) </span><span class="functiontext">NonlocalVariables::warn_about_change</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">);</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="functiontext">Lvalues::get_local_variable_if_any</span><span class="plain">(</span><span class="identifier">to</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">lvar</span><span class="plain">) &amp;&amp; (</span><span class="functiontext">LocalVariables::protected</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">))) </span><span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5_4">&#167;3.5.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_4_3"></a><b>&#167;3.5.4.3. </b>One can't, for example, increment a backdrop, or a text.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Check that increment or decrement make sense</span> <span class="cwebmacronumber">3.5.4.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Behaviour::is_quasinumerical</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="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="functiontext">Problems::quote_kind</span><span class="plain">(2, </span><span class="identifier">K1</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_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">PM_CantIncrementKind</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"To achieve %1, we'd need to be able to add or subtract 1 from "</span>
<span class="string">"a value of the kind '%2', but there's no good way to do this."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5_4">&#167;3.5.4</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_5"></a><b>&#167;3.5.5. </b>The next command generates code able to test if a token in the invocation,
or an I6 variable, matches a given description &mdash; which need not be constant.
For example,
</p>
<blockquote>
<p>To say a list of (OS - description of objects): ...</p>
</blockquote>
<p class="inwebparagraph">is defined in the Standard Rules thus:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">objectloop({-my:itm} ofclass Object)</span>
<span class="plain"> if ({-matches-description:itm:OS})</span>
<span class="plain"> give itm workflag2;</span>
<span class="plain"> else</span>
<span class="plain"> give itm ~workflag2;</span>
<span class="plain">WriteListOfMarkedObjects(ENGLISH_BIT);</span>
</pre>
<p class="inwebparagraph">The whole "workflag" nonsense is Inform 6 convention from the stone age, but
the basic point here is that the loop does one thing if an object matches
the description and another if it doesn't. (In this example <code class="display"><span class="extract">itm</span></code> was a
local I6 variable and <code class="display"><span class="extract">OS</span></code> a token from the invocation, but these can be
mixed freely. Or we could use a single digit to refer to a numbered "my"
variable.)
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "matches-description"</span> <span class="cwebmacronumber">3.5.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">to_match</span><span class="plain"> =</span>
<span class="functiontext">Invocations::Inline::parse_bracing_operand_as_identifier</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand2</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">tokens</span><span class="plain">, </span><span class="identifier">my_vars</span><span class="plain">);</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">to_test</span><span class="plain"> =</span>
<span class="functiontext">Invocations::Inline::parse_bracing_operand_as_identifier</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">tokens</span><span class="plain">, </span><span class="identifier">my_vars</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">to_test</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">to_match</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) {</span>
<span class="identifier">Problems::quote_stream</span><span class="plain">(4, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">);</span>
<span class="identifier">Problems::quote_stream</span><span class="plain">(5, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand2</span><span class="plain">);</span>
<span class="functiontext">Problems::Issue::inline_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_InlineMatchesDescription</span><span class="plain">), </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">owner</span><span class="plain">-&gt;</span><span class="identifier">parent_schema</span><span class="plain">-&gt;</span><span class="identifier">converted_from</span><span class="plain">,</span>
<span class="string">"The command {-matches-description:...}, which asks to test whether "</span>
<span class="string">"'%5' is a valid description for '%4', has gone wrong: I couldn't "</span>
<span class="string">"work those out."</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">Calculus::Deferrals::emit_substitution_test</span><span class="plain">(</span><span class="identifier">to_test</span><span class="plain">, </span><span class="identifier">to_match</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5">&#167;3.5</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_6"></a><b>&#167;3.5.6. </b>This is the same, except that it compiles code to assert that the given
variable matches the given description.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "now-matches-description"</span> <span class="cwebmacronumber">3.5.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">to_test</span><span class="plain"> =</span>
<span class="functiontext">Invocations::Inline::parse_bracing_operand_as_identifier</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">tokens</span><span class="plain">, </span><span class="identifier">my_vars</span><span class="plain">);</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">to_match</span><span class="plain"> =</span>
<span class="functiontext">Invocations::Inline::parse_bracing_operand_as_identifier</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand2</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">tokens</span><span class="plain">, </span><span class="identifier">my_vars</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">to_test</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">to_match</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) {</span>
<span class="identifier">Problems::quote_stream</span><span class="plain">(4, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">);</span>
<span class="identifier">Problems::quote_stream</span><span class="plain">(5, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand2</span><span class="plain">);</span>
<span class="functiontext">Problems::Issue::inline_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_InlineNowMatchesDescription</span><span class="plain">),</span>
<span class="identifier">ph</span><span class="plain">, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">owner</span><span class="plain">-&gt;</span><span class="identifier">parent_schema</span><span class="plain">-&gt;</span><span class="identifier">converted_from</span><span class="plain">,</span>
<span class="string">"The command {-now-matches-description:...}, which asks to change "</span>
<span class="string">"'%4' so that '%5' becomes a valid description of it, has gone "</span>
<span class="string">"wrong: I couldn't work those out."</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">Calculus::Deferrals::emit_substitution_now</span><span class="plain">(</span><span class="identifier">to_test</span><span class="plain">, </span><span class="identifier">to_match</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5">&#167;3.5</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_7"></a><b>&#167;3.5.7. </b><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "arithmetic-operation"</span> <span class="cwebmacronumber">3.5.7</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">op</span><span class="plain"> = </span><span class="functiontext">Phrases::TypeData::arithmetic_operation</span><span class="plain">(</span><span class="identifier">ph</span><span class="plain">);</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">binary</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Dimensions::arithmetic_op_is_unary</span><span class="plain">(</span><span class="identifier">op</span><span class="plain">)) </span><span class="identifier">binary</span><span class="plain"> = </span><span class="identifier">FALSE</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">NULL</span><span class="plain">, *</span><span class="identifier">Y</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">KX</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">KY</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
&lt;<span class="cwebmacro">Read the operands and their kinds</span> <span class="cwebmacronumber">3.5.7.1</span>&gt;<span class="plain">;</span>
<span class="functiontext">Kinds::Compile::perform_arithmetic_emit</span><span class="plain">(</span><span class="identifier">op</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="identifier">NULL</span><span class="plain">, </span><span class="identifier">KX</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">KY</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5">&#167;3.5</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_7_1"></a><b>&#167;3.5.7.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Read the operands and their kinds</span> <span class="cwebmacronumber">3.5.7.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">X</span><span class="plain"> = </span><span class="functiontext">Invocations::Inline::parse_bracing_operand_as_identifier</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">tokens</span><span class="plain">, </span><span class="identifier">my_vars</span><span class="plain">);</span>
<span class="identifier">KX</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">binary</span><span class="plain">) {</span>
<span class="identifier">Y</span><span class="plain"> = </span><span class="functiontext">Invocations::Inline::parse_bracing_operand_as_identifier</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand2</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">tokens</span><span class="plain">, </span><span class="identifier">my_vars</span><span class="plain">);</span>
<span class="identifier">KY</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">Y</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5_7">&#167;3.5.7</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_8"></a><b>&#167;3.5.8. </b>This prints a token or variable using the correct format for its kind. The
code below optimises this so that constant text is printed directly, rather
than stored as a constant text value and printed by a call to <code class="display"><span class="extract">TEXT_TY_Say</span></code>:
this saves 2 words of memory and a function call at print time. But the
result would be the same without the optimisation.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "say"</span> <span class="cwebmacronumber">3.5.8</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">to_say</span><span class="plain"> =</span>
<span class="functiontext">Invocations::Inline::parse_bracing_operand_as_identifier</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">tokens</span><span class="plain">, </span><span class="identifier">my_vars</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">to_say</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Issue a no-such-local problem message</span> <span class="cwebmacronumber">3.5.2.1</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</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">Invocations::Inline::parse_bracing_operand_as_kind</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand2</span><span class="plain">,</span>
<span class="identifier">ParseTree::get_kind_variable_declarations</span><span class="plain">(</span><span class="identifier">inv</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">K</span><span class="plain">, </span><span class="identifier">K_text</span><span class="plain">)) </span>&lt;<span class="cwebmacro">Inline say text</span> <span class="cwebmacronumber">3.5.8.1</span>&gt;<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">K</span><span class="plain">, </span><span class="identifier">K_number</span><span class="plain">)) </span>&lt;<span class="cwebmacro">Inline say number</span> <span class="cwebmacronumber">3.5.8.2</span>&gt;<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">K</span><span class="plain">, </span><span class="identifier">K_unicode_character</span><span class="plain">)) </span>&lt;<span class="cwebmacro">Inline say unicode character</span> <span class="cwebmacronumber">3.5.8.3</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">K</span><span class="plain">) {</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">Kinds::Behaviour::get_iname</span><span class="plain">(</span><span class="identifier">K</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="constant">BEGIN_COMPILATION_MODE</span><span class="plain">;</span>
<span class="identifier">COMPILATION_MODE_EXIT</span><span class="plain">(</span><span class="constant">DEREFERENCE_POINTERS_CMODE</span><span class="plain">);</span>
<span class="functiontext">Specifications::Compiler::emit_to_kind</span><span class="plain">(</span><span class="identifier">to_say</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="constant">END_COMPILATION_MODE</span><span class="plain">;</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span>&lt;<span class="cwebmacro">Issue an inline no-such-kind problem</span> <span class="cwebmacronumber">3.2.1.2</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5">&#167;3.5</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_8_1"></a><b>&#167;3.5.8.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Inline say text</span> <span class="cwebmacronumber">3.5.8.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">SW</span><span class="plain"> = </span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">to_say</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">to_say</span><span class="plain">, </span><span class="identifier">K_text</span><span class="plain">)) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Wordings::length</span><span class="plain">(</span><span class="identifier">SW</span><span class="plain">) == </span><span class="constant">1</span><span class="plain">) &amp;&amp;</span>
<span class="plain">(</span><span class="identifier">Vocabulary::test_flags</span><span class="plain">(</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">SW</span><span class="plain">), </span><span class="identifier">TEXTWITHSUBS_MC</span><span class="plain">) == </span><span class="identifier">FALSE</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">PRINT_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">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">);</span>
<span class="functiontext">CompiledText::from_wide_string_for_emission</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">Lexer::word_text</span><span class="plain">(</span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">SW</span><span class="plain">)));</span>
<span class="identifier">Produce::val_text</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">T</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">to_say</span><span class="plain">);</span>
<span class="constant">BEGIN_COMPILATION_MODE</span><span class="plain">;</span>
<span class="identifier">COMPILATION_MODE_EXIT</span><span class="plain">(</span><span class="constant">DEREFERENCE_POINTERS_CMODE</span><span class="plain">);</span>
<span class="identifier">Produce::inv_call_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">Kinds::Behaviour::get_iname</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">));</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">Specifications::Compiler::emit_to_kind</span><span class="plain">(</span><span class="identifier">to_say</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="constant">END_COMPILATION_MODE</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5_8">&#167;3.5.8</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_8_2"></a><b>&#167;3.5.8.2. </b>Numbers are also handled directly...
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline say number</span> <span class="cwebmacronumber">3.5.8.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">PRINTNUMBER_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">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_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">Produce::ref_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">SAY__N_HL</span><span class="plain">));</span>
<span class="functiontext">Specifications::Compiler::emit_to_kind</span><span class="plain">(</span><span class="identifier">to_say</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5_8">&#167;3.5.8</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_8_3"></a><b>&#167;3.5.8.3. </b>And similarly for Unicode characters. It would be tidier to abstract this
with a function call, but it would cost a function call.
</p>
<p class="inwebparagraph">Note that emitting a Unicode character requires different code on the Z-machine
to Glulx; we have to handle this within I6 conditional compilation blocks
because neither syntax will compile when I6 is compiling for the other VM.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline say unicode character</span> <span class="cwebmacronumber">3.5.8.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">STORE_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">Produce::ref_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">UNICODE_TEMP_HL</span><span class="plain">));</span>
<span class="functiontext">Specifications::Compiler::emit_to_kind</span><span class="plain">(</span><span class="identifier">to_say</span><span class="plain">, </span><span class="identifier">K</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">TargetVMs::is_16_bit</span><span class="plain">(</span><span class="functiontext">Task::vm</span><span class="plain">())) {</span>
<span class="identifier">Produce::inv_assembly</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">I</span><span class="string">"@print_unicode"</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">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">UNICODE_TEMP_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Produce::inv_assembly</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">I</span><span class="string">"@streamunichar"</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">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">UNICODE_TEMP_HL</span><span class="plain">));</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5_8">&#167;3.5.8</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_9"></a><b>&#167;3.5.9. </b>This is for debugging purposes only: it does the equivalent of the "showme"
phrase applied to the named variable.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "show-me"</span> <span class="cwebmacronumber">3.5.9</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">to_show</span><span class="plain"> =</span>
<span class="functiontext">Invocations::Inline::parse_bracing_operand_as_identifier</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">tokens</span><span class="plain">, </span><span class="identifier">my_vars</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">to_show</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Issue a no-such-local problem message</span> <span class="cwebmacronumber">3.5.2.1</span>&gt;<span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="constant">BEGIN_COMPILATION_MODE</span><span class="plain">;</span>
<span class="identifier">COMPILATION_MODE_EXIT</span><span class="plain">(</span><span class="constant">DEREFERENCE_POINTERS_CMODE</span><span class="plain">);</span>
<span class="identifier">Produce::inv_primitive</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">IFDEBUG_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">Produce::code</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::down</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="functiontext">PL::Parsing::TestScripts::emit_showme</span><span class="plain">(</span><span class="identifier">to_show</span><span class="plain">);</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="constant">END_COMPILATION_MODE</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5">&#167;3.5</a>.</p>
<p class="inwebparagraph"><a id="SP3_6"></a><b>&#167;3.6. Miscellaneous commands. </b>These really have nothing in common, except that each can be used only in
very special circumstances.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Expand a bracing containing a miscellaneous command</span> <span class="cwebmacronumber">3.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">segment_count_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "segment-count"</span> <span class="cwebmacronumber">3.6.1</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">final_segment_marker_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "final-segment-marker"</span> <span class="cwebmacronumber">3.6.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">list_together_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "list-together"</span> <span class="cwebmacronumber">3.6.3</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">rescale_ISINC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Inline command "rescale"</span> <span class="cwebmacronumber">3.6.4</span>&gt;<span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_6_1"></a><b>&#167;3.6.1. </b>These two are publicly documented, and have to do with multiple-segment
"say" phrases.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "segment-count"</span> <span class="cwebmacronumber">3.6.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</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">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="constant">ssp_segment_count_ANNOT</span><span class="plain">));</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_6">&#167;3.6</a>.</p>
<p class="inwebparagraph"><a id="SP3_6_2"></a><b>&#167;3.6.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "final-segment-marker"</span> <span class="cwebmacronumber">3.6.2</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">inv</span><span class="plain">, </span><span class="constant">ssp_closing_segment_wn_ANNOT</span><span class="plain">) == -1) {</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Hierarchy::find</span><span class="plain">(</span><span class="constant">NULL_HL</span><span class="plain">));</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="string">"%~W"</span><span class="plain">, </span><span class="identifier">Wordings::one_word</span><span class="plain">(</span><span class="identifier">ParseTree::int_annotation</span><span class="plain">(</span><span class="identifier">inv</span><span class="plain">, </span><span class="constant">ssp_closing_segment_wn_ANNOT</span><span class="plain">)));</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">T_s</span><span class="plain"> = </span><span class="identifier">EmitInterSchemas::find_identifier_text</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="identifier">Produce::val_symbol</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">T_s</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_6">&#167;3.6</a>.</p>
<p class="inwebparagraph"><a id="SP3_6_3"></a><b>&#167;3.6.3. </b>This is a shim for an old Inform 6 library feature. It's used only to define
the "group... together" phrases.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "list-together"</span> <span class="cwebmacronumber">3.6.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_subcommand</span><span class="plain"> == </span><span class="identifier">unarticled_ISINSC</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">ListTogether::new</span><span class="plain">(</span><span class="identifier">FALSE</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">iname</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">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_subcommand</span><span class="plain"> == </span><span class="identifier">articled_ISINSC</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">ListTogether::new</span><span class="plain">(</span><span class="identifier">TRUE</span><span class="plain">);</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="identifier">iname</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Problems::Issue::inline_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_InlineListTogether</span><span class="plain">),</span>
<span class="identifier">ph</span><span class="plain">, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">owner</span><span class="plain">-&gt;</span><span class="identifier">parent_schema</span><span class="plain">-&gt;</span><span class="identifier">converted_from</span><span class="plain">,</span>
<span class="string">"The only legal forms here are {-list-together:articled} and "</span>
<span class="string">"{-list-together:unarticled}."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_6">&#167;3.6</a>.</p>
<p class="inwebparagraph"><a id="SP3_6_4"></a><b>&#167;3.6.4. </b>This exists to manage scaled arithmetic, and should only be used for the
mathematical definitions in the Standard Rules.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Inline command "rescale"</span> <span class="cwebmacronumber">3.6.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_source</span><span class="plain">(1, </span><span class="identifier">current_sentence</span><span class="plain">);</span>
<span class="identifier">Problems::Issue::handmade_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">PM_RescaleWithdrawn</span><span class="plain">));</span>
<span class="identifier">Problems::issue_problem_segment</span><span class="plain">(</span>
<span class="string">"I attempted to compile %1 using its inline definition, "</span>
<span class="string">"but this contained the invalid annotation '{-rescale:...}', "</span>
<span class="string">"which has been withdrawn."</span><span class="plain">);</span>
<span class="identifier">Problems::issue_problem_end</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_6">&#167;3.6</a>.</p>
<p class="inwebparagraph"><a id="SP3_7"></a><b>&#167;3.7. Primitive definitions. </b>Some phrases are just too complicated to express in invocation language,
especially those involving complicated linguistic propositions. For example:
</p>
<blockquote>
<p>To decide which arithmetic value is total (p - arithmetic value valued property) of (S - description of values): ...</p>
</blockquote>
<p class="inwebparagraph">has the inline definition:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">(- {-primitive-definition:total-of} -).</span>
&lt;<span class="cwebmacrodefn">Expand an entirely internal-made definition</span> <span class="cwebmacronumber">3.7</span>&gt; =
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_subcommand</span><span class="plain"> == </span><span class="identifier">repeat_through_ISINSC</span><span class="plain">) {</span>
<span class="functiontext">Calculus::Deferrals::emit_repeat_through_domain_S</span><span class="plain">(</span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[1],</span>
<span class="functiontext">Lvalues::get_local_variable_if_any</span><span class="plain">(</span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[0]));</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">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_subcommand</span><span class="plain"> == </span><span class="identifier">repeat_through_list_ISINSC</span><span class="plain">) {</span>
<span class="functiontext">Calculus::Deferrals::emit_loop_over_list_S</span><span class="plain">(</span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[1],</span>
<span class="functiontext">Lvalues::get_local_variable_if_any</span><span class="plain">(</span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[0]));</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">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_subcommand</span><span class="plain"> == </span><span class="identifier">number_of_ISINSC</span><span class="plain">) {</span>
<span class="functiontext">Calculus::Deferrals::emit_number_of_S</span><span class="plain">(</span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[0]);</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">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_subcommand</span><span class="plain"> == </span><span class="identifier">random_of_ISINSC</span><span class="plain">) {</span>
<span class="functiontext">Calculus::Deferrals::emit_random_of_S</span><span class="plain">(</span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[0]);</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">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_subcommand</span><span class="plain"> == </span><span class="identifier">total_of_ISINSC</span><span class="plain">) {</span>
<span class="functiontext">Calculus::Deferrals::emit_total_of_S</span><span class="plain">(</span>
<span class="functiontext">Rvalues::to_property</span><span class="plain">(</span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[0]), </span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[1]);</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">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_subcommand</span><span class="plain"> == </span><span class="identifier">extremal_ISINSC</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">extremal_property_sign</span><span class="plain"> != </span><span class="constant">MEASURE_T_EXACTLY</span><span class="plain">) &amp;&amp; (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">extremal_property</span><span class="plain">)) {</span>
<span class="functiontext">Calculus::Deferrals::emit_extremal_of_S</span><span class="plain">(</span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[0],</span>
<span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">extremal_property</span><span class="plain">, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">extremal_property_sign</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span>
<span class="functiontext">Problems::Issue::inline_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_InlineExtremal</span><span class="plain">),</span>
<span class="identifier">ph</span><span class="plain">, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">owner</span><span class="plain">-&gt;</span><span class="identifier">parent_schema</span><span class="plain">-&gt;</span><span class="identifier">converted_from</span><span class="plain">,</span>
<span class="string">"In the '{-primitive-definition:extremal...}' command, there "</span>
<span class="string">"should be a '&lt;' or '&gt;' sign then the name of a property."</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">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_subcommand</span><span class="plain"> == </span><span class="identifier">function_application_ISINSC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Primitive "function-application"</span> <span class="cwebmacronumber">3.7.1</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_subcommand</span><span class="plain"> == </span><span class="identifier">description_application_ISINSC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Primitive "description-application"</span> <span class="cwebmacronumber">3.7.2</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_subcommand</span><span class="plain"> == </span><span class="identifier">solve_equation_ISINSC</span><span class="plain">) </span>&lt;<span class="cwebmacro">Primitive "solve-equation"</span> <span class="cwebmacronumber">3.7.3</span>&gt;
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_subcommand</span><span class="plain"> == </span><span class="identifier">switch_ISINSC</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">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_subcommand</span><span class="plain"> == </span><span class="identifier">break_ISINSC</span><span class="plain">) </span><span class="functiontext">Frames::Blocks::emit_break</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">sche</span><span class="plain">-&gt;</span><span class="identifier">inline_subcommand</span><span class="plain"> == </span><span class="identifier">verbose_checking_ISINSC</span><span class="plain">) {</span>
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">what</span><span class="plain"> = </span><span class="identifier">L</span><span class="string">""</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">tokens_count</span><span class="plain"> &gt; </span><span class="constant">0</span><span class="plain">) {</span>
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">aspect</span><span class="plain"> = </span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[0];</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Wordings::nonempty</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">aspect</span><span class="plain">))) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">aw1</span><span class="plain"> = </span><span class="identifier">Wordings::first_wn</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">aspect</span><span class="plain">));</span>
<span class="identifier">Word::dequote</span><span class="plain">(</span><span class="identifier">aw1</span><span class="plain">);</span>
<span class="identifier">what</span><span class="plain"> = </span><span class="identifier">Lexer::word_text</span><span class="plain">(</span><span class="identifier">aw1</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="functiontext">Dash::tracing_phrases</span><span class="plain">(</span><span class="identifier">what</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">Problems::quote_stream</span><span class="plain">(4, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">);</span>
<span class="functiontext">Problems::Issue::inline_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_InlinePrimitive</span><span class="plain">), </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">owner</span><span class="plain">-&gt;</span><span class="identifier">parent_schema</span><span class="plain">-&gt;</span><span class="identifier">converted_from</span><span class="plain">,</span>
<span class="string">"I don't know any primitive definition called '%4'."</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP3_7_1"></a><b>&#167;3.7.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Primitive "function-application"</span> <span class="cwebmacronumber">3.7.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain"> = </span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[0];</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">fn_kind</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">X</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">Y</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::get_construct</span><span class="plain">(</span><span class="identifier">fn_kind</span><span class="plain">) != </span><span class="identifier">CON_phrase</span><span class="plain">) {</span>
<span class="functiontext">Problems::quote_spec</span><span class="plain">(4, </span><span class="identifier">fn</span><span class="plain">);</span>
<span class="functiontext">Problems::Issue::inline_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_InlineFunctionApplication</span><span class="plain">),</span>
<span class="identifier">ph</span><span class="plain">, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">owner</span><span class="plain">-&gt;</span><span class="identifier">parent_schema</span><span class="plain">-&gt;</span><span class="identifier">converted_from</span><span class="plain">,</span>
<span class="string">"A function application only makes sense if the first token, "</span>
<span class="string">"'%4', is a phrase: here it isn't."</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">Kinds::binary_construction_material</span><span class="plain">(</span><span class="identifier">fn_kind</span><span class="plain">, &amp;</span><span class="identifier">X</span><span class="plain">, &amp;</span><span class="identifier">Y</span><span class="plain">);</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=1; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">tokens_count</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">-1] = </span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">];</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">head</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">, *</span><span class="identifier">tail</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">Kinds::binary_construction_material</span><span class="plain">(</span><span class="identifier">X</span><span class="plain">, &amp;</span><span class="identifier">head</span><span class="plain">, &amp;</span><span class="identifier">tail</span><span class="plain">);</span>
<span class="identifier">X</span><span class="plain"> = </span><span class="identifier">tail</span><span class="plain">;</span>
<span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">kind_required</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">-1] = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Kinds::Behaviour::uses_pointer_values</span><span class="plain">(</span><span class="identifier">head</span><span class="plain">)) &amp;&amp; (</span><span class="identifier">Kinds::Behaviour::definite</span><span class="plain">(</span><span class="identifier">head</span><span class="plain">)))</span>
<span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">kind_required</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">-1] = </span><span class="identifier">head</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">tokens_count</span><span class="plain">--;</span>
<span class="functiontext">Invocations::AsCalls::emit_function_call</span><span class="plain">(</span><span class="identifier">tokens</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, -1, </span><span class="identifier">fn</span><span class="plain">, </span><span class="identifier">TRUE</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_7">&#167;3.7</a>.</p>
<p class="inwebparagraph"><a id="SP3_7_2"></a><b>&#167;3.7.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Primitive "description-application"</span> <span class="cwebmacronumber">3.7.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain"> = </span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[1];</span>
<span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[1] = </span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[0];</span>
<span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[0] = </span><span class="functiontext">Rvalues::from_int</span><span class="plain">(-1, </span><span class="identifier">EMPTY_WORDING</span><span class="plain">);</span>
<span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">tokens_count</span><span class="plain"> = </span><span class="constant">2</span><span class="plain">;</span>
<span class="functiontext">Invocations::AsCalls::emit_function_call</span><span class="plain">(</span><span class="identifier">tokens</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, -1, </span><span class="identifier">fn</span><span class="plain">, </span><span class="identifier">FALSE</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_7">&#167;3.7</a>.</p>
<p class="inwebparagraph"><a id="SP3_7_3"></a><b>&#167;3.7.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Primitive "solve-equation"</span> <span class="cwebmacronumber">3.7.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<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">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[1], </span><span class="identifier">K_equation</span><span class="plain">)) {</span>
<span class="functiontext">Equations::emit_solution</span><span class="plain">(</span><span class="identifier">ParseTree::get_text</span><span class="plain">(</span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[0]),</span>
<span class="functiontext">Rvalues::to_equation</span><span class="plain">(</span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[1]));</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">PM_SolvedNameless</span><span class="plain">),</span>
<span class="string">"only specific named equations can be solved"</span><span class="plain">,</span>
<span class="string">"not equations arrived at by further calculations or choices. (Sorry: "</span>
<span class="string">"but there would be no safe way to determine when an equation could "</span>
<span class="string">"be used, because all equations have differing natures and variables.)"</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_7">&#167;3.7</a>.</p>
<p class="inwebparagraph"><a id="SP3_5_2_1"></a><b>&#167;3.5.2.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Issue a no-such-local problem message</span> <span class="cwebmacronumber">3.5.2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">Problems::quote_stream</span><span class="plain">(4, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">operand</span><span class="plain">);</span>
<span class="functiontext">Problems::Issue::inline_problem</span><span class="plain">(</span><span class="identifier">_p_</span><span class="plain">(</span><span class="identifier">PM_InlineNoSuch</span><span class="plain">), </span><span class="identifier">ph</span><span class="plain">, </span><span class="identifier">sche</span><span class="plain">-&gt;</span><span class="identifier">owner</span><span class="plain">-&gt;</span><span class="identifier">parent_schema</span><span class="plain">-&gt;</span><span class="identifier">converted_from</span><span class="plain">,</span>
<span class="string">"I don't know any local variable called '%4'."</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3_5_2">&#167;3.5.2</a>, <a href="#SP3_5_8">&#167;3.5.8</a>, <a href="#SP3_5_9">&#167;3.5.9</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Parsing the invocation operands. </b>Two ways. First, as an identifier name, which stands for a local I6 variable
or for a token in the phrase being invoked. There are three ways we can
write this:
</p>
<p class="inwebparagraph"></p>
<ul class="items"><li>(a) the operands "0" to "9", a single digit, mean the <code class="display"><span class="extract">{-my:...}</span></code> variables
with those numbers, if they exist;
</li><li>(b) otherwise if we have the name of a token in the phrase being invoked,
then the operand refers to its value in the current invocation;
</li><li>(c) and failing that we have the name of a local I6 variable.
</li></ul>
<pre class="display">
<span class="identifier">parse_node</span><span class="plain"> *</span><span class="functiontext">Invocations::Inline::parse_bracing_operand_as_identifier</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">operand</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="reserved">tokens_packet</span><span class="plain"> *</span><span class="identifier">tokens</span><span class="plain">, </span><span class="reserved">local_variable</span><span class="plain"> **</span><span class="identifier">my_vars</span><span class="plain">) {</span>
<span class="reserved">local_variable</span><span class="plain"> *</span><span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">operand</span><span class="plain">, </span><span class="constant">1</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">operand</span><span class="plain">, </span><span class="constant">0</span><span class="plain">) &gt;= </span><span class="character">'0'</span><span class="plain">) &amp;&amp; (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">operand</span><span class="plain">, </span><span class="constant">0</span><span class="plain">) &lt;= </span><span class="character">'9'</span><span class="plain">))</span>
<span class="identifier">lvar</span><span class="plain"> = </span><span class="identifier">my_vars</span><span class="plain">[</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">operand</span><span class="plain">, </span><span class="constant">0</span><span class="plain">) - </span><span class="character">'0'</span><span class="plain">];</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">LW</span><span class="plain"> = </span><span class="identifier">Feeds::feed_stream</span><span class="plain">(</span><span class="identifier">operand</span><span class="plain">);</span>
<span class="identifier">lvar</span><span class="plain"> = </span><span class="functiontext">LocalVariables::parse</span><span class="plain">(&amp;(</span><span class="identifier">ph</span><span class="plain">-&gt;</span><span class="element">stack_frame</span><span class="plain">), </span><span class="identifier">LW</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain">) {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">tok</span><span class="plain"> = </span><span class="functiontext">LocalVariables::get_parameter_number</span><span class="plain">(</span><span class="identifier">lvar</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">tok</span><span class="plain"> &gt;= </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">tokens</span><span class="plain">-&gt;</span><span class="element">args</span><span class="plain">[</span><span class="identifier">tok</span><span class="plain">];</span>
<span class="plain">}</span>
<span class="identifier">lvar</span><span class="plain"> = </span><span class="functiontext">LocalVariables::by_name</span><span class="plain">(</span><span class="identifier">operand</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">lvar</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Lvalues::new_LOCAL_VARIABLE</span><span class="plain">(</span><span class="identifier">EMPTY_WORDING</span><span class="plain">, </span><span class="identifier">lvar</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 Invocations::Inline::parse_bracing_operand_as_identifier is used in <a href="#SP3_5_2">&#167;3.5.2</a>, <a href="#SP3_5_3">&#167;3.5.3</a>, <a href="#SP3_5_4_1">&#167;3.5.4.1</a>, <a href="#SP3_5_5">&#167;3.5.5</a>, <a href="#SP3_5_6">&#167;3.5.6</a>, <a href="#SP3_5_7_1">&#167;3.5.7.1</a>, <a href="#SP3_5_8">&#167;3.5.8</a>, <a href="#SP3_5_9">&#167;3.5.9</a>.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>The second sort of operand is a kind.
</p>
<p class="inwebparagraph">If the kind named involves kind variables A, B, C, ..., then these are
substituted with their values in the context of the invocation being made.
In addition two special kind names are recognised:
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">return-kind</span>
<span class="plain">rule-return-kind</span>
</pre>
<p class="inwebparagraph">The former being the return kind from the phrase we are being invoked in
(if it's a phrase to decide a value), and the latter being the kind of value
which this rule should produce (if it's a rule, and if it's in a rulebook
which wants to produce a value). For example, you could define a phrase
which would safely abandon any attempt to define a value like this:
</p>
<blockquote>
<p>To give up deciding: (- return {-new:return-kind}; -).</p>
</blockquote>
<pre class="display">
<span class="identifier">kind</span><span class="plain"> *</span><span class="functiontext">Invocations::Inline::parse_bracing_operand_as_kind</span><span class="plain">(</span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">kind_variable_declaration</span><span class="plain"> *</span><span class="identifier">kvd</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"return-kind"</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Frames::get_kind_returned</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">operand</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"rule-return-kind"</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Rulebooks::kind_from_context</span><span class="plain">();</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">kind_vars_inline</span><span class="plain">[27];</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;27; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">kind_vars_inline</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">for</span><span class="plain"> (; </span><span class="identifier">kvd</span><span class="plain">; </span><span class="identifier">kvd</span><span class="plain">=</span><span class="identifier">kvd</span><span class="plain">-&gt;</span><span class="element">next</span><span class="plain">) </span><span class="identifier">kind_vars_inline</span><span class="plain">[</span><span class="identifier">kvd</span><span class="plain">-&gt;</span><span class="identifier">kv_number</span><span class="plain">] = </span><span class="identifier">kvd</span><span class="plain">-&gt;</span><span class="identifier">kv_value</span><span class="plain">;</span>
<span class="identifier">kind</span><span class="plain"> **</span><span class="identifier">saved</span><span class="plain"> = </span><span class="functiontext">Frames::temporarily_set_kvs</span><span class="plain">(</span><span class="identifier">kind_vars_inline</span><span class="plain">);</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">KW</span><span class="plain"> = </span><span class="identifier">Feeds::feed_stream</span><span class="plain">(</span><span class="identifier">operand</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">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">type</span><span class="plain">-</span><span class="identifier">expression</span><span class="plain">&gt;(</span><span class="identifier">KW</span><span class="plain">)) </span><span class="identifier">spec</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="functiontext">Frames::temporarily_set_kvs</span><span class="plain">(</span><span class="identifier">saved</span><span class="plain">);</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = </span><span class="functiontext">Specifications::to_kind</span><span class="plain">(</span><span class="identifier">spec</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">K</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Invocations::Inline::parse_bracing_operand_as_kind is used in <a href="#SP3_2_1">&#167;3.2.1</a>, <a href="#SP3_2_2">&#167;3.2.2</a>, <a href="#SP3_2_3">&#167;3.2.3</a>, <a href="#SP3_2_4">&#167;3.2.4</a>, <a href="#SP3_2_5">&#167;3.2.5</a>, <a href="#SP3_2_6">&#167;3.2.6</a>, <a href="#SP3_2_7">&#167;3.2.7</a>, <a href="#SP3_2_8">&#167;3.2.8</a>, <a href="#SP3_5_1_1_1">&#167;3.5.1.1.1</a>, <a href="#SP3_5_3">&#167;3.5.3</a>, <a href="#SP3_5_8">&#167;3.5.8</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. I7 expression evaluation. </b>This is not quite like regular expression evaluation, because we want
"room" and "lighted" to be evaluated as the I6 translation of the
relevant class or property, rather than as code to test the predicate
"X is a room" or "X is lighted", and similarly for bare names
of defined adjectives. So:
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Invocations::Inline::compile_I7_expression_from_text</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">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">VH</span><span class="plain">) &amp;&amp; (</span><span class="identifier">VH</span><span class="plain">-&gt;</span><span class="identifier">vhmode_wanted</span><span class="plain"> == </span><span class="identifier">INTER_VOID_VHMODE</span><span class="plain">)) {</span>
<span class="identifier">Produce::evaluation</span><span class="plain">(</span><span class="functiontext">Emit::tree</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="plain">}</span>
<span class="functiontext">Invocations::Inline::compile_I7_expression_from_text_inner</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">VH</span><span class="plain">) &amp;&amp; (</span><span class="identifier">VH</span><span class="plain">-&gt;</span><span class="identifier">vhmode_wanted</span><span class="plain"> == </span><span class="identifier">INTER_VOID_VHMODE</span><span class="plain">)) {</span>
<span class="identifier">Produce::up</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">());</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Invocations::Inline::compile_I7_expression_from_text_inner</span><span class="plain">(</span><span class="identifier">value_holster</span><span class="plain"> *</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">p</span><span class="plain">) {</span>
<span class="identifier">wording</span><span class="plain"> </span><span class="identifier">LW</span><span class="plain"> = </span><span class="identifier">Feeds::feed_stream</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="reserved">property</span><span class="plain">-</span><span class="identifier">name</span><span class="plain">&gt;(</span><span class="identifier">LW</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VH</span><span class="plain">)</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Properties::iname</span><span class="plain">(&lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;));</span>
<span class="reserved">else</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="string">"%n"</span><span class="plain">, </span><span class="functiontext">Properties::iname</span><span class="plain">(&lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;));</span>
<span class="reserved">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">k</span><span class="plain">-</span><span class="identifier">kind</span><span class="plain">&gt;(</span><span class="identifier">LW</span><span class="plain">)) {</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Kinds::Compare::lt</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">, </span><span class="identifier">K_object</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VH</span><span class="plain">)</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Kinds::RunTime::I6_classname</span><span class="plain">(</span><span class="identifier">K</span><span class="plain">));</span>
<span class="reserved">else</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="string">"%n"</span><span class="plain">, </span><span class="functiontext">Kinds::RunTime::I6_classname</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="plain">}</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">Instances::parse_object</span><span class="plain">(</span><span class="identifier">LW</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">VH</span><span class="plain">)</span>
<span class="identifier">Produce::val_iname</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_value</span><span class="plain">, </span><span class="functiontext">Instances::iname</span><span class="plain">(&lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;));</span>
<span class="reserved">else</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">OUT</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">return</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">adjectival_phrase</span><span class="plain"> *</span><span class="identifier">aph</span><span class="plain"> = </span><span class="identifier">Adjectives::parse</span><span class="plain">(</span><span class="identifier">LW</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">aph</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Adjectives::Meanings::write_adjective_test_routine</span><span class="plain">(</span><span class="identifier">VH</span><span class="plain">, </span><span class="identifier">aph</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="identifier">Problems::Issue::unlocated_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">BelievedImpossible</span><span class="plain">),</span>
<span class="string">"You tried to use '(+' and '+)' to expand to the Inform 6 routine "</span>
<span class="string">"address of an adjective, but it was an adjective with no meaning."</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">int</span><span class="plain"> </span><span class="identifier">initial_problem_count</span><span class="plain"> = </span><span class="identifier">problem_count</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="identifier">spec</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (&lt;</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">&gt;(</span><span class="identifier">LW</span><span class="plain">)) </span><span class="identifier">spec</span><span class="plain"> = &lt;&lt;</span><span class="identifier">rp</span><span class="plain">&gt;&gt;;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">spec</span><span class="plain"> = </span><span class="functiontext">Specifications::new_UNKNOWN</span><span class="plain">(</span><span class="identifier">LW</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">ifndef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="identifier">Produce::val</span><span class="plain">(</span><span class="functiontext">Emit::tree</span><span class="plain">(), </span><span class="identifier">K_number</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, </span><span class="constant">0</span><span class="plain">);</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">initial_problem_count</span><span class="plain"> &lt; </span><span class="identifier">problem_count</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="functiontext">Dash::check_value</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">if</span><span class="plain"> (</span><span class="identifier">initial_problem_count</span><span class="plain"> &lt; </span><span class="identifier">problem_count</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="constant">BEGIN_COMPILATION_MODE</span><span class="plain">;</span>
<span class="identifier">COMPILATION_MODE_EXIT</span><span class="plain">(</span><span class="constant">DEREFERENCE_POINTERS_CMODE</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">VH</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">spec</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">nonlocal_variable</span><span class="plain"> *</span><span class="identifier">nlv</span><span class="plain"> = </span><span class="functiontext">NonlocalVariables::parse</span><span class="plain">(</span><span class="identifier">LW</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">nlv</span><span class="plain">) {</span>
<span class="identifier">PUT</span><span class="plain">(</span><span class="identifier">URL_SYMBOL_CHAR</span><span class="plain">);</span>
<span class="identifier">Inter::SymbolsTables::symbol_to_url_name</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">InterNames::to_symbol</span><span class="plain">(</span><span class="functiontext">NonlocalVariables::iname</span><span class="plain">(</span><span class="identifier">nlv</span><span class="plain">)));</span>
<span class="identifier">PUT</span><span class="plain">(</span><span class="identifier">URL_SYMBOL_CHAR</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">value_holster</span><span class="plain"> </span><span class="identifier">VH2</span><span class="plain"> = </span><span class="identifier">Holsters::new</span><span class="plain">(</span><span class="identifier">INTER_DATA_VHMODE</span><span class="plain">);</span>
<span class="functiontext">Specifications::Compiler::compile_inner</span><span class="plain">(&amp;</span><span class="identifier">VH2</span><span class="plain">, </span><span class="identifier">spec</span><span class="plain">);</span>
<span class="identifier">inter_t</span><span class="plain"> </span><span class="identifier">v1</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">, </span><span class="identifier">v2</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
<span class="identifier">Holsters::unholster_pair</span><span class="plain">(&amp;</span><span class="identifier">VH2</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="reserved">if</span><span class="plain"> (</span><span class="identifier">v1</span><span class="plain"> == </span><span class="identifier">ALIAS_IVAL</span><span class="plain">) {</span>
<span class="identifier">PUT</span><span class="plain">(</span><span class="identifier">URL_SYMBOL_CHAR</span><span class="plain">);</span>
<span class="identifier">inter_symbols_table</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain"> = </span><span class="identifier">Inter::Packages::scope</span><span class="plain">(</span><span class="functiontext">Emit::current_enclosure</span><span class="plain">()-&gt;</span><span class="identifier">actual_package</span><span class="plain">);</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::symbol_from_id</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="identifier">v2</span><span class="plain">);</span>
<span class="identifier">Inter::SymbolsTables::symbol_to_url_name</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">);</span>
<span class="identifier">PUT</span><span class="plain">(</span><span class="identifier">URL_SYMBOL_CHAR</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">CodeGen::FC::val_from</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">Packaging::at</span><span class="plain">(</span><span class="functiontext">Emit::tree</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="plain">}</span>
<span class="plain">}</span>
<span class="constant">END_COMPILATION_MODE</span><span class="plain">;</span>
<span class="plain">#</span><span class="identifier">endif</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Invocations::Inline::compile_I7_expression_from_text is used in <a href="#SP2">&#167;2</a>, 26/iti (<a href="26-iti.html#SP2_5">&#167;2.5</a>).</p>
<p class="endnote">The function Invocations::Inline::compile_I7_expression_from_text_inner appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><a href="25-ciac.html">Back to 'Compile Invocations As Calls'</a></li><li><a href="25-cp.html">Continue with 'Compile Phrases'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>