mirror of
https://github.com/ganelson/inform.git
synced 2024-07-05 16:44:21 +03:00
2964 lines
288 KiB
HTML
2964 lines
288 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 http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
</head>
|
|
<body>
|
|
|
|
<!--Weave of '25/cii' generated by 7-->
|
|
<ul class="crumbs"><li><a href="../webs.html">★</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">§1. CSI: Inline</a></li><li><a href="#SP3_2">§3.2. Commands about kinds</a></li><li><a href="#SP3_3">§3.3. Typographic commands</a></li><li><a href="#SP3_4">§3.4. Label or counter commands</a></li><li><a href="#SP3_1_1_4">§3.1.1.4. Token annotations</a></li><li><a href="#SP3_5">§3.5. High-level commands</a></li><li><a href="#SP3_6">§3.6. Miscellaneous commands</a></li><li><a href="#SP3_7">§3.7. Primitive definitions</a></li><li><a href="#SP6">§6. Parsing the invocation operands</a></li><li><a href="#SP8">§8. I7 expression evaluation</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="inwebparagraph"><a id="SP1"></a><b>§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"> 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>
|
|
<<span class="cwebmacro">Start with all of the implicit my-variables unused</span> <span class="cwebmacronumber">1.1</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Create any new local variables explicitly called for</span> <span class="cwebmacronumber">1.2</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="identifier">CSIS</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="element">.ph</span><span class="plain"> = </span><span class="identifier">ph</span><span class="plain">;</span>
|
|
<span class="identifier">CSIS</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="element">.tokens</span><span class="plain"> = </span><span class="identifier">tokens</span><span class="plain">;</span>
|
|
<span class="identifier">CSIS</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>
|
|
|
|
<<span class="cwebmacro">Expand those into streams</span> <span class="cwebmacronumber">1.3</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="cwebmacro">Open a code block</span> <span class="cwebmacronumber">1.4</span>>
|
|
<span class="reserved">else</span><span class="plain"> </span><<span class="cwebmacro">Release any variables created inline</span> <span class="cwebmacronumber">1.5</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ph</span><span class="plain">-</span><span class="element">>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">§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>§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">
|
|
<<span class="cwebmacrodefn">Start with all of the implicit my-variables unused</span> <span class="cwebmacronumber">1.1</span>> =
|
|
</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"><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">§1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP1_2"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Create any new local variables explicitly called for</span> <span class="cwebmacronumber">1.2</span>> =
|
|
</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"><</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">-</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><<span class="cwebmacro">Create a local at this token</span> <span class="cwebmacronumber">1.2.1</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">§1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP1_2_1"></a><b>§1.2.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Create a local at this token</span> <span class="cwebmacronumber">1.2.1</span>> =
|
|
</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">-</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">, 8);</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">§1.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP1_3"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Expand those into streams</span> <span class="cwebmacronumber">1.3</span>> =
|
|
</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">), &</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">§1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP1_4"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Open a code block</span> <span class="cwebmacronumber">1.4</span>> =
|
|
</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">) > 0) </span><span class="identifier">val</span><span class="plain"> = </span><span class="identifier">tokens</span><span class="plain">-</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">§1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP1_5"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Release any variables created inline</span> <span class="cwebmacronumber">1.5</span>> =
|
|
</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"><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">§1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP2"></a><b>§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">-></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">-></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">-></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">-></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">&</span><span class="functiontext">Invocations::Inline::csi_inline_inner_inner</span><span class="plain">, &</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">§1.3</a>, 24/pb (<a href="24-pb.html#SP14">§14</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§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">-</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">-</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">-</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">-</span><span class="element">>my_vars</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></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">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">primitive_definition_ISINC</span><span class="plain">)</span>
|
|
<<span class="cwebmacro">Expand an entirely internal-made definition</span> <span class="cwebmacronumber">3.7</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Expand a bracing containing a kind command</span> <span class="cwebmacronumber">3.2</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Expand a bracing containing a typographic command</span> <span class="cwebmacronumber">3.3</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Expand a bracing containing a label or counter command</span> <span class="cwebmacronumber">3.4</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Expand a bracing containing a high-level command</span> <span class="cwebmacronumber">3.5</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Expand a bracing containing a miscellaneous command</span> <span class="cwebmacronumber">3.6</span>><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">-></span><span class="identifier">bracing</span><span class="plain">);</span>
|
|
<<span class="cwebmacro">Expand a bracing containing natural language text</span> <span class="cwebmacronumber">3.1</span>><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">§2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§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"> 1 </span> <span class="comment">the text "phrase options"</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">OPT_INSUB</span><span class="plain"> 2 </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"> 3 </span> <span class="comment">the name of a token</span>
|
|
<span class="definitionkeyword">define</span> <span class="constant">PROBLEM_INSUB</span><span class="plain"> 4 </span> <span class="comment">the syntax was wrong, so do nothing</span>
|
|
</pre>
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§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"><</span><span class="identifier">inline</span><span class="plain">-</span><span class="identifier">substitution</span><span class="plain">> ::=</span>
|
|
<span class="reserved">phrase</span><span class="plain"> </span><span class="identifier">options</span><span class="plain"> | ==> </span><span class="constant">OPTS_INSUB</span>
|
|
<span class="plain"><</span><span class="reserved">phrase</span><span class="plain">-</span><span class="identifier">option</span><span class="plain">> | ==> </span><span class="constant">OPT_INSUB</span><span class="plain">; <<</span><span class="identifier">opt</span><span class="plain">>> = </span><span class="identifier">R</span><span class="plain">[1]</span>
|
|
<span class="plain"><</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">> | ==> </span><span class="constant">LOCAL_INSUB</span><span class="plain">; <<</span><span class="reserved">local_variable</span><span class="plain">:</span><span class="identifier">var</span><span class="plain">>> = </span><span class="identifier">RP</span><span class="plain">[1]</span>
|
|
<span class="plain">... ==> </span><<span class="cwebmacro">Issue PM_BadInlineExpansion problem</span> <span class="cwebmacronumber">5.2</span>>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5_1"></a><b>§5.1. </b>This matches one of the token names in the preamble to the inline definition.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"><</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">> </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">(&(</span><span class="identifier">ph_being_parsed</span><span class="plain">-</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>§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">
|
|
<<span class="cwebmacrodefn">Issue PM_BadInlineExpansion problem</span> <span class="cwebmacronumber">5.2</span>> =
|
|
</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="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">§5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1"></a><b>§3.1. </b>Acting on that:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Expand a bracing containing natural language text</span> <span class="cwebmacronumber">3.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">phod_being_parsed</span><span class="plain"> = &(</span><span class="identifier">ph</span><span class="plain">-</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"><</span><span class="identifier">inline</span><span class="plain">-</span><span class="identifier">substitution</span><span class="plain">>(</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"> (<<</span><span class="identifier">r</span><span class="plain">>>) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">OPTS_INSUB</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="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="constant">OPT_INSUB</span><span class="plain">:</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">current_opts</span><span class="plain"> & <<</span><span class="identifier">opt</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">, 1); </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">, 0);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">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"> = <<</span><span class="reserved">local_variable</span><span class="plain">:</span><span class="identifier">var</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"> >= 0) </span><<span class="cwebmacro">Expand a bracing containing a token name</span> <span class="cwebmacronumber">3.1.1</span>><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">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Expand a bracing containing a token name</span> <span class="cwebmacronumber">3.1.1</span>> =
|
|
</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">-</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>
|
|
<<span class="cwebmacro">Take account of any annotation to the inline token</span> <span class="cwebmacronumber">3.1.1.4</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="cwebmacro">Work out values for the kind variables in this context</span> <span class="cwebmacronumber">3.1.1.1</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="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">-</span><span class="element">>type_data.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">, &</span><span class="identifier">changed</span><span class="plain">);</span>
|
|
<<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>><span class="character">;</span>
|
|
<<span class="cwebmacro">Compile the token value</span> <span class="cwebmacronumber">3.1.1.3</span>><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">§3.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_1"></a><b>§3.1.1.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Work out values for the kind variables in this context</span> <span class="cwebmacronumber">3.1.1.1</span>> =
|
|
</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"><=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">-</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">-></span><span class="identifier">kv_number</span><span class="plain">] = </span><span class="identifier">kvd</span><span class="plain">-></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">§3.1.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_2"></a><b>§3.1.1.2. </b><code class="display">
|
|
<<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>> =
|
|
</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">) && (</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">-</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="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">§3.1.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_3"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Compile the token value</span> <span class="cwebmacronumber">3.1.1.3</span>> =
|
|
</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\</span><span class="plain">n</span><span class="string">"</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">§3.1.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2"></a><b>§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>
|
|
|
|
<<span class="cwebmacrodefn">Expand a bracing containing a kind command</span> <span class="cwebmacronumber">3.2</span>> =
|
|
<span class="identifier">Problems::quote_stream</span><span class="plain">(4, </span><span class="identifier">sche</span><span class="plain">-></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">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">new_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "new"</span> <span class="cwebmacronumber">3.2.1</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">new_list_of_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "new-list-of"</span> <span class="cwebmacronumber">3.2.2</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">printing_routine_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "printing-routine"</span> <span class="cwebmacronumber">3.2.5</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">ranger_routine_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "ranger-routine"</span> <span class="cwebmacronumber">3.2.6</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">next_routine_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "next-routine"</span> <span class="cwebmacronumber">3.2.3</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">previous_routine_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "previous-routine"</span> <span class="cwebmacronumber">3.2.4</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">strong_kind_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "strong-kind"</span> <span class="cwebmacronumber">3.2.7</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">weak_kind_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "weak-kind"</span> <span class="cwebmacronumber">3.2.8</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_1"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline command "new"</span> <span class="cwebmacronumber">3.2.1</span>> =
|
|
</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">-></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><<span class="cwebmacro">Issue an inline no-such-kind problem</span> <span class="cwebmacronumber">3.2.1.2</span>>
|
|
<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>
|
|
<<span class="cwebmacro">Issue problem for no natural choice</span> <span class="cwebmacronumber">3.2.1.1</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">§3.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_1_1"></a><b>§3.2.1.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Issue problem for no natural choice</span> <span class="cwebmacronumber">3.2.1.1</span>> =
|
|
</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="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">§3.2.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_2"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline command "new-list-of"</span> <span class="cwebmacronumber">3.2.2</span>> =
|
|
</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">-></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">-</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">§3.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_3"></a><b>§3.2.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Inline command "next-routine"</span> <span class="cwebmacronumber">3.2.3</span>> =
|
|
</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">-></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><<span class="cwebmacro">Issue an inline no-such-kind problem</span> <span class="cwebmacronumber">3.2.1.2</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">§3.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_4"></a><b>§3.2.4. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Inline command "previous-routine"</span> <span class="cwebmacronumber">3.2.4</span>> =
|
|
</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">-></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><<span class="cwebmacro">Issue an inline no-such-kind problem</span> <span class="cwebmacronumber">3.2.1.2</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">§3.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_5"></a><b>§3.2.5. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Inline command "printing-routine"</span> <span class="cwebmacronumber">3.2.5</span>> =
|
|
</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">-></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><<span class="cwebmacro">Issue an inline no-such-kind problem</span> <span class="cwebmacronumber">3.2.1.2</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">§3.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_6"></a><b>§3.2.6. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Inline command "ranger-routine"</span> <span class="cwebmacronumber">3.2.6</span>> =
|
|
</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">-></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><<span class="cwebmacro">Issue an inline no-such-kind problem</span> <span class="cwebmacronumber">3.2.1.2</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">§3.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_7"></a><b>§3.2.7. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Inline command "strong-kind"</span> <span class="cwebmacronumber">3.2.7</span>> =
|
|
</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">-></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><<span class="cwebmacro">Issue an inline no-such-kind problem</span> <span class="cwebmacronumber">3.2.1.2</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">§3.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_8"></a><b>§3.2.8. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Inline command "weak-kind"</span> <span class="cwebmacronumber">3.2.8</span>> =
|
|
</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">-></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><<span class="cwebmacro">Issue an inline no-such-kind problem</span> <span class="cwebmacronumber">3.2.1.2</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">§3.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_1_2"></a><b>§3.2.1.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Issue an inline no-such-kind problem</span> <span class="cwebmacronumber">3.2.1.2</span>> =
|
|
</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">-></span><span class="identifier">owner</span><span class="plain">-></span><span class="identifier">parent_schema</span><span class="plain">-></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">§3.2.1</a>, <a href="#SP3_2_3">§3.2.3</a>, <a href="#SP3_2_4">§3.2.4</a>, <a href="#SP3_2_5">§3.2.5</a>, <a href="#SP3_2_6">§3.2.6</a>, <a href="#SP3_2_7">§3.2.7</a>, <a href="#SP3_2_8">§3.2.8</a>, <a href="#SP3_5_8">§3.5.8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_3"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Expand a bracing containing a typographic command</span> <span class="cwebmacronumber">3.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">backspace_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "backspace"</span> <span class="cwebmacronumber">3.3.1</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></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">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">open_brace_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "open-brace"</span> <span class="cwebmacronumber">3.3.2</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">close_brace_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "close-brace"</span> <span class="cwebmacronumber">3.3.3</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_3_1"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline command "backspace"</span> <span class="cwebmacronumber">3.3.1</span>> =
|
|
</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="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">§3.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_3_2"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline command "open-brace"</span> <span class="cwebmacronumber">3.3.2</span>> =
|
|
</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">§3.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_3_3"></a><b>§3.3.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Inline command "close-brace"</span> <span class="cwebmacronumber">3.3.3</span>> =
|
|
</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">§3.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_4"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Expand a bracing containing a label or counter command</span> <span class="cwebmacronumber">3.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">label_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "label"</span> <span class="cwebmacronumber">3.4.1</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">counter_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "counter"</span> <span class="cwebmacronumber">3.4.2</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">counter_storage_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "counter-storage"</span> <span class="cwebmacronumber">3.4.3</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">counter_up_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "counter-up"</span> <span class="cwebmacronumber">3.4.4</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">counter_down_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "counter-down"</span> <span class="cwebmacronumber">3.4.5</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">counter_makes_array_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "counter-makes-array"</span> <span class="cwebmacronumber">3.4.6</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_4_1"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline command "label"</span> <span class="cwebmacronumber">3.4.1</span>> =
|
|
</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">-></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">§3.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_4_2"></a><b>§3.4.2. </b>We can also output just the numerical counter:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Inline command "counter"</span> <span class="cwebmacronumber">3.4.2</span>> =
|
|
</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">-></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">§3.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_4_3"></a><b>§3.4.3. </b>We can also output just the storage array:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Inline command "counter-storage"</span> <span class="cwebmacronumber">3.4.3</span>> =
|
|
</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">-></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">§3.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_4_4"></a><b>§3.4.4. </b>Or increment it, printing nothing:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Inline command "counter-up"</span> <span class="cwebmacronumber">3.4.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="functiontext">JumpLabels::read_counter</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-></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">§3.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_4_5"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline command "counter-down"</span> <span class="cwebmacronumber">3.4.5</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="functiontext">JumpLabels::read_counter</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-></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">§3.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_4_6"></a><b>§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-->{-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 — 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">
|
|
<<span class="cwebmacrodefn">Inline command "counter-makes-array"</span> <span class="cwebmacronumber">3.4.6</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">words_per_count</span><span class="plain"> = 1;</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">-></span><span class="identifier">operand2</span><span class="plain">) > 0) </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">-></span><span class="identifier">operand2</span><span class="plain">, 0);</span>
|
|
<span class="functiontext">JumpLabels::allocate_counter</span><span class="plain">(</span><span class="identifier">sche</span><span class="plain">-></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">§3.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_4"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Take account of any annotation to the inline token</span> <span class="cwebmacronumber">3.1.1.4</span>> =
|
|
</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">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">by_reference_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline annotation "by-reference"</span> <span class="cwebmacronumber">3.1.1.4.1</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">by_reference_blank_out_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline annotation "by-reference-blank-out"</span> <span class="cwebmacronumber">3.1.1.4.2</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">reference_exists_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline annotation "reference-exists"</span> <span class="cwebmacronumber">3.1.1.4.3</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">lvalue_by_reference_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline annotation "lvalue-by-reference"</span> <span class="cwebmacronumber">3.1.1.4.4</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">by_value_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline annotation "by-value"</span> <span class="cwebmacronumber">3.1.1.4.5</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">box_quotation_text_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline annotation "box-quotation-text"</span> <span class="cwebmacronumber">3.1.1.4.6</span>><span class="plain">;</span>
|
|
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">IF_MODULE</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">try_action_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline annotation "try-action"</span> <span class="cwebmacronumber">3.1.1.4.9</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">try_action_silently_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline annotation "try-action-silently"</span> <span class="cwebmacronumber">3.1.1.4.10</span>><span class="plain">;</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">return_value_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline annotation "return-value"</span> <span class="cwebmacronumber">3.1.1.4.7</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">return_value_from_rule_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline annotation "return-value-from-rule"</span> <span class="cwebmacronumber">3.1.1.4.8</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">property_holds_block_value_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline annotation "property-holds-block-value"</span> <span class="cwebmacronumber">3.1.1.4.11</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">mark_event_used_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline annotation "mark-event-used"</span> <span class="cwebmacronumber">3.1.1.4.12</span>><span class="plain">;</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> != </span><span class="identifier">no_ISINC</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="cwebmacro">Throw a problem message for an invalid inline annotation</span> <span class="cwebmacronumber">3.1.1.4.13</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_1_1">§3.1.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_4_1"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline annotation "by-reference"</span> <span class="cwebmacronumber">3.1.1.4.1</span>> =
|
|
</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">§3.1.1.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_4_2"></a><b>§3.1.1.4.2. </b>And, variedly:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Inline annotation "by-reference-blank-out"</span> <span class="cwebmacronumber">3.1.1.4.2</span>> =
|
|
</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">§3.1.1.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_4_3"></a><b>§3.1.1.4.3. </b>And, variedly:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Inline annotation "reference-exists"</span> <span class="cwebmacronumber">3.1.1.4.3</span>> =
|
|
</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">§3.1.1.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_4_4"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline annotation "lvalue-by-reference"</span> <span class="cwebmacronumber">3.1.1.4.4</span>> =
|
|
</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">§3.1.1.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_4_5"></a><b>§3.1.1.4.5. </b>This is the default, so it's redundant, but clarifies definitions.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Inline annotation "by-value"</span> <span class="cwebmacronumber">3.1.1.4.5</span>> =
|
|
</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">§3.1.1.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_4_6"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline annotation "box-quotation-text"</span> <span class="cwebmacronumber">3.1.1.4.6</span>> =
|
|
</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="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">§3.1.1.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_4_7"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline annotation "return-value"</span> <span class="cwebmacronumber">3.1.1.4.7</span>> =
|
|
</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>
|
|
<<span class="cwebmacro">Handle an inline return</span> <span class="cwebmacronumber">3.1.1.4.7.1</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_1_1_4">§3.1.1.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_4_8"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline annotation "return-value-from-rule"</span> <span class="cwebmacronumber">3.1.1.4.8</span>> =
|
|
</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>
|
|
<<span class="cwebmacro">Handle an inline return</span> <span class="cwebmacronumber">3.1.1.4.7.1</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_1_1_4">§3.1.1.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_4_7_1"></a><b>§3.1.1.4.7.1. </b>So here's the common code:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Handle an inline return</span> <span class="cwebmacronumber">3.1.1.4.7.1</span>> =
|
|
</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">(&(</span><span class="identifier">phrase_being_compiled</span><span class="plain">-</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">) && (</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">) && (</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><<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>><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">) && (</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><<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>><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">§3.1.1.4.7</a>, <a href="#SP3_1_1_4_8">§3.1.1.4.8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_4_7_1_1"></a><b>§3.1.1.4.7.1.1. </b><code class="display">
|
|
<<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>> =
|
|
</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="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="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">§3.1.1.4.7.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_4_7_1_2"></a><b>§3.1.1.4.7.1.2. </b><code class="display">
|
|
<<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>> =
|
|
</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="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="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">§3.1.1.4.7.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_4_9"></a><b>§3.1.1.4.9. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Inline annotation "try-action"</span> <span class="cwebmacronumber">3.1.1.4.9</span>> =
|
|
</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">§3.1.1.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_4_10"></a><b>§3.1.1.4.10. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Inline annotation "try-action-silently"</span> <span class="cwebmacronumber">3.1.1.4.10</span>> =
|
|
</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">, 1);</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">, 1);</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">, 1);</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">§3.1.1.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_4_11"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline annotation "property-holds-block-value"</span> <span class="cwebmacronumber">3.1.1.4.11</span>> =
|
|
</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">, 0);</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">, 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_truth_state</span><span class="plain">, </span><span class="identifier">LITERAL_IVAL</span><span class="plain">, 0);</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">§3.1.1.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_4_12"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline annotation "mark-event-used"</span> <span class="cwebmacronumber">3.1.1.4.12</span>> =
|
|
</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="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">§3.1.1.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1_1_4_13"></a><b>§3.1.1.4.13. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Throw a problem message for an invalid inline annotation</span> <span class="cwebmacronumber">3.1.1.4.13</span>> =
|
|
</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">-></span><span class="identifier">command</span><span class="plain">);</span>
|
|
<span class="identifier">Problems::Issue::handmade_problem</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">§3.1.1.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Expand a bracing containing a high-level command</span> <span class="cwebmacronumber">3.5</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">my_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "my"</span> <span class="cwebmacronumber">3.5.1</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">unprotect_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "unprotect"</span> <span class="cwebmacronumber">3.5.2</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">copy_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "copy"</span> <span class="cwebmacronumber">3.5.4</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">initialise_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "initialise"</span> <span class="cwebmacronumber">3.5.3</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">matches_description_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "matches-description"</span> <span class="cwebmacronumber">3.5.5</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">now_matches_description_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "now-matches-description"</span> <span class="cwebmacronumber">3.5.6</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">arithmetic_operation_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "arithmetic-operation"</span> <span class="cwebmacronumber">3.5.7</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">say_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "say"</span> <span class="cwebmacronumber">3.5.8</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">show_me_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "show-me"</span> <span class="cwebmacronumber">3.5.9</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_1"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline command "my"</span> <span class="cwebmacronumber">3.5.1</span>> =
|
|
</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">-></span><span class="identifier">operand</span><span class="plain">, 0) - </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">-></span><span class="identifier">operand</span><span class="plain">, 1) == 0) && (</span><span class="identifier">n</span><span class="plain"> >= 0) && (</span><span class="identifier">n</span><span class="plain"> < 10)) </span><<span class="cwebmacro">A single digit as the name</span> <span class="cwebmacronumber">3.5.1.1</span>>
|
|
<span class="reserved">else</span><span class="plain"> </span><<span class="cwebmacro">An Inform 6 identifier as the name</span> <span class="cwebmacronumber">3.5.1.2</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">, 8);</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">§3.5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_1_1"></a><b>§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}<=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">
|
|
<<span class="cwebmacrodefn">A single digit as the name</span> <span class="cwebmacronumber">3.5.1.1</span>> =
|
|
</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>
|
|
<<span class="cwebmacro">Set the kind of the my-variable</span> <span class="cwebmacronumber">3.5.1.1.1</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="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">§3.5.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_1_2"></a><b>§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">
|
|
<<span class="cwebmacrodefn">An Inform 6 identifier as the name</span> <span class="cwebmacronumber">3.5.1.2</span>> =
|
|
</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">-></span><span class="identifier">operand</span><span class="plain">);</span>
|
|
<<span class="cwebmacro">Set the kind of the my-variable</span> <span class="cwebmacronumber">3.5.1.1.1</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_5_1">§3.5.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_1_1_1"></a><b>§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>
|
|
|
|
<<span class="cwebmacrodefn">Set the kind of the my-variable</span> <span class="cwebmacronumber">3.5.1.1.1</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">-></span><span class="identifier">operand2</span><span class="plain">) > 0)</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">-></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">§3.5.1.1</a>, <a href="#SP3_5_1_2">§3.5.1.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_2"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline command "unprotect"</span> <span class="cwebmacronumber">3.5.2</span>> =
|
|
</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">-></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><<span class="cwebmacro">Issue a no-such-local problem message</span> <span class="cwebmacronumber">3.5.2.1</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">§3.5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_3"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline command "initialise"</span> <span class="cwebmacronumber">3.5.3</span>> =
|
|
</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">-></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">-></span><span class="identifier">operand2</span><span class="plain">) > 0)</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">-></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">, 8);</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">, 8);</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="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">§3.5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_4"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline command "copy"</span> <span class="cwebmacronumber">3.5.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">copy_form</span><span class="plain"> = 0;</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>
|
|
<<span class="cwebmacro">Find what we are copying from, to and how</span> <span class="cwebmacronumber">3.5.4.1</span>><span class="plain">;</span>
|
|
<<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>><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"> != 0) </span><<span class="cwebmacro">Check that increment or decrement make sense</span> <span class="cwebmacronumber">3.5.4.3</span>><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\</span><span class="plain">n</span><span class="string">"</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">, &</span><span class="identifier">pt1</span><span class="plain">, &</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">§3.5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_4_1"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Find what we are copying from, to and how</span> <span class="cwebmacronumber">3.5.4.1</span>> =
|
|
</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">-></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"> = 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">-></span><span class="identifier">operand2</span><span class="plain">, 1); }</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">-></span><span class="identifier">operand2</span><span class="plain">, 1); }</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">-></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">) == 0) && (</span><span class="identifier">copy_form</span><span class="plain"> != 0))</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">) > 0)</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">-></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">-></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">-></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">-></span><span class="identifier">owner</span><span class="plain">-></span><span class="identifier">parent_schema</span><span class="plain">-></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">§3.5.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_4_2"></a><b>§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">
|
|
<<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>> =
|
|
</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">) && (</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">) && (</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">§3.5.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_4_3"></a><b>§3.5.4.3. </b>One can't, for example, increment a backdrop, or a text.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Check that increment or decrement make sense</span> <span class="cwebmacronumber">3.5.4.3</span>> =
|
|
</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="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">§3.5.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_5"></a><b>§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 — 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">
|
|
<<span class="cwebmacrodefn">Inline command "matches-description"</span> <span class="cwebmacronumber">3.5.5</span>> =
|
|
</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">-></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">-></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">-></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">-></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">-></span><span class="identifier">owner</span><span class="plain">-></span><span class="identifier">parent_schema</span><span class="plain">-></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">§3.5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_6"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline command "now-matches-description"</span> <span class="cwebmacronumber">3.5.6</span>> =
|
|
</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">-></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">-></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">-></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">-></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">-></span><span class="identifier">owner</span><span class="plain">-></span><span class="identifier">parent_schema</span><span class="plain">-></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">§3.5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_7"></a><b>§3.5.7. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Inline command "arithmetic-operation"</span> <span class="cwebmacronumber">3.5.7</span>> =
|
|
</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>
|
|
<<span class="cwebmacro">Read the operands and their kinds</span> <span class="cwebmacronumber">3.5.7.1</span>><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">§3.5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_7_1"></a><b>§3.5.7.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Read the operands and their kinds</span> <span class="cwebmacronumber">3.5.7.1</span>> =
|
|
</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">-></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">-></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">§3.5.7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_8"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline command "say"</span> <span class="cwebmacronumber">3.5.8</span>> =
|
|
</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">-></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>
|
|
<<span class="cwebmacro">Issue a no-such-local problem message</span> <span class="cwebmacronumber">3.5.2.1</span>><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">-></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><<span class="cwebmacro">Inline say text</span> <span class="cwebmacronumber">3.5.8.1</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="cwebmacro">Inline say number</span> <span class="cwebmacronumber">3.5.8.2</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_unicode_character</span><span class="plain">)) </span><<span class="cwebmacro">Inline say unicode character</span> <span class="cwebmacronumber">3.5.8.3</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::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><<span class="cwebmacro">Issue an inline no-such-kind problem</span> <span class="cwebmacronumber">3.2.1.2</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">§3.5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_8_1"></a><b>§3.5.8.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Inline say text</span> <span class="cwebmacronumber">3.5.8.1</span>> =
|
|
</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">)) &&</span>
|
|
<span class="plain">(</span><span class="identifier">Wordings::length</span><span class="plain">(</span><span class="identifier">SW</span><span class="plain">) == 1) &&</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">§3.5.8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_8_2"></a><b>§3.5.8.2. </b>Numbers are also handled directly...
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Inline say number</span> <span class="cwebmacronumber">3.5.8.2</span>> =
|
|
</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">§3.5.8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_8_3"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline say unicode character</span> <span class="cwebmacronumber">3.5.8.3</span>> =
|
|
</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="functiontext">VirtualMachines::is_16_bit</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">§3.5.8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_9"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline command "show-me"</span> <span class="cwebmacronumber">3.5.9</span>> =
|
|
</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">-></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>
|
|
<<span class="cwebmacro">Issue a no-such-local problem message</span> <span class="cwebmacronumber">3.5.2.1</span>><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">§3.5</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_6"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Expand a bracing containing a miscellaneous command</span> <span class="cwebmacronumber">3.6</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">segment_count_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "segment-count"</span> <span class="cwebmacronumber">3.6.1</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">final_segment_marker_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "final-segment-marker"</span> <span class="cwebmacronumber">3.6.2</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">list_together_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "list-together"</span> <span class="cwebmacronumber">3.6.3</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></span><span class="identifier">inline_command</span><span class="plain"> == </span><span class="identifier">rescale_ISINC</span><span class="plain">) </span><<span class="cwebmacro">Inline command "rescale"</span> <span class="cwebmacronumber">3.6.4</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_6_1"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline command "segment-count"</span> <span class="cwebmacronumber">3.6.1</span>> =
|
|
</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">§3.6</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_6_2"></a><b>§3.6.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Inline command "final-segment-marker"</span> <span class="cwebmacronumber">3.6.2</span>> =
|
|
</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">§3.6</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_6_3"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline command "list-together"</span> <span class="cwebmacronumber">3.6.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></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">-></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">-></span><span class="identifier">owner</span><span class="plain">-></span><span class="identifier">parent_schema</span><span class="plain">-></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">§3.6</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_6_4"></a><b>§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">
|
|
<<span class="cwebmacrodefn">Inline command "rescale"</span> <span class="cwebmacronumber">3.6.4</span>> =
|
|
</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="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">§3.6</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_7"></a><b>§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>
|
|
|
|
<<span class="cwebmacrodefn">Expand an entirely internal-made definition</span> <span class="cwebmacronumber">3.7</span>> =
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sche</span><span class="plain">-></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">-</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">-</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">-></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">-</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">-</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">-></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">-</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">-></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">-</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">-></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">-</span><span class="element">>args</span><span class="plain">[0]), </span><span class="identifier">tokens</span><span class="plain">-</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">-></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">-></span><span class="identifier">extremal_property_sign</span><span class="plain"> != </span><span class="constant">MEASURE_T_EXACTLY</span><span class="plain">) && (</span><span class="identifier">sche</span><span class="plain">-></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">-</span><span class="element">>args</span><span class="plain">[0],</span>
|
|
<span class="identifier">sche</span><span class="plain">-></span><span class="identifier">extremal_property</span><span class="plain">, </span><span class="identifier">sche</span><span class="plain">-></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">-></span><span class="identifier">owner</span><span class="plain">-></span><span class="identifier">parent_schema</span><span class="plain">-></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 '<' or '>' 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">-></span><span class="identifier">inline_subcommand</span><span class="plain"> == </span><span class="identifier">function_application_ISINSC</span><span class="plain">) </span><<span class="cwebmacro">Primitive "function-application"</span> <span class="cwebmacronumber">3.7.1</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">-></span><span class="identifier">inline_subcommand</span><span class="plain"> == </span><span class="identifier">description_application_ISINSC</span><span class="plain">) </span><<span class="cwebmacro">Primitive "description-application"</span> <span class="cwebmacronumber">3.7.2</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">-></span><span class="identifier">inline_subcommand</span><span class="plain"> == </span><span class="identifier">solve_equation_ISINSC</span><span class="plain">) </span><<span class="cwebmacro">Primitive "solve-equation"</span> <span class="cwebmacronumber">3.7.3</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">-></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">-></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">-></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">-</span><span class="element">>tokens_count</span><span class="plain"> > 0) {</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">-</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">-></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">-></span><span class="identifier">owner</span><span class="plain">-></span><span class="identifier">parent_schema</span><span class="plain">-></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">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_7_1"></a><b>§3.7.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Primitive "function-application"</span> <span class="cwebmacronumber">3.7.1</span>> =
|
|
</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">-</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">-></span><span class="identifier">owner</span><span class="plain">-></span><span class="identifier">parent_schema</span><span class="plain">-></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">, &</span><span class="identifier">X</span><span class="plain">, &</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"><</span><span class="identifier">tokens</span><span class="plain">-</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">-</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">-</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">, &</span><span class="identifier">head</span><span class="plain">, &</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">-</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">)) && (</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">-</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">-</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">§3.7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_7_2"></a><b>§3.7.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Primitive "description-application"</span> <span class="cwebmacronumber">3.7.2</span>> =
|
|
</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">-</span><span class="element">>args</span><span class="plain">[1];</span>
|
|
<span class="identifier">tokens</span><span class="plain">-</span><span class="element">>args</span><span class="plain">[1] = </span><span class="identifier">tokens</span><span class="plain">-</span><span class="element">>args</span><span class="plain">[0];</span>
|
|
<span class="identifier">tokens</span><span class="plain">-</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">-</span><span class="element">>tokens_count</span><span class="plain"> = 2;</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">§3.7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_7_3"></a><b>§3.7.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Primitive "solve-equation"</span> <span class="cwebmacronumber">3.7.3</span>> =
|
|
</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">-</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">-</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">-</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="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">§3.7</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_5_2_1"></a><b>§3.5.2.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Issue a no-such-local problem message</span> <span class="cwebmacronumber">3.5.2.1</span>> =
|
|
</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">-></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">-></span><span class="identifier">owner</span><span class="plain">-></span><span class="identifier">parent_schema</span><span class="plain">-></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">§3.5.2</a>, <a href="#SP3_5_8">§3.5.8</a>, <a href="#SP3_5_9">§3.5.9</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§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">, 1) == 0) && (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">operand</span><span class="plain">, 0) >= </span><span class="character">'0'</span><span class="plain">) && (</span><span class="identifier">Str::get_at</span><span class="plain">(</span><span class="identifier">operand</span><span class="plain">, 0) <= </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">, 0) - </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">(&(</span><span class="identifier">ph</span><span class="plain">-</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"> >= 0) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">tokens</span><span class="plain">-</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">§3.5.2</a>, <a href="#SP3_5_3">§3.5.3</a>, <a href="#SP3_5_4_1">§3.5.4.1</a>, <a href="#SP3_5_5">§3.5.5</a>, <a href="#SP3_5_6">§3.5.6</a>, <a href="#SP3_5_7_1">§3.5.7.1</a>, <a href="#SP3_5_8">§3.5.8</a>, <a href="#SP3_5_9">§3.5.9</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§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"><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">-</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">-></span><span class="identifier">kv_number</span><span class="plain">] = </span><span class="identifier">kvd</span><span class="plain">-></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"> (<</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">>(</span><span class="identifier">KW</span><span class="plain">)) </span><span class="identifier">spec</span><span class="plain"> = <<</span><span class="identifier">rp</span><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="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">§3.2.1</a>, <a href="#SP3_2_2">§3.2.2</a>, <a href="#SP3_2_3">§3.2.3</a>, <a href="#SP3_2_4">§3.2.4</a>, <a href="#SP3_2_5">§3.2.5</a>, <a href="#SP3_2_6">§3.2.6</a>, <a href="#SP3_2_7">§3.2.7</a>, <a href="#SP3_2_8">§3.2.8</a>, <a href="#SP3_5_1_1_1">§3.5.1.1.1</a>, <a href="#SP3_5_3">§3.5.3</a>, <a href="#SP3_5_8">§3.5.8</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§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">) && (</span><span class="identifier">VH</span><span class="plain">-></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">) && (</span><span class="identifier">VH</span><span class="plain">-></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"> (<</span><span class="reserved">property</span><span class="plain">-</span><span class="identifier">name</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">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">(<<</span><span class="identifier">rp</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">Properties::iname</span><span class="plain">(<<</span><span class="identifier">rp</span><span class="plain">>>));</span>
|
|
<span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (<</span><span class="identifier">k</span><span class="plain">-</span><span class="identifier">kind</span><span class="plain">>(</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"> = <<</span><span class="identifier">rp</span><span class="plain">>>;</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">(<<</span><span class="identifier">rp</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">"%~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="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"> (<</span><span class="identifier">s</span><span class="plain">-</span><span class="identifier">value</span><span class="plain">>(</span><span class="identifier">LW</span><span class="plain">)) </span><span class="identifier">spec</span><span class="plain"> = <<</span><span class="identifier">rp</span><span class="plain">>>;</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">, 0);</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"> < </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"> < </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">(&</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"> = 0, </span><span class="identifier">v2</span><span class="plain"> = 0;</span>
|
|
<span class="identifier">Holsters::unholster_pair</span><span class="plain">(&</span><span class="identifier">VH2</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="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">()-></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">§2</a>, 26/iti (<a href="26-iti.html#SP2_5">§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-->
|
|
</body>
|
|
</html>
|
|
|