mirror of
https://github.com/ganelson/inform.git
synced 2024-07-03 07:24:58 +03:00
383 lines
34 KiB
HTML
383 lines
34 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-assets/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="../assertions-module/index.html">assertions</a></li>
|
|
<li><a href="../values-module/index.html">values</a></li>
|
|
<li><a href="../knowledge-module/index.html">knowledge</a></li>
|
|
<li><a href="../imperative-module/index.html">imperative</a></li>
|
|
<li><a href="../runtime-module/index.html">runtime</a></li>
|
|
<li><a href="../if-module/index.html">if</a></li>
|
|
<li><a href="../multimedia-module/index.html">multimedia</a></li>
|
|
<li><a href="../index-module/index.html">index</a></li>
|
|
</ul><h2>Inter Modules</h2><ul>
|
|
<li><a href="../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>Services</h2><ul>
|
|
<li><a href="../arch-module/index.html">arch</a></li>
|
|
<li><a href="../calculus-module/index.html">calculus</a></li>
|
|
<li><a href="../html-module/index.html">html</a></li>
|
|
<li><a href="../inflections-module/index.html">inflections</a></li>
|
|
<li><a href="../kinds-module/index.html">kinds</a></li>
|
|
<li><a href="../linguistics-module/index.html">linguistics</a></li>
|
|
<li><a href="../problems-module/index.html">problems</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="../../../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">§1. Code packages</a></li><li><a href="M-cpiti.html#SP2">§2. Local variables</a></li><li><a href="M-cpiti.html#SP3">§3. Labels</a></li><li><a href="M-cpiti.html#SP4">§4. Primitive invocations</a></li><li><a href="M-cpiti.html#SP6">§6. Function invocations</a></li><li><a href="M-cpiti.html#SP7">§7. Val and cast</a></li><li><a href="M-cpiti.html#SP8">§8. Ref, lab and code</a></li><li><a href="M-cpiti.html#SP9">§9. Evaluation and reference</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§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" class="paragraph-anchor"></a><b>§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" class="paragraph-anchor"></a><b>§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" class="paragraph-anchor"></a><b>§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 -> 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"> -> </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 -> 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"> -> </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 -> void</span></span> and not <span class="extract"><span class="extract-syntax">primitive !jump val -> 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"> -> </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" class="paragraph-anchor"></a><b>§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"> -> </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"> -> </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" class="paragraph-anchor"></a><b>§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"> -> </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 -> val</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>§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 <- 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"> <- </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"> <- </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" class="paragraph-anchor"></a><b>§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"> -> </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"> -> </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"> -> </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" class="paragraph-anchor"></a><b>§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">❮</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">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|