1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-03 07:24:58 +03:00
inform7/docs/inter/M-cpiti.html
2020-05-03 01:20:55 +01:00

377 lines
33 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Code Packages in Textual Inter</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-src/Figures/Inform.png" height=72">
</a></h1>
<ul><li><a href="../compiler.html">compiler tools</a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul><h2>Compiler Webs</h2><ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="index.html"><span class="selectedlink">inter</span></a></li>
</ul><h2>Inbuild Modules</h2><ul>
<li><a href="../supervisor-module/index.html">supervisor</a></li>
</ul><h2>Inform7 Modules</h2><ul>
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../index-module/index.html">index</a></li>
</ul><h2>Inter Modules</h2><ul>
<li><a href="../bytecode-module/index.html">bytecode</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul><h2>Shared Modules</h2><ul>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../html-module/index.html">html</a></li>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Code Packages in Textual Inter' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Compiler Tools</a></li><li><a href="index.html">inter</a></li><li><a href="index.html#M">Manual</a></li><li><b>Code Packages in Textual Inter</b></li></ul></div>
<p class="purpose">How executable functions are expressed in textual inter programs.</p>
<ul class="toc"><li><a href="M-cpiti.html#SP1">&#167;1. Code packages</a></li><li><a href="M-cpiti.html#SP2">&#167;2. Local variables</a></li><li><a href="M-cpiti.html#SP3">&#167;3. Labels</a></li><li><a href="M-cpiti.html#SP4">&#167;4. Primitive invocations</a></li><li><a href="M-cpiti.html#SP6">&#167;6. Function invocations</a></li><li><a href="M-cpiti.html#SP7">&#167;7. Val and cast</a></li><li><a href="M-cpiti.html#SP8">&#167;8. Ref, lab and code</a></li><li><a href="M-cpiti.html#SP9">&#167;9. Evaluation and reference</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. Code packages. </b>To recap: a file of textual inter has a brief global section at the top, and
is then a hierarchiy of package definitions. Each package begins with a
symbols table, but then has contents which depend on its type. This section
covers the possible contents for a code package, that is, one whose type
is <span class="extract"><span class="extract-syntax">_code</span></span>.
</p>
<p class="commentary">Note that <span class="extract"><span class="extract-syntax">package</span></span> is a data statement, not a code statement, and it follows
that there is no way for a code package to contain sub-packages. Conceptually,
a code package is a single executable function.
</p>
<p class="commentary firstcommentary"><a id="SP2"></a><b>&#167;2. Local variables. </b>The statement <span class="extract"><span class="extract-syntax">local NAME KIND</span></span> gives the code package a local variable;
the <span class="extract"><span class="extract-syntax">NAME</span></span> must be a private <span class="extract"><span class="extract-syntax">misc</span></span> symbol in the package's symbols table.
Local variable definitions should be made after the symbols table and before
the <span class="extract"><span class="extract-syntax">code</span></span> statement. When the function is called at run-time, its
earliest-defined locals will hold any arguments from the function call.
So for example, if:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">package</span><span class="plain-syntax"> Double _code</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">symbol</span><span class="plain-syntax"> </span><span class="reserved-syntax">private</span><span class="plain-syntax"> </span><span class="reserved-syntax">misc</span><span class="plain-syntax"> x</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local</span><span class="plain-syntax"> x </span><span class="identifier-syntax">K_number</span>
</pre>
<p class="commentary">then a call <span class="extract"><span class="extract-syntax">Double(6)</span></span> would begin executing with <span class="extract"><span class="extract-syntax">x</span></span> equal to 6.
</p>
<p class="commentary firstcommentary"><a id="SP3"></a><b>&#167;3. Labels. </b>Like labels in any assembly language, these are named reference points in the
code; they are written <span class="extract"><span class="extract-syntax">NAME</span></span>, where <span class="extract"><span class="extract-syntax">NAME</span></span> must be a private <span class="extract"><span class="extract-syntax">label</span></span> symbol
in the package's symbols table, and must begin with a full stop <span class="extract"><span class="extract-syntax">.</span></span>.
</p>
<p class="commentary">All code packages must contain a "code" node at the top level, which is the
final statement in the package, and contains the actual body code.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">package</span><span class="plain-syntax"> HelloWorld _code</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">code</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!print</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_text</span><span class="plain-syntax"> </span><span class="string-syntax">"Hello World!\n"</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4"></a><b>&#167;4. Primitive invocations. </b>Other than labels and locals, code is a series of "invocations". An invocation
is a use of either another function, or of a primitive.
</p>
<p class="commentary">Recall that the global section at the top of the inter file will likely have
declared a number of primitives, with the notation:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">primitive</span><span class="plain-syntax"> PRIMITIVE IN -&gt; OUT</span>
</pre>
<p class="commentary">Primitives are, in effect, built-in functions. <span class="extract"><span class="extract-syntax">IN</span></span> can either be <span class="extract"><span class="extract-syntax">void</span></span> or
can be a list of one or more terms which are all either <span class="extract"><span class="extract-syntax">ref</span></span>, <span class="extract"><span class="extract-syntax">val</span></span>, <span class="extract"><span class="extract-syntax">lab</span></span> or
<span class="extract"><span class="extract-syntax">code</span></span>. <span class="extract"><span class="extract-syntax">OUT</span></span> can be either <span class="extract"><span class="extract-syntax">void</span></span> or else a single term which is either
<span class="extract"><span class="extract-syntax">ref</span></span> or <span class="extract"><span class="extract-syntax">val</span></span>. For example,
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">primitive</span><span class="plain-syntax"> </span><span class="function-syntax">!plus</span><span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> -&gt; </span><span class="reserved-syntax">val</span>
</pre>
<p class="commentary">declares that the signature of the primitive <span class="extract"><span class="extract-syntax">!plus</span></span> is <span class="extract"><span class="extract-syntax">val val -&gt; val</span></span>,
meaning that it takes two values and produces another as result, while
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">primitive</span><span class="plain-syntax"> </span><span class="function-syntax">!ifelse</span><span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="reserved-syntax">code</span><span class="plain-syntax"> </span><span class="reserved-syntax">code</span><span class="plain-syntax"> -&gt; </span><span class="reserved-syntax">void</span>
</pre>
<p class="commentary">says that <span class="extract"><span class="extract-syntax">!ifelse</span></span> consumes a value and two blocks of code, and produces
nothing. Of course, <span class="extract"><span class="extract-syntax">!plus</span></span> adds the values, whereas <span class="extract"><span class="extract-syntax">!ifelse</span></span> evaluates
the value and then executes one of the two code blocks depending on
the result. But the statement <span class="extract"><span class="extract-syntax">primitive</span></span> specifies only names and
signatures, not meanings.
</p>
<p class="commentary">The third term type, <span class="extract"><span class="extract-syntax">lab</span></span>, means "the name of a label". This must be an
explicit name: labels are not values, which is why the signature for
<span class="extract"><span class="extract-syntax">!jump</span></span> is <span class="extract"><span class="extract-syntax">primitive !jump lab -&gt; void</span></span> and not <span class="extract"><span class="extract-syntax">primitive !jump val -&gt; void</span></span>.
</p>
<p class="commentary">The final term type, <span class="extract"><span class="extract-syntax">ref</span></span>, means "a reference to a value", and is in
effect an lvalue rather than an rvalue: for example,
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">primitive</span><span class="plain-syntax"> </span><span class="function-syntax">!pull</span><span class="plain-syntax"> </span><span class="reserved-syntax">ref</span><span class="plain-syntax"> -&gt; </span><span class="reserved-syntax">void</span>
</pre>
<p class="commentary">is the prototype of a primitive which pulls a value from the stack and
stores it in whatever is referred to by the <span class="extract"><span class="extract-syntax">ref</span></span> (typically, a variable).
</p>
<p class="commentary">Convention. Inform defines a standard set of around 90 primitives. Although
their names and prototypes are not part of the inter specification as such,
you will only be able to use Inter's "compile to I6" feature if those are
the primitives you use, so in effect this is the standard set. Details of
these primitives and what they do will appear below.
</p>
<p class="commentary firstcommentary"><a id="SP5"></a><b>&#167;5. </b>A primitive is invoked by <span class="extract"><span class="extract-syntax">inv PRIMITIVE</span></span>, with any necessary inputs,
matching the <span class="extract"><span class="extract-syntax">IN</span></span> part of its signature, occurring on subsequent lines
indented one tab stop in. For example:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!plus</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_number</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_number</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
</pre>
<p class="commentary">would compute <span class="extract"><span class="extract-syntax">2+2</span></span>. This brings up the issue of "context". Code statements
are always parsed in a given context, the context being what they are
expected to produce or do. In this example:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!print</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_text</span><span class="plain-syntax"> </span><span class="string-syntax">"Hello World!\n"</span>
</pre>
<p class="commentary">the invocation of <span class="extract"><span class="extract-syntax">!print</span></span> occurs at the top level of the function, in what
is called "void" context; but the <span class="extract"><span class="extract-syntax">val</span></span> statement occurs in value context,
because it appears where the <span class="extract"><span class="extract-syntax">!print</span></span> invocation expects to find a text value.
It is an error to use a statement in the wrong context. For example, this:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">code</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!plus</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_number</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_number</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
</pre>
<p class="commentary">is an error, because it makes no sense to evaluate <span class="extract"><span class="extract-syntax">!plus</span></span> in a void context:
the sum would just be thrown away unused. The context in which an <span class="extract"><span class="extract-syntax">inv</span></span>
statement is allowed depends on the <span class="extract"><span class="extract-syntax">OUT</span></span> part of the signature of its
primitive. Comparing the declarations of <span class="extract"><span class="extract-syntax">!print</span></span> and <span class="extract"><span class="extract-syntax">!plus</span></span>, we see:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">primitive</span><span class="plain-syntax"> </span><span class="function-syntax">!print</span><span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> -&gt; </span><span class="reserved-syntax">void</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">primitive</span><span class="plain-syntax"> </span><span class="function-syntax">!plus</span><span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> -&gt; </span><span class="reserved-syntax">val</span>
</pre>
<p class="commentary">so that <span class="extract"><span class="extract-syntax">!print</span></span> can only be invoked in a void context, and <span class="extract"><span class="extract-syntax">!plus</span></span> in a
value context.
</p>
<p class="commentary firstcommentary"><a id="SP6"></a><b>&#167;6. Function invocations. </b>The same statement, <span class="extract"><span class="extract-syntax">inv</span></span>, is also used to call functions which are not
primitive: that is, functions which are defined by code packages.
</p>
<p class="commentary">To do so, though, we need a value identifying the function. This is
done as follows. Suppose:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_number</span><span class="plain-syntax"> </span><span class="reserved-syntax">int32</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_number_to_number</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_number</span><span class="plain-syntax"> -&gt; </span><span class="identifier-syntax">K_number</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">package</span><span class="plain-syntax"> Double_B _code</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">symbol</span><span class="plain-syntax"> </span><span class="reserved-syntax">private</span><span class="plain-syntax"> </span><span class="reserved-syntax">misc</span><span class="plain-syntax"> x</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">local</span><span class="plain-syntax"> x </span><span class="identifier-syntax">K_number</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">code</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!return</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!plus</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_number</span><span class="plain-syntax"> x</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_number</span><span class="plain-syntax"> x</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">constant</span><span class="plain-syntax"> Double </span><span class="identifier-syntax">K_number_to_number</span><span class="plain-syntax"> = Double_B</span>
</pre>
<p class="commentary">The value <span class="extract"><span class="extract-syntax">Double</span></span> now evaluates to this function, and that's what we
can invoke. Thus:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> Double</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_number</span><span class="plain-syntax"> </span><span class="constant-syntax">17</span>
</pre>
<p class="commentary">compiles to a function call returning the number 34.
</p>
<p class="commentary">It would not make sense, and is an error, to write <span class="extract"><span class="extract-syntax">inv Double_B</span></span>, because
<span class="extract"><span class="extract-syntax">Double_B</span></span> is a package name, not a value; and because there is no way to
know its signature. By contrast, <span class="extract"><span class="extract-syntax">Double</span></span> is indeed a value, and by looking
at its kind <span class="extract"><span class="extract-syntax">K_number_to_number</span></span>, we can see that the signature for the
invocation must be <span class="extract"><span class="extract-syntax">val -&gt; val</span></span>.
</p>
<p class="commentary firstcommentary"><a id="SP7"></a><b>&#167;7. Val and cast. </b>As has already been seen in the above examples, <span class="extract"><span class="extract-syntax">val KIND VALUE</span></span> can be
used in value context to supply an argument for a function or primitive.
</p>
<p class="commentary">In general, inter code has very weak type checking. <span class="extract"><span class="extract-syntax">val KIND VALUE</span></span> forces
the <span class="extract"><span class="extract-syntax">VALUE</span></span> to conform to the <span class="extract"><span class="extract-syntax">KIND</span></span>, but no check is made on whether
this kind is appropriate in the current context. For example, the primitive
<span class="extract"><span class="extract-syntax">!print</span></span> requires its one value to be textual, so that the following:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!print</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_number</span><span class="plain-syntax"> </span><span class="constant-syntax">7</span>
</pre>
<p class="commentary">has undefined behaviour at run-time. Though a terrible idea, this is valid
inter code. This code, on the other hand, will throw an error:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!print</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_number</span><span class="plain-syntax"> </span><span class="string-syntax">"Seven"</span>
</pre>
<p class="commentary">The inter language does nevertheless provide for compilers which want to
produce much stricter type-checked code, or which need their code-generators
to compile shim code converting values between kinds. The statement:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">cast</span><span class="plain-syntax"> KIND1 &lt;- KIND2</span>
</pre>
<p class="commentary">is valid only in value context, and marks that a value of <span class="extract"><span class="extract-syntax">KIND2</span></span> needs to
be interpreted in some way as a value of <span class="extract"><span class="extract-syntax">KIND1</span></span>. For example, one might
imagine something like this:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!times</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">cast</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_number</span><span class="plain-syntax"> &lt;- </span><span class="identifier-syntax">K_truth_state</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_truth_state</span><span class="plain-syntax"> flag1</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">cast</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_number</span><span class="plain-syntax"> &lt;- </span><span class="identifier-syntax">K_truth_state</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_truth_state</span><span class="plain-syntax"> flag2</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8"></a><b>&#167;8. Ref, lab and code. </b>Just as <span class="extract"><span class="extract-syntax">val</span></span> supplies a value as needed by a <span class="extract"><span class="extract-syntax">val</span></span> term in an invocation
signature, so <span class="extract"><span class="extract-syntax">ref</span></span>, <span class="extract"><span class="extract-syntax">lab</span></span> and <span class="extract"><span class="extract-syntax">code</span></span> meet the other possible requirements.
For example, suppose the following signatures:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">primitive</span><span class="plain-syntax"> </span><span class="function-syntax">!jump</span><span class="plain-syntax"> </span><span class="reserved-syntax">lab</span><span class="plain-syntax"> -&gt; </span><span class="reserved-syntax">void</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">primitive</span><span class="plain-syntax"> </span><span class="function-syntax">!pull</span><span class="plain-syntax"> </span><span class="reserved-syntax">ref</span><span class="plain-syntax"> -&gt; </span><span class="reserved-syntax">val</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">primitive</span><span class="plain-syntax"> </span><span class="function-syntax">!if</span><span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="reserved-syntax">code</span><span class="plain-syntax"> -&gt; </span><span class="reserved-syntax">void</span>
</pre>
<p class="commentary">These might be invoked as follows:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!jump</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">lab</span><span class="plain-syntax"> .end</span>
</pre>
<p class="commentary">Here <span class="extract"><span class="extract-syntax">.end</span></span> is the name of a label in the current function. References to
labels in other functions are impossible, because label names are all <span class="extract"><span class="extract-syntax">private</span></span>
to the current symbols table. No kind is mentioned in a <span class="extract"><span class="extract-syntax">lab</span></span> statement
because labels are not values, and therefore do not have kinds.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!pull</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">ref</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_number</span><span class="plain-syntax"> x</span>
</pre>
<p class="commentary">Here <span class="extract"><span class="extract-syntax">x</span></span> is the name of a variable, but it could be the name of any form of
storage. On the other hand, <span class="extract"><span class="extract-syntax">ref K_number 10</span></span> would be an error, because it
isn't possible to write to the number 10: that is an rvalue but not an lvalue.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!if</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_truth_state</span><span class="plain-syntax"> flag</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">code</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!print</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_text</span><span class="plain-syntax"> </span><span class="string-syntax">"Yes!"</span>
</pre>
<p class="commentary">compiles to something like <span class="extract"><span class="extract-syntax">if (flag) { print "Yes!"; }</span></span>. The <span class="extract"><span class="extract-syntax">code</span></span> statement
is similar to a braced code block in a C-like language. Any amount of code
can appear inside it, indented by one further tab stop; this code is all
read in void context. There is no such thing as a code block which returns
a value, and <span class="extract"><span class="extract-syntax">code</span></span> can only be used in code context (i.e. matching the
signature term <span class="extract"><span class="extract-syntax">code</span></span>), not in value context. If what you need is code to
return a value, that should be another function.
</p>
<p class="commentary firstcommentary"><a id="SP9"></a><b>&#167;9. Evaluation and reference. </b>Using the mechanisms above, there is no good way to throw away an unwanted
value: it is an error, for example, to evaluate something in void context.
That's unfortunate if we want to evaluate something not for its result
but for a side-effect. To get around that, we have:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">evaluation</span>
<span class="plain-syntax"> ...</span>
</pre>
<p class="commentary"><span class="extract"><span class="extract-syntax">evaluation</span></span> causes any number of indented values to be evaluated,
throwing each result away in turn. In effect, it's a shim which changes
the context from void context to value context; it tends to generate no code
in the final program.
</p>
<p class="commentary"><span class="extract"><span class="extract-syntax">reference</span></span> is similarly a shim, but from reference context to value context.
This is not in general a safe thing to do: consider the consequences of the
following, for example -
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!store</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">reference</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_number</span><span class="plain-syntax"> </span><span class="constant-syntax">7</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_number</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span>
</pre>
<p class="commentary">In general <span class="extract"><span class="extract-syntax">reference</span></span> must only be used where it can be proved that its
content will compile to an lvalue in the Inform 6 generated. Inform uses it
as little as possible.
</p>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="M-dpiti.html">&#10094;</a></li><li class="progresscurrentchapter">M</li><li class="progresssection"><a href="M-ui.html">ui</a></li><li class="progresssection"><a href="M-ti.html">ti</a></li><li class="progresssection"><a href="M-dpiti.html">dpiti</a></li><li class="progresscurrent">cpiti</li><li class="progresssection"><a href="M-ip.html">ip</a></li><li class="progresssection"><a href="M-ia.html">ia</a></li><li class="progresssection"><a href="M-io.html">io</a></li><li class="progresssection"><a href="M-pas.html">pas</a></li><li class="progresssection"><a href="M-rc.html">rc</a></li><li class="progresschapter"><a href="1-mn.html">1</a></li><li class="progressnext"><a href="M-ip.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>