mirror of
https://github.com/ganelson/inform.git
synced 2024-07-08 01:54:21 +03:00
550 lines
46 KiB
HTML
550 lines
46 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">
|
|
<script src="http://code.jquery.com/jquery-1.12.4.min.js"
|
|
integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
|
|
|
|
<script src="../docs-assets/Bigfoot.js"></script>
|
|
<link href="../docs-assets/Bigfoot.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="../index.html">home</a></li>
|
|
</ul><h2>Compiler</h2><ul>
|
|
<li><a href="../structure.html">structure</a></li>
|
|
<li><a href="../inbuildn.html">inbuild</a></li>
|
|
<li><a href="../inform7n.html">inform7</a></li>
|
|
<li><a href="../intern.html">inter</a></li>
|
|
<li><a href="../services.html">services</a></li>
|
|
<li><a href="../secrets.html">secrets</a></li>
|
|
</ul><h2>Other Tools</h2><ul>
|
|
<li><a href="../inblorbn.html">inblorb</a></li>
|
|
<li><a href="../indocn.html">indoc</a></li>
|
|
<li><a href="../inform6.html">inform6</a></li>
|
|
<li><a href="../inpolicyn.html">inpolicy</a></li>
|
|
<li><a href="../inrtpsn.html">inrtps</a></li>
|
|
</ul><h2>Resources</h2><ul>
|
|
<li><a href="../extensions.html">extensions</a></li>
|
|
<li><a href="../kits.html">kits</a></li>
|
|
</ul><h2>Repository</h2><ul>
|
|
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=18> github</a></li>
|
|
</ul><h2>Related Projects</h2><ul>
|
|
<li><a href="../../../inweb/index.html">inweb</a></li>
|
|
<li><a href="../../../intest/index.html">intest</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="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#SP4">§4. Contexts</a></li><li><a href="M-cpiti.html#SP8">§8. Function calls</a></li><li><a href="M-cpiti.html#SP10">§10. Val, ref, lab and cast</a></li><li><a href="M-cpiti.html#SP12">§12. Labels and assembly language</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§1. Code packages. </b>To recap from <a href="M-ti.html" class="internal">Textual Inter</a>: an Inter program is a nested hierarchy of
|
|
packages. Some of those are special <span class="extract"><span class="extract-syntax">_code</span></span> packages which define functions,
|
|
special in several ways:
|
|
</p>
|
|
|
|
<ul class="items"><li>● Their names can be used as values: that's how functions are called. See
|
|
<span class="extract"><span class="extract-syntax">inv</span></span> below.
|
|
</li><li>● Their names can optionally have types: see <a href="M-dpiti.html" class="internal">Data Packages in Textual Inter</a>
|
|
for details.
|
|
</li><li>● They cannot have subpackages. Conceptually, a code package is a single
|
|
function body. Packages are not used for "code blocks", and there are no
|
|
nested functions.
|
|
</li><li>● They cannot contain <span class="extract"><span class="extract-syntax">constant</span></span>, <span class="extract"><span class="extract-syntax">variable</span></span>, and similar instructions found
|
|
in data packages. Instead they can only contain the set of instructions which
|
|
are the subject of this section (and which are allowed only in <span class="extract"><span class="extract-syntax">_code</span></span> packages).
|
|
</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>§2. </b>The basic structure of a function body like this is that it begins with some
|
|
local variable declarations, and then has its actual content inside a <span class="extract"><span class="extract-syntax">code</span></span>
|
|
block, like so:
|
|
</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">local</span><span class="plain-syntax"> x</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"> x</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> x</span>
|
|
</pre>
|
|
<p class="commentary">As with its global analogue, <span class="extract"><span class="extract-syntax">variable</span></span>, a <span class="extract"><span class="extract-syntax">local</span></span> instruction can optionally
|
|
specify a type:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">local</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int32</span><span class="plain-syntax">) x</span>
|
|
</pre>
|
|
<p class="commentary">There can be at most one <span class="extract"><span class="extract-syntax">code</span></span> instruction at the top level. This is incorrect:
|
|
</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"> fails _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">!enableprinting</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="string-syntax">"I am dismal.\n"</span>
|
|
</pre>
|
|
<p class="commentary">and should instead be:
|
|
</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"> succeeds _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">!enableprinting</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="string-syntax">"I am glorious.\n"</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>§3. </b>Surprisingly, perhaps, it's legal not to have a <span class="extract"><span class="extract-syntax">code</span></span> block at all. This
|
|
function works:
|
|
</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"> succeeds _code</span>
|
|
</pre>
|
|
<p class="commentary">But of course it does nothing. If the return value of such a function is used,
|
|
it will be 0.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>§4. Contexts. </b>At any point inside a function body (except at the very top level), the
|
|
instruction used is expected to have a given "category", decided by the
|
|
"context" at that point. These categories have names:
|
|
</p>
|
|
|
|
<ul class="items"><li>● <span class="extract"><span class="extract-syntax">code</span></span> context. This means an instruction is expected to do something,
|
|
but not produce a resulting value.
|
|
</li><li>● <span class="extract"><span class="extract-syntax">val</span></span> context. This means an instruction is expected to produce a value.
|
|
</li><li>● <span class="extract"><span class="extract-syntax">ref</span></span> context. This means an instruction is expected to provide a
|
|
"reference" to some storage in the program. For example, it could indicate
|
|
a global variable, or a particular property of some instance.
|
|
</li><li>● <span class="extract"><span class="extract-syntax">lab</span></span> context. This means an instruction is expected to indicate a label
|
|
marking a position in that same function.
|
|
</li></ul>
|
|
<p class="commentary">In a <span class="extract"><span class="extract-syntax">code</span></span> block, the context is initially <span class="extract"><span class="extract-syntax">code</span></span>. For example:
|
|
</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">local</span><span class="plain-syntax"> x top level has no context</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">code</span><span class="plain-syntax"> top level has no context</span>
|
|
<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"> context is </span><span class="reserved-syntax">code</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">lab</span><span class="plain-syntax"> .SkipWarning context is </span><span class="reserved-syntax">lab</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"> context is </span><span class="reserved-syntax">code</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="string-syntax">"It'll get bigger!\n"</span><span class="plain-syntax"> context is </span><span class="reserved-syntax">val</span>
|
|
<span class="plain-syntax"> .SkipWarning context is </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">!store</span><span class="plain-syntax"> context is </span><span class="reserved-syntax">code</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">ref</span><span class="plain-syntax"> x context is </span><span class="reserved-syntax">ref</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"> context is </span><span class="reserved-syntax">val</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> x context is </span><span class="reserved-syntax">val</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> x context is </span><span class="reserved-syntax">val</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"> context is </span><span class="reserved-syntax">code</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> x context is </span><span class="reserved-syntax">val</span>
|
|
</pre>
|
|
<p class="commentary">In this function, the <span class="extract"><span class="extract-syntax">code</span></span> block contains five instructions, each of which
|
|
is read in a <span class="extract"><span class="extract-syntax">code</span></span> context. Each of those then has its own expectations which
|
|
set the context for its child instructions, and so on. For example, <span class="extract"><span class="extract-syntax">inv !store</span></span>
|
|
expects to see two child instructions, the first in <span class="extract"><span class="extract-syntax">ref</span></span> context and the
|
|
second in <span class="extract"><span class="extract-syntax">val</span></span> context.
|
|
</p>
|
|
|
|
<p class="commentary">Those uses of <span class="extract"><span class="extract-syntax">inv !something</span></span> are called "primitive invocations". They are
|
|
like function calls, but where the function is built in to Inter and is not
|
|
itself defined in Inter. Each such has a "signature". For example, the
|
|
internal declaration of <span class="extract"><span class="extract-syntax">!store</span></span> is:
|
|
</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">!store</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">val</span>
|
|
</pre>
|
|
<p class="commentary">So its signature is <span class="extract"><span class="extract-syntax">ref val -> val</span></span>. This expresses that its two children
|
|
should be read in <span class="extract"><span class="extract-syntax">ref</span></span> and <span class="extract"><span class="extract-syntax">val</span></span> context, and that its result is a <span class="extract"><span class="extract-syntax">val</span></span>.
|
|
(As in most C-like languages, stores are values in Inter, though in
|
|
practice those values are often thrown away.)
|
|
</p>
|
|
|
|
<p class="commentary">The standard built-in stock of primitive invocations is described in the
|
|
next section, on <a href="M-ip.html" class="internal">Inform Primitives</a>.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>§5. </b>How is all this policed? Whereas typechecking of data is often weak in Inter,
|
|
signature checking is taken much more seriously. If the context is <span class="extract"><span class="extract-syntax">code</span></span>, then
|
|
the only legal primitives to invoke are those where the return part of the
|
|
signature is either <span class="extract"><span class="extract-syntax">void</span></span> (no value) or <span class="extract"><span class="extract-syntax">val</span></span> (a value, but which is thrown
|
|
away and ignored, as in most C-like languages). Otherwise, <span class="extract"><span class="extract-syntax">ref</span></span> context
|
|
requires a <span class="extract"><span class="extract-syntax">ref</span></span> result, and similarly for <span class="extract"><span class="extract-syntax">val</span></span> and <span class="extract"><span class="extract-syntax">lab</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary">For example, <span class="extract"><span class="extract-syntax">!return</span></span> has the signature <span class="extract"><span class="extract-syntax">val -> void</span></span>, which makes it legal
|
|
to use in a <span class="extract"><span class="extract-syntax">code</span></span> context as in the above example. But these two attempts
|
|
to use it would both be incorrect:
|
|
</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">!return</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!printnumber</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">val</span><span class="plain-syntax"> </span><span class="constant-syntax">10</span>
|
|
</pre>
|
|
<p class="commentary">The first fails because it tries to use <span class="extract"><span class="extract-syntax">!return</span></span> as if it were <span class="extract"><span class="extract-syntax">void -> void</span></span>,
|
|
i.e., with no supplied value; the second fails because it tries to use it as if
|
|
it were <span class="extract"><span class="extract-syntax">val -> val</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>§6. </b>Some primitives have <span class="extract"><span class="extract-syntax">code</span></span> as one or more of their arguments. 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">!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">This evaluates the first argument (a value), then executes the second argument
|
|
(a code block) if the value is non-zero, or alternatively the third if it is zero.
|
|
There is no result. 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">!ifelse</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> x</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">!printnumber</span>
|
|
<span class="plain-syntax"> x</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="string-syntax">"I refuse to print zeroes on principle."</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>§7. </b>Rather like <span class="extract"><span class="extract-syntax">code</span></span>, which executes a run of instructions as if they were a
|
|
single instruction, <span class="extract"><span class="extract-syntax">evaluation</span></span> makes a run of evaluations. 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"> </span><span class="function-syntax">!printnumber</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">evaluation</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="constant-syntax">23</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> -1</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="constant-syntax">12</span>
|
|
</pre>
|
|
<p class="commentary">prints just "12". The point of this is that there may be side-effects in the
|
|
earlier evaluations, of course, though there weren't in this example.
|
|
</p>
|
|
|
|
<p class="commentary">Another converter, so to speak, is <span class="extract"><span class="extract-syntax">reference</span></span>, but this is much more limited
|
|
in what it is allowed to do.
|
|
</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"> x</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span>
|
|
</pre>
|
|
<p class="commentary">is exactly equivalent to:
|
|
</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">ref</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="constant-syntax">5</span>
|
|
</pre>
|
|
<p class="commentary">This is not a very useful example: but consider —
|
|
</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">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!propertyvalue</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> Odessa</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> area</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="constant-syntax">5000</span>
|
|
</pre>
|
|
<p class="commentary">which changes the property <span class="extract"><span class="extract-syntax">area</span></span> for <span class="extract"><span class="extract-syntax">Odessa</span></span> to 5000. The signature of
|
|
<span class="extract"><span class="extract-syntax">!propertyvalue</span></span> is <span class="extract"><span class="extract-syntax">val val -> val</span></span>, and ordinarily it evaluates the property.
|
|
But placed under a <span class="extract"><span class="extract-syntax">reference</span></span>, it becomes a reference to where that property
|
|
is stored, and thus allows the value to be changed with <span class="extract"><span class="extract-syntax">!store</span></span>. 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">!store</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">inv</span><span class="plain-syntax"> </span><span class="function-syntax">!propertyvalue</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> Odessa</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> area</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="constant-syntax">5000</span>
|
|
</pre>
|
|
<p class="commentary">would by contrast be rejected with an error, as trying to use a <span class="extract"><span class="extract-syntax">val</span></span> in a <span class="extract"><span class="extract-syntax">ref</span></span>
|
|
context.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">reference</span></span> cannot be applied to anything other than storage (a local or global
|
|
variable, a memory location or a property value), so for example:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<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="constant-syntax">5</span>
|
|
</pre>
|
|
<p class="commentary">is meaningless and will be rejected. There is in general no way to make, say,
|
|
a pointer to a function or instance using <span class="extract"><span class="extract-syntax">reference</span></span>. It is much more circumscribed
|
|
than the <span class="extract"><span class="extract-syntax">&</span></span> operator in C.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>§8. Function calls. </b>This seems a good point to say how to make function calls, since it's almost
|
|
exactly the same. 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">!printnumber</span>
|
|
<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="constant-syntax">10</span>
|
|
</pre>
|
|
<p class="commentary">prints "20". Note the lack of a <span class="extract"><span class="extract-syntax">!</span></span> in front of the function name: this means
|
|
it is a regular function, not a primitive.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>§9. </b>Function calls work in a rather assembly-language-like way, and Inter makes
|
|
much less effort to type-check these for any kind of safety: so beware. It
|
|
allows them to have any of the signatures <span class="extract"><span class="extract-syntax">void -> val</span></span>, <span class="extract"><span class="extract-syntax">val -> val</span></span>,
|
|
<span class="extract"><span class="extract-syntax">val val -> val</span></span>, ... and so on: in other words, they can be called with
|
|
any number of arguments.
|
|
</p>
|
|
|
|
<p class="commentary">In particular, even if a function is declared with a type it is still legal to
|
|
call it with any number of arguments. Again: beware.
|
|
</p>
|
|
|
|
<p class="commentary">Those arguments become the initial values of the local variables. 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"> example _code</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">local</span><span class="plain-syntax"> x</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">local</span><span class="plain-syntax"> y</span>
|
|
</pre>
|
|
<p class="commentary">then:
|
|
</p>
|
|
|
|
<ul class="items"><li>● a call with no arguments results in <span class="extract"><span class="extract-syntax">x</span></span> and <span class="extract"><span class="extract-syntax">y</span></span> equal to 0 and 0;
|
|
</li><li>● a call with argument 7 results in <span class="extract"><span class="extract-syntax">x</span></span> and <span class="extract"><span class="extract-syntax">y</span></span> equal to 7 and 0;
|
|
</li><li>● a call with arguments 7 and 81 results in <span class="extract"><span class="extract-syntax">x</span></span> and <span class="extract"><span class="extract-syntax">y</span></span> equal to 7 and 81;
|
|
</li><li>● a call with three or more arguments has undefined results and may crash
|
|
the program altogether.
|
|
</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>§10. Val, ref, lab and cast. </b>We have seen many examples already, but:
|
|
</p>
|
|
|
|
<ul class="items"><li>● <span class="extract"><span class="extract-syntax">val V</span></span> allows us to use any simple value <span class="extract"><span class="extract-syntax">V</span></span> in any <span class="extract"><span class="extract-syntax">val</span></span> context. For
|
|
what is meant by a "simple" value, see <a href="M-dpiti.html" class="internal">Data Packages in Textual Inter</a>.
|
|
</li><li>● <span class="extract"><span class="extract-syntax">ref R</span></span> allows us to refer to any variable, local or global, in a <span class="extract"><span class="extract-syntax">ref</span></span>
|
|
context.
|
|
</li><li>● <span class="extract"><span class="extract-syntax">lab L</span></span> allows us to refer to any label declared somewhere in the current
|
|
function body, in a <span class="extract"><span class="extract-syntax">lab</span></span> context.
|
|
</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>§11. </b>The <span class="extract"><span class="extract-syntax">val</span></span> and <span class="extract"><span class="extract-syntax">ref</span></span> instructions both allow optional type markers to be placed,
|
|
so for example:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int32</span><span class="plain-syntax">) x</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">ref</span><span class="plain-syntax"> (</span><span class="reserved-syntax">text</span><span class="plain-syntax">) y</span>
|
|
</pre>
|
|
<p class="commentary">Where no type marker is given, the type is always considered <span class="extract"><span class="extract-syntax">unchecked</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary">Types of <span class="extract"><span class="extract-syntax">val</span></span> or <span class="extract"><span class="extract-syntax">ref</span></span> tend not to be checked or looked at anyway, so this
|
|
feature is currently little used. For many primitives, some of which are quite
|
|
polymorphic, it would be difficult to impose a typechecking regime anyway.
|
|
But the ability to mark <span class="extract"><span class="extract-syntax">val</span></span> and <span class="extract"><span class="extract-syntax">ref</span></span> with types is preserved as a hedge
|
|
against potential future developments, when Inter might conceivably be
|
|
tightened up to typecheck explicitly typed values.
|
|
</p>
|
|
|
|
<p class="commentary">Similarly unuseful for the moment is <span class="extract"><span class="extract-syntax">cast</span></span>. This instruction allows us to
|
|
say "consider this value as if it had a different type". For example, if we
|
|
are using an enumerated type <span class="extract"><span class="extract-syntax">city</span></span>, we could read the enumeration values as
|
|
numbers like so:
|
|
</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"> </span><span class="reserved-syntax">int32</span><span class="plain-syntax"> <- city</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> (city) Odessa</span>
|
|
</pre>
|
|
<p class="commentary">Right now this is no different from:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int32</span><span class="plain-syntax">) Odessa</span>
|
|
</pre>
|
|
<p class="commentary">but we keep <span class="extract"><span class="extract-syntax">cast</span></span> around as a hedge against future developments, in case we
|
|
ever want to typecheck strictly enough that <span class="extract"><span class="extract-syntax">val (int32) Odessa</span></span> is rejected
|
|
as a contradiction in terms.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>§12. Labels and assembly language. </b>Like labels in C, 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 begin with a full stop <span class="extract"><span class="extract-syntax">.</span></span>. Labels are not values;
|
|
they cannot be stored, or computed with, or cast. They can only be used in
|
|
a <span class="extract"><span class="extract-syntax">lab</span></span> instruction.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>§13. </b>Two uses of <span class="extract"><span class="extract-syntax">inv</span></span> have already been covered: to call an Inter function, and
|
|
to invoke a primitive operation. The third is to execute an "assembly-language
|
|
opcode". What we mean by that is the direct use of the instruction set on the
|
|
target virtual machine we are expecting our program to run on.
|
|
</p>
|
|
|
|
<p class="commentary">This has always been a feature of Inform 6 code. For example, some real-number
|
|
arithmetic functions in BasicInformKit are written to use heavy amounts of
|
|
Glulx assembly language, in order to access functionality not present in the
|
|
Inform language itself. Here is a sample:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> @</span><span class="identifier-syntax">fdiv</span><span class="plain-syntax"> </span><span class="identifier-syntax">sp</span><span class="plain-syntax"> </span><span class="constant-syntax">$40135D8E</span><span class="plain-syntax"> </span><span class="identifier-syntax">log10val</span><span class="plain-syntax">; </span><span class="comment-syntax">$40135D8E is log(10)</span>
|
|
<span class="plain-syntax"> @</span><span class="identifier-syntax">floor</span><span class="plain-syntax"> </span><span class="identifier-syntax">log10val</span><span class="plain-syntax"> </span><span class="identifier-syntax">fexpo</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> @</span><span class="identifier-syntax">ftonumn</span><span class="plain-syntax"> </span><span class="identifier-syntax">fexpo</span><span class="plain-syntax"> </span><span class="identifier-syntax">expo</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<p class="commentary">Those "opcodes" beginning <span class="extract"><span class="extract-syntax">@</span></span> are part of the instruction set for the
|
|
Glulx virtual machine: real number arithmetic is impossible on the smaller
|
|
Z-machine, so we couldn't meaningfully compile this code to that platform,
|
|
and that is just is well because it has a completely different instruction
|
|
set of opcodes from Glulx anyway. Still, there's no denying that Inter code
|
|
using assembly immediately becomes less portable. This is why it is always
|
|
better to use Inter primitives if possible.
|
|
</p>
|
|
|
|
<p class="commentary">Still, BasicInformKit must be compiled to Inter code somehow. We clearly need to
|
|
deal with those opcodes somehow. The standard Inform-provided kits use two
|
|
different sets of opcodes, as noted: the Z-machine and Glulx instruction sets.
|
|
One conceivable way to deal with this would have been to provide primitives
|
|
equivalent to every opcode in either set (or at least every opcode used in
|
|
the standard Inform kits). But that would hugely increase the set of primitives,
|
|
and also incur a certain amount of awkward repetition.
|
|
</p>
|
|
|
|
<p class="commentary">Instead, the Inter specification goes to the opposite extreme. It makes no
|
|
assumptions about what assembly opcodes do, or do not, exist. Inter allows
|
|
absolutely anything, and would be quite happy to accept, say, <span class="extract"><span class="extract-syntax">inv @flytothemoon</span></span>,
|
|
even though this opcode does not exist in any known system of assembly language.<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>
|
|
</p>
|
|
|
|
<p class="commentary">And so the above is in fact compiled to:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">inv</span><span class="plain-syntax"> @</span><span class="identifier-syntax">fdiv</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">assembly</span><span class="plain-syntax"> </span><span class="identifier-syntax">stack</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">val</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="identifier-syntax">x40135D8E</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">log10val</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">inv</span><span class="plain-syntax"> @</span><span class="identifier-syntax">floor</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">log10val</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">fexpo</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">inv</span><span class="plain-syntax"> @</span><span class="identifier-syntax">ftonumn</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">fexpo</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">val</span><span class="plain-syntax"> </span><span class="identifier-syntax">expo</span>
|
|
</pre>
|
|
<p class="commentary">And when the <a href="../building-module/index.html" class="internal">building</a> module performed that compilation, it knew nothing
|
|
about <span class="extract"><span class="extract-syntax">@fdiv</span></span> and the rest: it just took on trust that this is meaningful.
|
|
</p>
|
|
|
|
<ul class="footnotetexts"><li class="footnote" id="fn:1"><p class="inwebfootnote"><sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> This can actually be useful, since it means people experimenting with new
|
|
hybrid forms of Inform can devise extra opcodes of their own.
|
|
<a href="#fnref:1" title="return to text"> ↩</a></p></li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>§14. </b>So, how apparently generous: the Inter specification allows us to invoke
|
|
opcodes with arbitrary names. But that does not, of course, mean that those
|
|
opcodes can be compiled to code which does anything useful. The <a href="../final-module/index.html" class="internal">final</a>
|
|
code-generation module probably won't know what to do with our hypothetical
|
|
<span class="extract"><span class="extract-syntax">@flytothemoon</span></span> opcode.
|
|
</p>
|
|
|
|
<p class="commentary">In practice, therefore, <a href="../final-module/index.html" class="internal">final</a> knows how to deal with the Z-machine
|
|
instruction set when compiling for Z via Inform 6, and how to deal with the
|
|
Glulx instruction set when compiling either for Glulx via Inform 6 or a
|
|
native executable via a C compiler like <span class="extract"><span class="extract-syntax">clang</span></span>. Any further code-generators
|
|
are also likely to follow Glulx conventions. So: if you really must use
|
|
assembly language in your Inter code, good advice would be —
|
|
</p>
|
|
|
|
<ul class="items"><li>(1) Use the Glulx instruction set, for better chances of portability.
|
|
</li><li>(2) Only use those opcodes which are also used in the standard Inform kits
|
|
somewhere, since those will probably be implemented.
|
|
</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>§15. </b>If we look at this example in more detail:
|
|
</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"> @fdiv</span>
|
|
<span class="plain-syntax"> assembly stack</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">x40135D8E</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> log10val</span>
|
|
</pre>
|
|
<p class="commentary">we see some general features of assembly language. Inter allows any number
|
|
of child instructions to be supplied — here, there are three. Since Inter knows
|
|
nothing about the meaning of <span class="extract"><span class="extract-syntax">@fdiv</span></span>, it has no way to know how many are
|
|
expected. They should all be usages of <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">assembly</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="extract"><span class="extract-syntax">val</span></span> and <span class="extract"><span class="extract-syntax">lab</span></span> we have seen already. <span class="extract"><span class="extract-syntax">assembly</span></span> is a sort of punctuation
|
|
instruction which allows various oddball syntaxes of Z-machine or Glulx
|
|
assembly to be imitated in Inter. There are only seven possible <span class="extract"><span class="extract-syntax">assembly</span></span>
|
|
instructions. Two are very common:
|
|
</p>
|
|
|
|
<ul class="items"><li>● <span class="extract"><span class="extract-syntax">assembly stack</span></span> is probably the most common, either reading or writing
|
|
to the top of the virtual machine's stack.
|
|
</li><li>● <span class="extract"><span class="extract-syntax">assembly store_to</span></span> indicates that a storage location follows (either
|
|
<span class="extract"><span class="extract-syntax">assembly stack</span></span> or a local or global variable). This is only used in Z-machine
|
|
assembly language; Glulx assembly doesn't have this marker.
|
|
</li></ul>
|
|
<p class="commentary">The other five apply only to "branch instructions", which perform some test
|
|
and then either return from the current function or make a jump to a label
|
|
(a "branch"), depending on the outcome of the test. By default the instruction
|
|
branches on a successful test. But alternatively it can:
|
|
</p>
|
|
|
|
<ul class="items"><li>● <span class="extract"><span class="extract-syntax">assembly branch_if_false</span></span>.
|
|
</li><li>● <span class="extract"><span class="extract-syntax">assembly return_true_if_true</span></span>.
|
|
</li><li>● <span class="extract"><span class="extract-syntax">assembly return_false_if_true</span></span>
|
|
</li><li>● <span class="extract"><span class="extract-syntax">assembly return_true_if_false</span></span>
|
|
</li><li>● <span class="extract"><span class="extract-syntax">assembly return_false_if_false</span></span>
|
|
</li></ul>
|
|
<p class="commentary">So for example the Z-machine instruction <span class="extract"><span class="extract-syntax">@random sp -> i;</span></span> compiles to Inter as:
|
|
</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"> @fdiv</span>
|
|
<span class="plain-syntax"> assembly stack</span>
|
|
<span class="plain-syntax"> assembly store_to</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">val</span><span class="plain-syntax"> i</span>
|
|
</pre>
|
|
<p class="commentary">And note the use of <span class="extract"><span class="extract-syntax">val i</span></span>, not <span class="extract"><span class="extract-syntax">ref i</span></span>, even though the variable is being
|
|
written to here. Even Inter's normal rules of category checking do not apply
|
|
to assembly language, the lowest of the low.
|
|
</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>
|
|
|