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-04-07 23:02:44 +01:00

403 lines
27 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>M/dpiti</title>
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<nav role="navigation">
<h1><a href="../webs.html">Sources</a></h1>
<ul>
<li><a href="../compiler.html"><b>compiler tools</b></a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul>
<h2>Compiler Webs</h2>
<ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
</ul>
<h2>Inbuild Modules</h2>
<ul>
<li><a href="../inbuild-module/index.html">inbuild</a></li>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../html-module/index.html">html</a></li>
</ul>
<h2>Inform7 Modules</h2>
<ul>
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="../index-module/index.html">index</a></li>
</ul>
<h2>Inter Modules</h2>
<ul>
<li><a href="../inter-module/index.html">inter</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul>
<h2>Foundation</h2>
<ul>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'M/cpiti' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</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><p class="purpose">How executable functions are expressed in textual inter programs.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Code packages</a></li><li><a href="#SP2">&#167;2. Local variables</a></li><li><a href="#SP3">&#167;3. Labels</a></li><li><a href="#SP4">&#167;4. Primitive invocations</a></li><li><a href="#SP6">&#167;6. Function invocations</a></li><li><a href="#SP7">&#167;7. Val and cast</a></li><li><a href="#SP8">&#167;8. Ref, lab and code</a></li><li><a href="#SP9">&#167;9. Evaluation and reference</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><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 <code class="display"><span class="extract">_code</span></code>.
</p>
<p class="inwebparagraph">Note that <code class="display"><span class="extract">package</span></code> 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="inwebparagraph"><a id="SP2"></a><b>&#167;2. Local variables. </b>The statement <code class="display"><span class="extract">local NAME KIND</span></code> gives the code package a local variable;
the <code class="display"><span class="extract">NAME</span></code> must be a private <code class="display"><span class="extract">misc</span></code> symbol in the package's symbols table.
Local variable definitions should be made after the symbols table and before
the <code class="display"><span class="extract">code</span></code> 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="display">
<span class="reserved">package</span><span class="plain"> Double _code</span>
<span class="reserved">symbol</span><span class="plain"> </span><span class="reserved">private</span><span class="plain"> </span><span class="reserved">misc</span><span class="plain"> x</span>
<span class="reserved">local</span><span class="plain"> x </span><span class="identifier">K_number</span>
</pre>
<p class="inwebparagraph">then a call <code class="display"><span class="extract">Double(6)</span></code> would begin executing with <code class="display"><span class="extract">x</span></code> equal to 6.
</p>
<p class="inwebparagraph"><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 <code class="display"><span class="extract">NAME</span></code>, where <code class="display"><span class="extract">NAME</span></code> must be a private <code class="display"><span class="extract">label</span></code> symbol
in the package's symbols table, and must begin with a full stop <code class="display"><span class="extract">.</span></code>.
</p>
<p class="inwebparagraph">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="display">
<span class="reserved">package</span><span class="plain"> HelloWorld _code</span>
<span class="reserved">code</span>
<span class="reserved">inv</span><span class="plain"> </span><span class="functiontext">!print</span>
<span class="reserved">val</span><span class="plain"> </span><span class="identifier">K_text</span><span class="plain"> </span><span class="string">"Hello World!\n"</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><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="inwebparagraph">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="display">
<span class="reserved">primitive</span><span class="plain"> PRIMITIVE IN -&gt; OUT</span>
</pre>
<p class="inwebparagraph">Primitives are, in effect, built-in functions. <code class="display"><span class="extract">IN</span></code> can either be <code class="display"><span class="extract">void</span></code> or
can be a list of one or more terms which are all either <code class="display"><span class="extract">ref</span></code>, <code class="display"><span class="extract">val</span></code>, <code class="display"><span class="extract">lab</span></code> or
<code class="display"><span class="extract">code</span></code>. <code class="display"><span class="extract">OUT</span></code> can be either <code class="display"><span class="extract">void</span></code> or else a single term which is either
<code class="display"><span class="extract">ref</span></code> or <code class="display"><span class="extract">val</span></code>. For example,
</p>
<pre class="display">
<span class="reserved">primitive</span><span class="plain"> </span><span class="functiontext">!plus</span><span class="plain"> </span><span class="reserved">val</span><span class="plain"> </span><span class="reserved">val</span><span class="plain"> -&gt; </span><span class="reserved">val</span>
</pre>
<p class="inwebparagraph">declares that the signature of the primitive <code class="display"><span class="extract">!plus</span></code> is <code class="display"><span class="extract">val val -&gt; val</span></code>,
meaning that it takes two values and produces another as result, while
</p>
<pre class="display">
<span class="reserved">primitive</span><span class="plain"> </span><span class="functiontext">!ifelse</span><span class="plain"> </span><span class="reserved">val</span><span class="plain"> </span><span class="reserved">code</span><span class="plain"> </span><span class="reserved">code</span><span class="plain"> -&gt; </span><span class="reserved">void</span>
</pre>
<p class="inwebparagraph">says that <code class="display"><span class="extract">!ifelse</span></code> consumes a value and two blocks of code, and produces
nothing. Of course, <code class="display"><span class="extract">!plus</span></code> adds the values, whereas <code class="display"><span class="extract">!ifelse</span></code> evaluates
the value and then executes one of the two code blocks depending on
the result. But the statement <code class="display"><span class="extract">primitive</span></code> specifies only names and
signatures, not meanings.
</p>
<p class="inwebparagraph">The third term type, <code class="display"><span class="extract">lab</span></code>, means "the name of a label". This must be an
explicit name: labels are not values, which is why the signature for
<code class="display"><span class="extract">!jump</span></code> is <code class="display"><span class="extract">primitive !jump lab -&gt; void</span></code> and not <code class="display"><span class="extract">primitive !jump val -&gt; void</span></code>.
</p>
<p class="inwebparagraph">The final term type, <code class="display"><span class="extract">ref</span></code>, means "a reference to a value", and is in
effect an lvalue rather than an rvalue: for example,
</p>
<pre class="display">
<span class="reserved">primitive</span><span class="plain"> </span><span class="functiontext">!pull</span><span class="plain"> </span><span class="reserved">ref</span><span class="plain"> -&gt; </span><span class="reserved">void</span>
</pre>
<p class="inwebparagraph">is the prototype of a primitive which pulls a value from the stack and
stores it in whatever is referred to by the <code class="display"><span class="extract">ref</span></code> (typically, a variable).
</p>
<p class="inwebparagraph">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="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>A primitive is invoked by <code class="display"><span class="extract">inv PRIMITIVE</span></code>, with any necessary inputs,
matching the <code class="display"><span class="extract">IN</span></code> part of its signature, occurring on subsequent lines
indented one tab stop in. For example:
</p>
<pre class="display">
<span class="reserved">inv</span><span class="plain"> </span><span class="functiontext">!plus</span>
<span class="reserved">val</span><span class="plain"> </span><span class="identifier">K_number</span><span class="plain"> </span><span class="constant">2</span>
<span class="reserved">val</span><span class="plain"> </span><span class="identifier">K_number</span><span class="plain"> </span><span class="constant">2</span>
</pre>
<p class="inwebparagraph">would compute <code class="display"><span class="extract">2+2</span></code>. 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="display">
<span class="reserved">inv</span><span class="plain"> </span><span class="functiontext">!print</span>
<span class="reserved">val</span><span class="plain"> </span><span class="identifier">K_text</span><span class="plain"> </span><span class="string">"Hello World!\n"</span>
</pre>
<p class="inwebparagraph">the invocation of <code class="display"><span class="extract">!print</span></code> occurs at the top level of the function, in what
is called "void" context; but the <code class="display"><span class="extract">val</span></code> statement occurs in value context,
because it appears where the <code class="display"><span class="extract">!print</span></code> 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="display">
<span class="reserved">code</span>
<span class="reserved">inv</span><span class="plain"> </span><span class="functiontext">!plus</span>
<span class="reserved">val</span><span class="plain"> </span><span class="identifier">K_number</span><span class="plain"> </span><span class="constant">2</span>
<span class="reserved">val</span><span class="plain"> </span><span class="identifier">K_number</span><span class="plain"> </span><span class="constant">2</span>
</pre>
<p class="inwebparagraph">is an error, because it makes no sense to evaluate <code class="display"><span class="extract">!plus</span></code> in a void context:
the sum would just be thrown away unused. The context in which an <code class="display"><span class="extract">inv</span></code>
statement is allowed depends on the <code class="display"><span class="extract">OUT</span></code> part of the signature of its
primitive. Comparing the declarations of <code class="display"><span class="extract">!print</span></code> and <code class="display"><span class="extract">!plus</span></code>, we see:
</p>
<pre class="display">
<span class="reserved">primitive</span><span class="plain"> </span><span class="functiontext">!print</span><span class="plain"> </span><span class="reserved">val</span><span class="plain"> -&gt; </span><span class="reserved">void</span>
<span class="reserved">primitive</span><span class="plain"> </span><span class="functiontext">!plus</span><span class="plain"> </span><span class="reserved">val</span><span class="plain"> </span><span class="reserved">val</span><span class="plain"> -&gt; </span><span class="reserved">val</span>
</pre>
<p class="inwebparagraph">so that <code class="display"><span class="extract">!print</span></code> can only be invoked in a void context, and <code class="display"><span class="extract">!plus</span></code> in a
value context.
</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Function invocations. </b>The same statement, <code class="display"><span class="extract">inv</span></code>, is also used to call functions which are not
primitive: that is, functions which are defined by code packages.
</p>
<p class="inwebparagraph">To do so, though, we need a value identifying the function. This is
done as follows. Suppose:
</p>
<pre class="display">
<span class="reserved">kind</span><span class="plain"> </span><span class="identifier">K_number</span><span class="plain"> </span><span class="reserved">int32</span>
<span class="reserved">kind</span><span class="plain"> </span><span class="identifier">K_number_to_number</span><span class="plain"> </span><span class="identifier">K_number</span><span class="plain"> -&gt; </span><span class="identifier">K_number</span>
<span class="reserved">package</span><span class="plain"> Double_B _code</span>
<span class="reserved">symbol</span><span class="plain"> </span><span class="reserved">private</span><span class="plain"> </span><span class="reserved">misc</span><span class="plain"> x</span>
<span class="reserved">local</span><span class="plain"> x </span><span class="identifier">K_number</span>
<span class="reserved">code</span>
<span class="reserved">inv</span><span class="plain"> </span><span class="functiontext">!return</span>
<span class="reserved">inv</span><span class="plain"> </span><span class="functiontext">!plus</span>
<span class="reserved">val</span><span class="plain"> </span><span class="identifier">K_number</span><span class="plain"> x</span>
<span class="reserved">val</span><span class="plain"> </span><span class="identifier">K_number</span><span class="plain"> x</span>
<span class="reserved">constant</span><span class="plain"> Double </span><span class="identifier">K_number_to_number</span><span class="plain"> = Double_B</span>
</pre>
<p class="inwebparagraph">The value <code class="display"><span class="extract">Double</span></code> now evaluates to this function, and that's what we
can invoke. Thus:
</p>
<pre class="display">
<span class="reserved">inv</span><span class="plain"> Double</span>
<span class="reserved">val</span><span class="plain"> </span><span class="identifier">K_number</span><span class="plain"> </span><span class="constant">17</span>
</pre>
<p class="inwebparagraph">compiles to a function call returning the number 34.
</p>
<p class="inwebparagraph">It would not make sense, and is an error, to write <code class="display"><span class="extract">inv Double_B</span></code>, because
<code class="display"><span class="extract">Double_B</span></code> is a package name, not a value; and because there is no way to
know its signature. By contrast, <code class="display"><span class="extract">Double</span></code> is indeed a value, and by looking
at its kind <code class="display"><span class="extract">K_number_to_number</span></code>, we can see that the signature for the
invocation must be <code class="display"><span class="extract">val -&gt; val</span></code>.
</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Val and cast. </b>As has already been seen in the above examples, <code class="display"><span class="extract">val KIND VALUE</span></code> can be
used in value context to supply an argument for a function or primitive.
</p>
<p class="inwebparagraph">In general, inter code has very weak type checking. <code class="display"><span class="extract">val KIND VALUE</span></code> forces
the <code class="display"><span class="extract">VALUE</span></code> to conform to the <code class="display"><span class="extract">KIND</span></code>, but no check is made on whether
this kind is appropriate in the current context. For example, the primitive
<code class="display"><span class="extract">!print</span></code> requires its one value to be textual, so that the following:
</p>
<pre class="display">
<span class="reserved">inv</span><span class="plain"> </span><span class="functiontext">!print</span>
<span class="reserved">val</span><span class="plain"> </span><span class="identifier">K_number</span><span class="plain"> </span><span class="constant">7</span>
</pre>
<p class="inwebparagraph">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="display">
<span class="reserved">inv</span><span class="plain"> </span><span class="functiontext">!print</span>
<span class="reserved">val</span><span class="plain"> </span><span class="identifier">K_number</span><span class="plain"> </span><span class="string">"Seven"</span>
</pre>
<p class="inwebparagraph">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="display">
<span class="reserved">cast</span><span class="plain"> KIND1 &lt;- KIND2</span>
</pre>
<p class="inwebparagraph">is valid only in value context, and marks that a value of <code class="display"><span class="extract">KIND2</span></code> needs to
be interpreted in some way as a value of <code class="display"><span class="extract">KIND1</span></code>. For example, one might
imagine something like this:
</p>
<pre class="display">
<span class="reserved">inv</span><span class="plain"> </span><span class="functiontext">!times</span>
<span class="reserved">cast</span><span class="plain"> </span><span class="identifier">K_number</span><span class="plain"> &lt;- </span><span class="identifier">K_truth_state</span>
<span class="reserved">val</span><span class="plain"> </span><span class="identifier">K_truth_state</span><span class="plain"> flag1</span>
<span class="reserved">cast</span><span class="plain"> </span><span class="identifier">K_number</span><span class="plain"> &lt;- </span><span class="identifier">K_truth_state</span>
<span class="reserved">val</span><span class="plain"> </span><span class="identifier">K_truth_state</span><span class="plain"> flag2</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Ref, lab and code. </b>Just as <code class="display"><span class="extract">val</span></code> supplies a value as needed by a <code class="display"><span class="extract">val</span></code> term in an invocation
signature, so <code class="display"><span class="extract">ref</span></code>, <code class="display"><span class="extract">lab</span></code> and <code class="display"><span class="extract">code</span></code> meet the other possible requirements.
For example, suppose the following signatures:
</p>
<pre class="display">
<span class="reserved">primitive</span><span class="plain"> </span><span class="functiontext">!jump</span><span class="plain"> </span><span class="reserved">lab</span><span class="plain"> -&gt; </span><span class="reserved">void</span>
<span class="reserved">primitive</span><span class="plain"> </span><span class="functiontext">!pull</span><span class="plain"> </span><span class="reserved">ref</span><span class="plain"> -&gt; </span><span class="reserved">val</span>
<span class="reserved">primitive</span><span class="plain"> </span><span class="functiontext">!if</span><span class="plain"> </span><span class="reserved">val</span><span class="plain"> </span><span class="reserved">code</span><span class="plain"> -&gt; </span><span class="reserved">void</span>
</pre>
<p class="inwebparagraph">These might be invoked as follows:
</p>
<pre class="display">
<span class="reserved">inv</span><span class="plain"> </span><span class="functiontext">!jump</span>
<span class="reserved">lab</span><span class="plain"> .end</span>
</pre>
<p class="inwebparagraph">Here <code class="display"><span class="extract">.end</span></code> is the name of a label in the current function. References to
labels in other functions are impossible, because label names are all <code class="display"><span class="extract">private</span></code>
to the current symbols table. No kind is mentioned in a <code class="display"><span class="extract">lab</span></code> statement
because labels are not values, and therefore do not have kinds.
</p>
<pre class="display">
<span class="reserved">inv</span><span class="plain"> </span><span class="functiontext">!pull</span>
<span class="reserved">ref</span><span class="plain"> </span><span class="identifier">K_number</span><span class="plain"> x</span>
</pre>
<p class="inwebparagraph">Here <code class="display"><span class="extract">x</span></code> is the name of a variable, but it could be the name of any form of
storage. On the other hand, <code class="display"><span class="extract">ref K_number 10</span></code> 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="display">
<span class="reserved">inv</span><span class="plain"> </span><span class="functiontext">!if</span>
<span class="reserved">val</span><span class="plain"> </span><span class="identifier">K_truth_state</span><span class="plain"> flag</span>
<span class="reserved">code</span>
<span class="reserved">inv</span><span class="plain"> </span><span class="functiontext">!print</span>
<span class="reserved">val</span><span class="plain"> </span><span class="identifier">K_text</span><span class="plain"> </span><span class="string">"Yes!"</span>
</pre>
<p class="inwebparagraph">compiles to something like <code class="display"><span class="extract">if (flag) { print "Yes!"; }</span></code>. The <code class="display"><span class="extract">code</span></code> 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 <code class="display"><span class="extract">code</span></code> can only be used in code context (i.e. matching the
signature term <code class="display"><span class="extract">code</span></code>), not in value context. If what you need is code to
return a value, that should be another function.
</p>
<p class="inwebparagraph"><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="display">
<span class="reserved">evaluation</span>
<span class="plain">...</span>
</pre>
<p class="inwebparagraph"><code class="display"><span class="extract">evaluation</span></code> 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="inwebparagraph"><code class="display"><span class="extract">reference</span></code> 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="display">
<span class="reserved">inv</span><span class="plain"> </span><span class="functiontext">!store</span>
<span class="reserved">reference</span>
<span class="reserved">val</span><span class="plain"> </span><span class="identifier">K_number</span><span class="plain"> </span><span class="constant">7</span>
<span class="reserved">val</span><span class="plain"> </span><span class="identifier">K_number</span><span class="plain"> </span><span class="constant">3</span>
</pre>
<p class="inwebparagraph">In general <code class="display"><span class="extract">reference</span></code> 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>
<hr class="tocbar">
<ul class="toc"><li><a href="M-dpiti.html">Back to 'Data Packages in Textual Inter'</a></li><li><a href="M-ip.html">Continue with 'Inform Primitives'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>